3376 lines
137 KiB
XML
3376 lines
137 KiB
XML
<?xml version="1.0" encoding="ISO8859-1" standalone="no"?>
|
|
<!--
|
|
The FreeBSD Documentation Project
|
|
|
|
$FreeBSD$
|
|
-->
|
|
|
|
<chapter id="firewalls">
|
|
<chapterinfo>
|
|
<authorgroup>
|
|
<author>
|
|
<firstname>Joseph J.</firstname>
|
|
<surname>Barbish</surname>
|
|
<contrib>Contributed by </contrib>
|
|
</author>
|
|
</authorgroup>
|
|
<authorgroup>
|
|
<author>
|
|
<firstname>Brad</firstname>
|
|
<surname>Davis</surname>
|
|
<contrib>Converted to SGML and updated by </contrib>
|
|
</author>
|
|
</authorgroup>
|
|
</chapterinfo>
|
|
|
|
<title>Firewalls</title>
|
|
|
|
<indexterm><primary>firewall</primary></indexterm>
|
|
|
|
<indexterm>
|
|
<primary>security</primary>
|
|
|
|
<secondary>firewalls</secondary>
|
|
</indexterm>
|
|
|
|
<sect1 id="firewalls-intro">
|
|
<title>Introduction</title>
|
|
|
|
<para>Firewalls make it possible to filter
|
|
incoming and outgoing traffic that flows through your system.
|
|
A firewall can use one or more sets of <quote>rules</quote> to
|
|
inspect the network packets as they come in or go out of your
|
|
network connections and either allows the traffic through or
|
|
blocks it. The rules of a firewall can inspect one or more
|
|
characteristics of the packets, including but not limited to the
|
|
protocol type, the source or destination host address, and the
|
|
source or destination port.</para>
|
|
|
|
<para>Firewalls can greatly enhance the security of a host or a
|
|
network. They can be used to do one or more of
|
|
the following things:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>To protect and insulate the applications, services and
|
|
machines of your internal network from unwanted traffic
|
|
coming in from the public Internet.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>To limit or disable access from hosts of the internal
|
|
network to services of the public Internet.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>To support network address translation
|
|
(<acronym>NAT</acronym>), which allows your internal network
|
|
to use private <acronym>IP</acronym> addresses and share a
|
|
single connection to the public Internet (either with a
|
|
single <acronym>IP</acronym> address or by a shared pool of
|
|
automatically assigned public addresses).</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>After reading this chapter, you will know:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>How to properly define packet filtering rules.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>The differences between the firewalls
|
|
built into &os;.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>How to use and configure the OpenBSD
|
|
<application>PF</application> firewall.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>How to use and configure
|
|
<application>IPFILTER</application>.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>How to use and configure
|
|
<application>IPFW</application>.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>Before reading this chapter, you should:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>Understand basic &os; and Internet concepts.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</sect1>
|
|
|
|
<sect1 id="firewalls-concepts">
|
|
<title>Firewall Concepts</title>
|
|
|
|
<indexterm>
|
|
<primary>firewall</primary>
|
|
|
|
<secondary>rulesets</secondary>
|
|
</indexterm>
|
|
|
|
<para>There are two basic ways to create firewall rulesets:
|
|
<quote>inclusive</quote> or <quote>exclusive</quote>. An
|
|
exclusive firewall allows all traffic through except for the
|
|
traffic matching the ruleset. An inclusive firewall does the
|
|
reverse. It only allows traffic matching the rules through and
|
|
blocks everything else.</para>
|
|
|
|
<para>An inclusive firewall offers much better control of the outgoing
|
|
traffic, making it a better choice for systems that offer services to
|
|
the public Internet. It also controls the type of traffic originating
|
|
from the public Internet that can gain access to your private network.
|
|
All traffic that does not match the rules, is blocked and logged by
|
|
design. Inclusive firewalls are generally safer than exclusive
|
|
firewalls because they significantly reduce the risk of allowing
|
|
unwanted traffic to pass through them.</para>
|
|
|
|
<note>
|
|
<para>Unless noted otherwise, all configuration and example
|
|
rulesets in this chapter, create inclusive type firewalls.</para>
|
|
</note>
|
|
|
|
<para>Security can be tightened further using a <quote>stateful
|
|
firewall</quote>. This type of firewall keeps
|
|
track of which connections are opened through the firewall and
|
|
will only allow traffic through which either matches an existing
|
|
connection or opens a new one. The disadvantage of a stateful
|
|
firewall is that it can be vulnerable to Denial of Service
|
|
(<acronym>DoS</acronym>) attacks if a lot of new connections are
|
|
opened very fast. With most firewalls it is possible to use a
|
|
combination of stateful and non-stateful behavior to make an
|
|
optimal firewall for the site.</para>
|
|
</sect1>
|
|
|
|
<sect1 id="firewalls-apps">
|
|
<title>Firewall Packages</title>
|
|
|
|
<para>&os; has three different firewall packages built
|
|
into the base system. They are: <emphasis>IPFILTER</emphasis>
|
|
(also known as <acronym>IPF</acronym>),
|
|
<emphasis>IPFIREWALL</emphasis> (also known as <acronym>IPFW</acronym>),
|
|
and <emphasis>OpenBSD's PacketFilter</emphasis> (also known as
|
|
<acronym>PF</acronym>). &os; also has two built in packages for
|
|
traffic shaping (basically controlling bandwidth usage):
|
|
&man.altq.4; and &man.dummynet.4;. Dummynet has traditionally been
|
|
closely tied with <acronym>IPFW</acronym>, and
|
|
<acronym>ALTQ</acronym> with
|
|
<acronym>PF</acronym>. Traffic shaping for IPFILTER can currently
|
|
be done with IPFILTER for NAT and filtering and
|
|
<acronym>IPFW</acronym> with &man.dummynet.4;
|
|
<emphasis>or</emphasis> by using <acronym>PF</acronym> with
|
|
<acronym>ALTQ</acronym>.
|
|
IPFW, and PF all use rules to control the access of packets to and
|
|
from your system, although they go about it different ways and
|
|
have a different rule syntax.</para>
|
|
|
|
<para>The reason that &os; has multiple built in firewall packages
|
|
is that different people have different requirements and
|
|
preferences. No single firewall package is the best.</para>
|
|
|
|
<para>The author prefers IPFILTER because its stateful rules are
|
|
much less complicated to use in a <acronym>NAT</acronym>
|
|
environment and it has a built in ftp proxy that simplifies the
|
|
rules to allow secure outbound FTP usage.</para>
|
|
|
|
<para>Since all firewalls are based on inspecting the values of
|
|
selected packet control fields, the creator of the firewall
|
|
rulesets must have an understanding of how
|
|
<acronym>TCP/IP</acronym> works, what the different values in
|
|
the packet control fields are and how these values are used in a
|
|
normal session conversation. For a good explanation go to:
|
|
<ulink
|
|
url="http://www.ipprimer.com/overview.cfm"></ulink>.</para>
|
|
</sect1>
|
|
|
|
<sect1 id="firewalls-pf">
|
|
<sect1info>
|
|
<authorgroup>
|
|
<author>
|
|
<firstname>John</firstname>
|
|
<surname>Ferrell</surname>
|
|
<contrib>Revised and updated by </contrib>
|
|
<!-- 24 March 2008 -->
|
|
</author>
|
|
</authorgroup>
|
|
</sect1info>
|
|
|
|
<title>The OpenBSD Packet Filter (PF) and
|
|
<acronym>ALTQ</acronym></title>
|
|
|
|
<indexterm>
|
|
<primary>firewall</primary>
|
|
|
|
<secondary>PF</secondary>
|
|
</indexterm>
|
|
|
|
<para>As of July 2003 the OpenBSD firewall software application
|
|
known as <acronym>PF</acronym> was ported to &os; and
|
|
made available in the &os; Ports Collection. Released in 2004,
|
|
&os; 5.3 was the first release that contained
|
|
<acronym>PF</acronym> as an integrated part of the base system.
|
|
<acronym>PF</acronym> is a complete, full-featured firewall
|
|
that has optional support for <acronym>ALTQ</acronym> (Alternate
|
|
Queuing). <acronym>ALTQ</acronym> provides Quality of Service
|
|
(<acronym>QoS</acronym>) functionality.</para>
|
|
|
|
<para>The OpenBSD Project does an outstanding job of
|
|
maintaining the <ulink
|
|
url="http://www.openbsd.org/faq/pf/">PF FAQ</ulink>.
|
|
As such, this section of the Handbook will focus on
|
|
<acronym>PF</acronym> as it pertains to &os; while providing
|
|
some general information regarding usage. For detailed usage
|
|
information please refer to the <ulink
|
|
url="http://www.openbsd.org/faq/pf/">PF FAQ</ulink>.</para>
|
|
|
|
<para>More information about <acronym>PF</acronym> for &os;
|
|
can be found at <ulink
|
|
url="http://pf4freebsd.love2party.net/"></ulink>.</para>
|
|
|
|
<sect2>
|
|
<title>Using the PF Loadable Kernel Modules</title>
|
|
|
|
<para>To load the PF Kernel Module add the following line to
|
|
<filename>/etc/rc.conf</filename>:</para>
|
|
|
|
<programlisting>pf_enable="YES"</programlisting>
|
|
|
|
<para>Then run the startup script to load the module:</para>
|
|
|
|
<screen>&prompt.root; <userinput>/etc/rc.d/pf start</userinput></screen>
|
|
|
|
<para>Note that the PF Module will not load if it cannot find
|
|
the ruleset config file. The default location is
|
|
<filename>/etc/pf.conf</filename>. If the PF ruleset is
|
|
located somewhere else, PF can be instructed to look there by
|
|
adding a line like the following to
|
|
<filename>/etc/rc.conf</filename>:</para>
|
|
|
|
<programlisting>pf_rules="<replaceable>/path/to/pf.conf</replaceable>"</programlisting>
|
|
|
|
<para>The sample <filename>pf.conf</filename>
|
|
can be found in <filename
|
|
class="directory">/usr/share/examples/pf/</filename>.
|
|
</para>
|
|
|
|
<para>The <acronym>PF</acronym> module can also be loaded manually
|
|
from the command line:</para>
|
|
|
|
<screen>&prompt.root; <userinput>kldload pf.ko</userinput></screen>
|
|
|
|
<para>Logging support for PF is provided by the
|
|
<literal>pflog.ko</literal> and can be loaded by adding the
|
|
following line to <filename>/etc/rc.conf</filename>:</para>
|
|
|
|
<programlisting>pflog_enable="YES"</programlisting>
|
|
|
|
<para>Then run the startup script to load the module:</para>
|
|
|
|
<screen>&prompt.root; <userinput>/etc/rc.d/pflog start</userinput></screen>
|
|
|
|
<para>If you need other <acronym>PF</acronym> features you will
|
|
need to compile <acronym>PF</acronym> support into the kernel.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>PF Kernel Options</title>
|
|
|
|
<indexterm>
|
|
<primary>kernel options</primary>
|
|
|
|
<secondary>device pf</secondary>
|
|
</indexterm>
|
|
|
|
<indexterm>
|
|
<primary>kernel options</primary>
|
|
|
|
<secondary>device pflog</secondary>
|
|
</indexterm>
|
|
|
|
<indexterm>
|
|
<primary>kernel options</primary>
|
|
|
|
<secondary>device pfsync</secondary>
|
|
</indexterm>
|
|
|
|
<para>While it is not necessary that you compile
|
|
<acronym>PF</acronym> support into the &os; kernel, you may want
|
|
to do so to take advantage of one of PF's advanced features that
|
|
is not included in the loadable module, namely &man.pfsync.4;, which
|
|
is a pseudo-device that exposes certain changes to
|
|
the state table used by <acronym>PF</acronym>. It can be
|
|
paired with &man.carp.4; to create failover firewalls using
|
|
<acronym>PF</acronym>. More information on
|
|
<acronym>CARP</acronym> can be found in
|
|
<xref linkend="carp"/> of the Handbook.</para>
|
|
|
|
<para>The <acronym>PF</acronym> kernel options can be found in
|
|
<filename>/usr/src/sys/conf/NOTES</filename> and are reproduced
|
|
below:</para>
|
|
|
|
<programlisting>device pf
|
|
device pflog
|
|
device pfsync</programlisting>
|
|
|
|
<para>The <literal>device pf</literal> option enables support for the
|
|
<quote>Packet Filter</quote> firewall (&man.pf.4;).</para>
|
|
|
|
<para>The <literal>device pflog</literal> option enables the optional
|
|
&man.pflog.4; pseudo network device which can be used to log
|
|
traffic to a &man.bpf.4; descriptor. The &man.pflogd.8; daemon
|
|
can be used to store the logging information to disk.</para>
|
|
|
|
<para>The <literal>device pfsync</literal> option enables the optional
|
|
&man.pfsync.4; pseudo-network device that is used to monitor
|
|
<quote>state changes</quote>.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Available <filename>rc.conf</filename> Options</title>
|
|
|
|
<para>The following &man.rc.conf.5; statements configure
|
|
<acronym>PF</acronym> and &man.pflog.4; at boot:</para>
|
|
|
|
<programlisting>pf_enable="YES" # Enable PF (load module if required)
|
|
pf_rules="/etc/pf.conf" # rules definition file for pf
|
|
pf_flags="" # additional flags for pfctl startup
|
|
pflog_enable="YES" # start pflogd(8)
|
|
pflog_logfile="/var/log/pflog" # where pflogd should store the logfile
|
|
pflog_flags="" # additional flags for pflogd startup</programlisting>
|
|
|
|
<para>If you have a LAN behind this firewall and have to forward
|
|
packets for the computers on the LAN or want to do NAT, you
|
|
will need the following option as well:</para>
|
|
|
|
<programlisting>gateway_enable="YES" # Enable as LAN gateway</programlisting>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Creating Filtering Rules</title>
|
|
|
|
<para><acronym>PF</acronym> reads its configuration rules from
|
|
&man.pf.conf.5; (<filename>/etc/pf.conf</filename> by
|
|
default) and it modifies, drops, or passes packets according to
|
|
the rules or definitions specified there. The &os;
|
|
installation includes several sample files located in
|
|
<filename>/usr/share/examples/pf/</filename>. Please refer to
|
|
the <ulink url="http://www.openbsd.org/faq/pf/">PF FAQ</ulink>
|
|
for complete coverage of <acronym>PF</acronym> rulesets.</para>
|
|
|
|
<warning>
|
|
<para>When browsing the <ulink
|
|
url="http://www.openbsd.org/faq/pf/">PF FAQ</ulink>,
|
|
please keep in mind that different versions of &os; can
|
|
contain different versions of PF. Currently,
|
|
&os; 8.<replaceable>X</replaceable> and prior is
|
|
using the same version of <acronym>PF</acronym> as
|
|
OpenBSD 4.1. &os; 9.<replaceable>X</replaceable> and
|
|
later is using the same version of <acronym>PF</acronym> as
|
|
OpenBSD 4.5.</para>
|
|
</warning>
|
|
|
|
<para>The &a.pf; is a good place to ask questions about
|
|
configuring and running the <acronym>PF</acronym>
|
|
firewall. Do not forget to check the mailing list archives
|
|
before asking questions!</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Working with PF</title>
|
|
|
|
<para>Use &man.pfctl.8; to control <acronym>PF</acronym>. Below
|
|
are some useful commands (be sure to review the &man.pfctl.8;
|
|
man page for all available options):</para>
|
|
|
|
<informaltable frame="none" pgwide="1">
|
|
<tgroup cols="2">
|
|
<thead>
|
|
<row>
|
|
<entry>Command</entry>
|
|
<entry>Purpose</entry>
|
|
</row>
|
|
</thead>
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry><command>pfctl <option>-e</option></command></entry>
|
|
<entry>Enable PF</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command>pfctl <option>-d</option></command></entry>
|
|
<entry>Disable PF</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command>pfctl <option>-F</option> all <option>-f</option> /etc/pf.conf</command></entry>
|
|
<entry>Flush all rules (nat, filter, state, table, etc.) and
|
|
reload from the file <filename>/etc/pf.conf</filename></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command>pfctl <option>-s</option> [ rules | nat | state ]</command></entry>
|
|
<entry>Report on the filter rules, nat rules, or state
|
|
table</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command>pfctl <option>-vnf</option> /etc/pf.conf</command></entry>
|
|
<entry>Check <filename>/etc/pf.conf</filename> for errors,
|
|
but do not load ruleset</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Enabling <acronym>ALTQ</acronym></title>
|
|
|
|
<para><acronym>ALTQ</acronym> is only available by compiling
|
|
support for it into the &os; kernel. <acronym>ALTQ</acronym> is
|
|
not supported by all of the available network card drivers.
|
|
Please see the &man.altq.4; manual page for a list of drivers
|
|
that are supported in your release of &os;.</para>
|
|
|
|
<para>The following kernel options will enable
|
|
<acronym>ALTQ</acronym> and add additional functionality:</para>
|
|
|
|
<programlisting>options ALTQ
|
|
options ALTQ_CBQ # Class Bases Queuing (CBQ)
|
|
options ALTQ_RED # Random Early Detection (RED)
|
|
options ALTQ_RIO # RED In/Out
|
|
options ALTQ_HFSC # Hierarchical Packet Scheduler (HFSC)
|
|
options ALTQ_PRIQ # Priority Queuing (PRIQ)
|
|
options ALTQ_NOPCC # Required for SMP build</programlisting>
|
|
|
|
<para><literal>options ALTQ</literal> enables the
|
|
<acronym>ALTQ</acronym> framework.</para>
|
|
|
|
<para><literal>options ALTQ_CBQ</literal> enables <emphasis>Class Based
|
|
Queuing</emphasis> (<acronym>CBQ</acronym>). <acronym>CBQ</acronym>
|
|
allows you to divide a connection's bandwidth into different
|
|
classes or queues to prioritize traffic based on filter
|
|
rules.</para>
|
|
|
|
<para><literal>options ALTQ_RED</literal> enables <emphasis>Random Early
|
|
Detection</emphasis> (<acronym>RED</acronym>). <acronym>RED</acronym> is
|
|
used to avoid network congestion. <acronym>RED</acronym> does
|
|
this by measuring the length of the queue and comparing it to
|
|
the minimum and maximum thresholds for the queue. If the
|
|
queue is over the maximum all new packets will be dropped.
|
|
True to its name, <acronym>RED</acronym> drops packets from
|
|
different connections randomly.</para>
|
|
|
|
<para><literal>options ALTQ_RIO</literal> enables <emphasis>Random Early
|
|
Detection In and Out</emphasis>.</para>
|
|
|
|
<para><literal>options ALTQ_HFSC</literal> enables the
|
|
<emphasis>Hierarchical Fair Service Curve Packet Scheduler</emphasis>. For more
|
|
information about <acronym>HFSC</acronym> see: <ulink
|
|
url="http://www-2.cs.cmu.edu/~hzhang/HFSC/main.html"></ulink>.</para>
|
|
|
|
<para><literal>options ALTQ_PRIQ</literal> enables <emphasis>Priority
|
|
Queuing</emphasis> (<acronym>PRIQ</acronym>). <acronym>PRIQ</acronym>
|
|
will always pass traffic that is in a higher queue
|
|
first.</para>
|
|
|
|
<para><literal>options ALTQ_NOPCC</literal> enables
|
|
<acronym>SMP</acronym> support for <acronym>ALTQ</acronym>.
|
|
This option is required on <acronym>SMP</acronym>
|
|
systems.</para>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 id="firewalls-ipf">
|
|
<title>The IPFILTER (IPF) Firewall</title>
|
|
|
|
<indexterm>
|
|
<primary>firewall</primary>
|
|
|
|
<secondary>IPFILTER</secondary>
|
|
</indexterm>
|
|
|
|
<para>The author of IPFILTER is Darren Reed. IPFILTER is not
|
|
operating system dependent: it is an open source application and
|
|
has been ported to &os;, NetBSD, OpenBSD, &sunos;, HP/UX, and
|
|
&solaris; operating systems. IPFILTER is actively being
|
|
supported and maintained, with updated versions being released
|
|
regularly.</para>
|
|
|
|
<para>IPFILTER is based on a kernel-side firewall and
|
|
<acronym>NAT</acronym> mechanism that can be controlled and
|
|
monitored by userland interface programs. The firewall rules can
|
|
be set or deleted with the &man.ipf.8; utility. The
|
|
<acronym>NAT</acronym> rules can be set or deleted with the
|
|
&man.ipnat.1; utility. The &man.ipfstat.8; utility can print
|
|
run-time statistics for the kernel parts of IPFILTER. The
|
|
&man.ipmon.8; program can log IPFILTER actions to the system log
|
|
files.</para>
|
|
|
|
<para>IPF was originally written using a rule processing logic of
|
|
<quote>the last matching rule wins</quote> and used only
|
|
stateless type of rules. Over time IPF has been enhanced to
|
|
include a <quote>quick</quote> option and a stateful <quote>keep
|
|
state</quote> option which drastically modernized the rules
|
|
processing logic. IPF's official documentation covers only the legacy
|
|
rule coding parameters and rule file processing
|
|
logic. The modernized functions are only included as additional
|
|
options, completely understating their benefits in producing a
|
|
far superior and more secure firewall.</para>
|
|
|
|
<para>The instructions contained in this section are based on
|
|
using rules that contain the <quote>quick</quote> option and the
|
|
stateful <quote>keep state</quote> option. This is the basic
|
|
framework for coding an inclusive firewall ruleset.</para>
|
|
|
|
<para>For detailed explanation of the legacy rules processing
|
|
method see: <ulink
|
|
url="http://www.obfuscation.org/ipf/ipf-howto.html#TOC_1"></ulink>
|
|
and <ulink
|
|
url="http://coombs.anu.edu.au/~avalon/ip-filter.html"></ulink>.</para>
|
|
|
|
<para>The IPF FAQ is at <ulink
|
|
url="http://www.phildev.net/ipf/index.html"></ulink>.</para>
|
|
|
|
<para>A searchable archive of the open-source IPFilter mailing list is
|
|
available at <ulink
|
|
url="http://marc.theaimsgroup.com/?l=ipfilter"></ulink>.</para>
|
|
|
|
<sect2>
|
|
<title>Enabling IPF</title>
|
|
|
|
<indexterm>
|
|
<primary>IPFILTER</primary>
|
|
|
|
<secondary>enabling</secondary>
|
|
</indexterm>
|
|
|
|
<para>IPF is included in the basic &os; install as a separate run
|
|
time loadable module. The system will dynamically load the IPF
|
|
kernel loadable module when the <filename>rc.conf</filename> statement
|
|
<literal>ipfilter_enable="YES"</literal> is used. The loadable
|
|
module was created with logging enabled and the
|
|
<literal>default pass all</literal> options. There is no need
|
|
to compile IPF into the &os; kernel just to change the default
|
|
to <literal>block all</literal>. This can be done just by adding
|
|
a <literal>block all</literal> rule at the end of your ruleset.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Kernel Options</title>
|
|
|
|
<indexterm>
|
|
<primary>kernel options</primary>
|
|
|
|
<secondary>IPFILTER</secondary>
|
|
</indexterm>
|
|
|
|
<indexterm>
|
|
<primary>kernel options</primary>
|
|
|
|
<secondary>IPFILTER_LOG</secondary>
|
|
</indexterm>
|
|
|
|
<indexterm>
|
|
<primary>kernel options</primary>
|
|
|
|
<secondary>IPFILTER_DEFAULT_BLOCK</secondary>
|
|
</indexterm>
|
|
|
|
<indexterm>
|
|
<primary>IPFILTER</primary>
|
|
|
|
<secondary>kernel options</secondary>
|
|
</indexterm>
|
|
|
|
<para>It is not a mandatory requirement to enable IPF by
|
|
compiling the following options into the &os; kernel. It is
|
|
only presented here as background information. Compiling IPF
|
|
into the kernel causes the loadable module to never be
|
|
used.</para>
|
|
|
|
<para>Sample kernel config IPF option statements are in the
|
|
<filename>/usr/src/sys/conf/NOTES</filename> kernel source
|
|
and are reproduced here:</para>
|
|
|
|
<programlisting>options IPFILTER
|
|
options IPFILTER_LOG
|
|
options IPFILTER_DEFAULT_BLOCK</programlisting>
|
|
|
|
<para><literal>options IPFILTER</literal> enables support for the
|
|
<quote>IPFILTER</quote> firewall.</para>
|
|
|
|
<para><literal>options IPFILTER_LOG</literal> enables the option
|
|
to have IPF log traffic by writing to the
|
|
<devicename>ipl</devicename> packet logging pseudo—device
|
|
for every rule that has the <literal>log</literal>
|
|
keyword.</para>
|
|
|
|
<para><literal>options IPFILTER_DEFAULT_BLOCK</literal> changes
|
|
the default behavior so any packet not matching a firewall
|
|
<literal>pass</literal> rule gets blocked.</para>
|
|
|
|
<para>These settings will take effect only after installing a kernel
|
|
that has been built with the above options set.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Available <filename>rc.conf</filename> Options</title>
|
|
|
|
<para>To activate IPF at boot time, the following statements need to
|
|
be added to <filename>/etc/rc.conf</filename>:</para>
|
|
|
|
<programlisting>ipfilter_enable="YES" # Start ipf firewall
|
|
ipfilter_rules="/etc/ipf.rules" # loads rules definition text file
|
|
ipmon_enable="YES" # Start IP monitor log
|
|
ipmon_flags="-Ds" # D = start as daemon
|
|
# s = log to syslog
|
|
# v = log tcp window, ack, seq
|
|
# n = map IP & port to names</programlisting>
|
|
|
|
<para>If there is a LAN behind this firewall that uses the
|
|
reserved private IP address ranges, the following lines will have to
|
|
be added to enable <acronym>NAT</acronym>
|
|
functionality:</para>
|
|
|
|
<programlisting>gateway_enable="YES" # Enable as LAN gateway
|
|
ipnat_enable="YES" # Start ipnat function
|
|
ipnat_rules="/etc/ipnat.rules" # rules definition file for ipnat</programlisting>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>IPF</title>
|
|
|
|
<indexterm><primary><command>ipf</command></primary></indexterm>
|
|
|
|
<para>The &man.ipf.8; command is used to load your ruleset file.
|
|
Your custom rules would normally be placed in a file, and the
|
|
following command could then be used to replace in mass the
|
|
currently running firewall rules:</para>
|
|
|
|
<screen>&prompt.root; <userinput>ipf -Fa -f /etc/ipf.rules</userinput></screen>
|
|
|
|
<para><option>-Fa</option> means flush all internal rules
|
|
tables.</para>
|
|
|
|
<para><option>-f</option> means this is the file to read for the
|
|
rules to load.</para>
|
|
|
|
<para>This gives you the ability to make changes to your custom
|
|
rules file, run the above IPF command, and thus update the
|
|
running firewall with a fresh copy of all the rules without
|
|
having to reboot the system. This method is very convenient
|
|
for testing new rules as the procedure can be executed as many
|
|
times as needed.</para>
|
|
|
|
<para>See the &man.ipf.8; manual page for details on the other
|
|
flags available with this command.</para>
|
|
|
|
<para>The &man.ipf.8; command expects the rules file to be a
|
|
standard text file. It will not accept a rules file written as
|
|
a script with symbolic substitution.</para>
|
|
|
|
<para>There is a way to build IPF rules that utilizes the power
|
|
of script symbolic substitution. For more information, see
|
|
<xref linkend="firewalls-ipf-rules-script"/>.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>IPFSTAT</title>
|
|
|
|
<indexterm><primary><command>ipfstat</command></primary></indexterm>
|
|
|
|
<indexterm>
|
|
<primary>IPFILTER</primary>
|
|
|
|
<secondary>statistics</secondary>
|
|
</indexterm>
|
|
|
|
<para>The default behavior of &man.ipfstat.8; is to retrieve and
|
|
display the totals of the accumulated statistics gathered as a
|
|
result of applying the user coded rules against packets going
|
|
in and out of the firewall since it was last started, or since
|
|
the last time the accumulators were reset to zero by the
|
|
<command>ipf -Z</command> command.</para>
|
|
|
|
<para>See the &man.ipfstat.8; manual page for details.</para>
|
|
|
|
<para>The default &man.ipfstat.8; command output will look
|
|
something like this:</para>
|
|
|
|
<screen>input packets: blocked 99286 passed 1255609 nomatch 14686 counted 0
|
|
output packets: blocked 4200 passed 1284345 nomatch 14687 counted 0
|
|
input packets logged: blocked 99286 passed 0
|
|
output packets logged: blocked 0 passed 0
|
|
packets logged: input 0 output 0
|
|
log failures: input 3898 output 0
|
|
fragment state(in): kept 0 lost 0
|
|
fragment state(out): kept 0 lost 0
|
|
packet state(in): kept 169364 lost 0
|
|
packet state(out): kept 431395 lost 0
|
|
ICMP replies: 0 <acronym>TCP</acronym> RSTs sent: 0
|
|
Result cache hits(in): 1215208 (out): 1098963
|
|
IN Pullups succeeded: 2 failed: 0
|
|
OUT Pullups succeeded: 0 failed: 0
|
|
Fastroute successes: 0 failures: 0
|
|
<acronym>TCP</acronym> cksum fails(in): 0 (out): 0
|
|
Packet log flags set: (0)</screen>
|
|
|
|
<para>When supplied with either <option>-i</option> for inbound
|
|
or <option>-o</option> for outbound, the command will retrieve and
|
|
display the appropriate list of filter rules currently
|
|
installed and in use by the kernel.</para>
|
|
|
|
<para><command>ipfstat -in</command> displays the inbound
|
|
internal rules table with rule number.</para>
|
|
|
|
<para><command>ipfstat -on</command> displays the outbound
|
|
internal rules table with the rule number.</para>
|
|
|
|
<para>The output will look something like this:</para>
|
|
|
|
<screen>@1 pass out on xl0 from any to any
|
|
@2 block out on dc0 from any to any
|
|
@3 pass out quick on dc0 proto tcp/udp from any to any keep state</screen>
|
|
|
|
<para><command>ipfstat -ih</command> displays the inbound
|
|
internal rules table, prefixing each rule with a count of how
|
|
many times the rule was matched.</para>
|
|
|
|
<para><command>ipfstat -oh</command> displays the outbound
|
|
internal rules table, prefixing each rule with a count of how
|
|
many times the rule was matched.</para>
|
|
|
|
<para>The output will look something like this:</para>
|
|
|
|
<screen>2451423 pass out on xl0 from any to any
|
|
354727 block out on dc0 from any to any
|
|
430918 pass out quick on dc0 proto tcp/udp from any to any keep state</screen>
|
|
|
|
<para>One of the most important functions of the
|
|
<command>ipfstat</command> command is the <option>-t</option>
|
|
flag which displays the state table in a way similar to the way
|
|
&man.top.1; shows the &os; running process table. When your
|
|
firewall is under attack, this function gives you the ability to
|
|
identify, drill down to, and see the attacking packets. The
|
|
optional sub-flags give the ability to select the destination
|
|
or source IP, port, or protocol that you want to monitor in
|
|
real time. See the &man.ipfstat.8; manual page for
|
|
details.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>IPMON</title>
|
|
|
|
<indexterm><primary><command>ipmon</command></primary></indexterm>
|
|
|
|
<indexterm>
|
|
<primary>IPFILTER</primary>
|
|
|
|
<secondary>logging</secondary>
|
|
</indexterm>
|
|
|
|
<para>In order for <command>ipmon</command> to work properly, the
|
|
kernel option <literal>IPFILTER_LOG</literal> must be turned on. This command has
|
|
two different modes that it can be used in. Native mode is the
|
|
default mode when the command is typed on the command line
|
|
without the <option>-D</option> flag.</para>
|
|
|
|
<para>Daemon mode is for when a continuous
|
|
system log file is desired, so that logging of past events may be
|
|
reviewed. This is how &os; and IPFILTER are configured to
|
|
work together. &os; has a built in facility to automatically
|
|
rotate system logs. That is why outputting the log information
|
|
to &man.syslogd.8; is better than the default of outputting to a
|
|
regular file. In the default <filename>rc.conf</filename> file,
|
|
the <literal>ipmon_flags</literal> statement uses the <option>-Ds</option>
|
|
flags:</para>
|
|
|
|
<programlisting>ipmon_flags="-Ds" # D = start as daemon
|
|
# s = log to syslog
|
|
# v = log tcp window, ack, seq
|
|
# n = map IP & port to names</programlisting>
|
|
|
|
<para>The benefits of logging are obvious. It provides the
|
|
ability to review, after the fact, information such as which
|
|
packets had been dropped, what addresses they came from and
|
|
where they were going. These can all provide a significant edge
|
|
in tracking down attackers.</para>
|
|
|
|
<para>Even with the logging facility enabled, IPF will not
|
|
generate any rule logging on its own. The firewall
|
|
administrator decides what rules in the ruleset he wants to
|
|
log and adds the log keyword to those rules. Normally only
|
|
deny rules are logged.</para>
|
|
|
|
<para>It is very customary to include a default deny everything
|
|
rule with the log keyword included as your last rule in the
|
|
ruleset. This makes it possible to see all the packets that did not
|
|
match any of the rules in the ruleset.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>IPMON Logging</title>
|
|
|
|
<para><application>Syslogd</application> uses its own special
|
|
method for segregation of log data. It uses special groupings
|
|
called <quote>facility</quote> and <quote>level</quote>. IPMON
|
|
in <option>-Ds</option> mode uses <literal>local0</literal>
|
|
as the <quote>facility</quote>
|
|
name by default.
|
|
The following levels can be
|
|
used to further segregate the logged data if desired:</para>
|
|
|
|
<screen>LOG_INFO - packets logged using the "log" keyword as the action rather than pass or block.
|
|
LOG_NOTICE - packets logged which are also passed
|
|
LOG_WARNING - packets logged which are also blocked
|
|
LOG_ERR - packets which have been logged and which can be considered short</screen>
|
|
|
|
<!-- XXX: "can be considered short" == "with incomplete header" -->
|
|
|
|
<para>To setup IPFILTER to log all data to
|
|
<filename>/var/log/ipfilter.log</filename>, the file will need to be
|
|
created beforehand. The following command will do that:</para>
|
|
|
|
<screen>&prompt.root; <userinput>touch /var/log/ipfilter.log</userinput></screen>
|
|
|
|
<para>The &man.syslogd.8; function is controlled by definition statements
|
|
in the <filename>/etc/syslog.conf</filename> file. The
|
|
<filename>syslog.conf</filename> file offers considerable
|
|
flexibility in how <application>syslog</application> will deal with system messages issued
|
|
by software applications like IPF.</para>
|
|
|
|
<para>Add the following statement to
|
|
<filename>/etc/syslog.conf</filename>:</para>
|
|
|
|
<programlisting>local0.* /var/log/ipfilter.log</programlisting>
|
|
|
|
<para>The <literal>local0.*</literal>
|
|
means to write all the logged messages to the coded
|
|
file location.</para>
|
|
|
|
<para>To activate the changes to <filename>/etc/syslog.conf
|
|
</filename> you can reboot or bump the &man.syslogd.8; daemon into
|
|
re-reading <filename>/etc/syslog.conf</filename> by running
|
|
<command>/etc/rc.d/syslogd reload</command></para>
|
|
|
|
<para>Do not forget to change
|
|
<filename>/etc/newsyslog.conf</filename> to rotate the new log
|
|
created above.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>The Format of Logged Messages</title>
|
|
|
|
<para>Messages generated by <command>ipmon</command> consist of
|
|
data fields separated by white space. Fields common to all
|
|
messages are:</para>
|
|
|
|
<orderedlist>
|
|
<listitem>
|
|
<para>The date of packet receipt.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>The time of packet receipt. This is in the form
|
|
HH:MM:SS.F, for hours, minutes, seconds, and fractions of a
|
|
second (which can be several digits long).</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>The name of the interface the packet was processed on,
|
|
e.g., <devicename>dc0</devicename>.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>The group and rule number of the rule, e.g.
|
|
<literal>@0:17</literal>.</para>
|
|
</listitem>
|
|
</orderedlist>
|
|
|
|
<para>These can be viewed with <command>ipfstat
|
|
-in</command>.</para>
|
|
|
|
<orderedlist>
|
|
<listitem>
|
|
<para>The action: p for passed, b for blocked, S for a short
|
|
packet, n did not match any rules, L for a log rule. The
|
|
order of precedence in showing flags is: S, p, b, n, L. A
|
|
capital P or B means that the packet has been logged due to
|
|
a global logging setting, not a particular rule.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>The addresses. This is actually three fields: the
|
|
source address and port (separated by a comma), the ->
|
|
symbol, and the destination address and port, e.g.:
|
|
<literal>209.53.17.22,80 -> 198.73.220.17,1722</literal>.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><literal>PR</literal> followed by the protocol name or
|
|
number, e.g.: <literal>PR tcp</literal>.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><literal>len</literal> followed by the header length
|
|
and total length of the packet, e.g.: <literal>len 20 40</literal>.</para>
|
|
</listitem>
|
|
</orderedlist>
|
|
|
|
<para>If the packet is a <acronym>TCP</acronym> packet, there
|
|
will be an additional field starting with a hyphen followed by
|
|
letters corresponding to any flags that were set. See the
|
|
&man.ipf.5; manual page for a list of letters and their
|
|
flags.</para>
|
|
|
|
<para>If the packet is an ICMP packet, there will be two fields
|
|
at the end, the first always being <quote>ICMP</quote>, and the
|
|
next being the ICMP message and sub-message type, separated by
|
|
a slash, e.g., ICMP 3/3 for a port unreachable message.</para>
|
|
</sect2>
|
|
|
|
<sect2 id="firewalls-ipf-rules-script">
|
|
<title>Building the Rule Script with Symbolic
|
|
Substitution</title>
|
|
|
|
<para>Some experienced IPF users create a file containing the
|
|
rules and code them in a manner compatible with running them as
|
|
a script with symbolic substitution. The major benefit of
|
|
doing this is that only the value associated
|
|
with the symbolic name needs to be changed, and when the script is run all the rules
|
|
containing the symbolic name will have the value substituted in
|
|
the rules. Being a script, symbolic substitution can be used
|
|
to code frequently used values and substitute them in multiple
|
|
rules. This can be seen in the following example.</para>
|
|
|
|
<para>The script syntax used here is compatible with the &man.sh.1;, &man.csh.1;,
|
|
and &man.tcsh.1; shells.</para>
|
|
|
|
<para>Symbolic substitution fields are prefixed with a dollar
|
|
sign: <literal>$</literal>.</para>
|
|
|
|
<para>Symbolic fields do not have the $ prefix.</para>
|
|
|
|
<para>The value to populate the symbolic field must be enclosed
|
|
with double quotes (<literal>"</literal>).</para>
|
|
|
|
<para>Start your rule file with something like this:</para>
|
|
|
|
<programlisting>############# Start of IPF rules script ########################
|
|
|
|
oif="dc0" # name of the outbound interface
|
|
odns="192.0.2.11" # ISP's DNS server IP address
|
|
myip="192.0.2.7" # my static IP address from ISP
|
|
ks="keep state"
|
|
fks="flags S keep state"
|
|
|
|
# You can choose between building /etc/ipf.rules file
|
|
# from this script or running this script "as is".
|
|
#
|
|
# Uncomment only one line and comment out another.
|
|
#
|
|
# 1) This can be used for building /etc/ipf.rules:
|
|
#cat > /etc/ipf.rules << EOF
|
|
#
|
|
# 2) This can be used to run script "as is":
|
|
/sbin/ipf -Fa -f - << EOF
|
|
|
|
# Allow out access to my ISP's Domain name server.
|
|
pass out quick on $oif proto tcp from any to $odns port = 53 $fks
|
|
pass out quick on $oif proto udp from any to $odns port = 53 $ks
|
|
|
|
# Allow out non-secure standard www function
|
|
pass out quick on $oif proto tcp from $myip to any port = 80 $fks
|
|
|
|
# Allow out secure www function https over TLS SSL
|
|
pass out quick on $oif proto tcp from $myip to any port = 443 $fks
|
|
EOF
|
|
################## End of IPF rules script ########################</programlisting>
|
|
|
|
<para>That is all there is to it. The rules are not important in
|
|
this example; how the symbolic substitution fields are
|
|
populated and used are. If the above example was in a file
|
|
named <filename>/etc/ipf.rules.script</filename>, these rules could be
|
|
reloaded by entering the following command:</para>
|
|
|
|
<screen>&prompt.root; <userinput>sh /etc/ipf.rules.script</userinput></screen>
|
|
|
|
<para>There is one problem with using a rules file with embedded
|
|
symbolics: IPF does not understand symbolic substitution, and
|
|
cannot read such scripts directly.</para>
|
|
|
|
<para>This script can be used in one of two ways:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>Uncomment the line that begins with
|
|
<literal>cat</literal>, and comment out the line that
|
|
begins with <literal>/sbin/ipf</literal>. Place
|
|
<literal>ipfilter_enable="YES"</literal> into
|
|
<filename>/etc/rc.conf</filename> as usual, and run script
|
|
once after each modification to create or update
|
|
<filename>/etc/ipf.rules</filename>.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Disable IPFILTER in system startup scripts by adding
|
|
<literal>ipfilter_enable="NO"</literal> (this is default
|
|
value) into <filename>/etc/rc.conf</filename> file.</para>
|
|
|
|
<para>Add a script like the following to your
|
|
<filename class="directory">/usr/local/etc/rc.d/</filename> startup
|
|
directory. The script should have an obvious name like
|
|
<filename>ipf.loadrules.sh</filename>. The
|
|
<filename>.sh</filename> extension is mandatory.</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
sh /etc/ipf.rules.script</programlisting>
|
|
|
|
<para>The permissions on this script file must be read,
|
|
write, execute for owner <username>root</username>.</para>
|
|
|
|
<screen>&prompt.root; <userinput>chmod 700 /usr/local/etc/rc.d/ipf.loadrules.sh</userinput></screen>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>Now, when your system boots, your IPF rules will be
|
|
loaded.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>IPF Rulesets</title>
|
|
|
|
<para>A ruleset is a group of IPF rules coded to pass or block
|
|
packets based on the values contained in the packet. The
|
|
bi-directional exchange of packets between hosts comprises a
|
|
session conversation. The firewall ruleset processes both the
|
|
packets arriving from the public Internet, as well as the packets
|
|
produced by the system as a response to them.
|
|
Each <acronym>TCP/IP</acronym> service (i.e.: telnet, www,
|
|
mail, etc.) is predefined by its protocol and privileged (listening)
|
|
port. Packets destined for a specific service, originate from the
|
|
source address using an unprivileged (high order) port and target the
|
|
specific service port on the destination address. All the above
|
|
parameters (i.e.: ports and addresses) can be used as selection
|
|
criteria to create rules which will pass or block services.</para>
|
|
|
|
<indexterm>
|
|
<primary>IPFILTER</primary>
|
|
|
|
<secondary>rule processing order</secondary>
|
|
</indexterm>
|
|
|
|
<para>IPF was originally written using a rules processing logic
|
|
of <quote>the last matching rule wins</quote> and used only
|
|
stateless rules. Over time IPF has been enhanced to include a
|
|
<quote>quick</quote> option and a stateful <quote>keep
|
|
state</quote> option which drastically modernized the rule
|
|
processing logic.</para>
|
|
|
|
<para>The instructions contained in this section are based on
|
|
using rules that contain the <quote>quick</quote> option and
|
|
the stateful <quote>keep state</quote> option. This is the
|
|
basic framework for coding an inclusive firewall rule
|
|
set.</para>
|
|
|
|
<warning>
|
|
<para>When working with the firewall rules, be <emphasis>very
|
|
careful</emphasis>. Some configurations <emphasis>will
|
|
lock you out</emphasis> of the server. To be on the safe
|
|
side, you may wish to consider performing the initial
|
|
firewall configuration from the local console rather than
|
|
doing it remotely e.g., via
|
|
<application>ssh</application>.</para>
|
|
</warning>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Rule Syntax</title>
|
|
|
|
<indexterm>
|
|
<primary>IPFILTER</primary>
|
|
|
|
<secondary>rule syntax</secondary>
|
|
</indexterm>
|
|
|
|
<para>The rule syntax presented here has been simplified to only
|
|
address the modern stateful rule context and <quote>first
|
|
matching rule wins</quote> logic. For the complete legacy rule
|
|
syntax description see the &man.ipf.8; manual page.</para>
|
|
|
|
<para>A <literal>#</literal> character is used to mark the start
|
|
of a comment and may appear at the end of a rule line or on its
|
|
own line. Blank lines are ignored.</para>
|
|
|
|
<para>Rules contain keywords. These keywords have to be coded in
|
|
a specific order from left to right on the line. Keywords are
|
|
identified in bold type. Some keywords have sub-options which
|
|
may be keywords themselves and also include more sub-options.
|
|
Each of the headings in the below syntax has a bold section
|
|
header which expands on the content.</para>
|
|
|
|
<!-- This section is probably wrong. See the OpenBSD flag -->
|
|
<!-- What is the "OpenBSD flag"? Reference please -->
|
|
|
|
<para><replaceable>ACTION IN-OUT OPTIONS SELECTION STATEFUL PROTO
|
|
SRC_ADDR,DST_ADDR OBJECT PORT_NUM TCP_FLAG
|
|
STATEFUL</replaceable></para>
|
|
|
|
<para><replaceable>ACTION</replaceable> = block | pass</para>
|
|
|
|
<para><replaceable>IN-OUT</replaceable> = in | out</para>
|
|
|
|
<para><replaceable>OPTIONS</replaceable> = log | quick | on
|
|
interface-name</para>
|
|
|
|
<para><replaceable>SELECTION</replaceable> = proto value |
|
|
source/destination IP | port = number | flags
|
|
flag-value</para>
|
|
|
|
<para><replaceable>PROTO</replaceable> = tcp/udp | udp | tcp |
|
|
icmp</para>
|
|
|
|
<para><replaceable>SRC_ADD,DST_ADDR</replaceable> = all | from
|
|
object to object</para>
|
|
|
|
<para><replaceable>OBJECT</replaceable> = IP address | any</para>
|
|
|
|
<para><replaceable>PORT_NUM</replaceable> = port number</para>
|
|
|
|
<para><replaceable>TCP_FLAG</replaceable> = S</para>
|
|
|
|
<para><replaceable>STATEFUL</replaceable> = keep state</para>
|
|
|
|
<sect3>
|
|
<title>ACTION</title>
|
|
|
|
<para>The action indicates what to do with the packet if it
|
|
matches the rest of the filter rule. Each rule
|
|
<emphasis>must</emphasis> have an action. The following
|
|
actions are recognized:</para>
|
|
|
|
<para><literal>block</literal> indicates that the packet should
|
|
be dropped if the selection parameters match the
|
|
packet.</para>
|
|
|
|
<para><literal>pass</literal> indicates that the packet should
|
|
exit the firewall if the selection parameters match the
|
|
packet.</para>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>IN-OUT</title>
|
|
|
|
<para>A mandatory requirement is that each filter rule
|
|
explicitly state which side of the I/O it is to be used on.
|
|
The next keyword must be either <literal>in</literal> or <literal>out</literal> and one or the
|
|
other has to be coded or the rule will not pass syntax
|
|
checks.</para>
|
|
|
|
<para><literal>in</literal> means this rule is being applied
|
|
against an inbound packet which has just been received on the
|
|
interface facing the public Internet.</para>
|
|
|
|
<para><literal>out</literal> means this rule is being applied
|
|
against an outbound packet destined for the interface facing
|
|
the public Internet.</para>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>OPTIONS</title>
|
|
|
|
<note>
|
|
<para>These options must be used in the order shown
|
|
here.</para>
|
|
</note>
|
|
|
|
<para><literal>log</literal> indicates that the packet header
|
|
will be written to
|
|
|
|
<!-- XXX - xref here -->
|
|
|
|
the <devicename>ipl</devicename> log (as described in the
|
|
LOGGING section below) if the selection parameters match the
|
|
packet.</para>
|
|
|
|
<para><literal>quick</literal> indicates that if the selection
|
|
parameters match the packet, this rule will be the last rule
|
|
checked, allowing a <quote>short-circuit</quote> path to avoid processing
|
|
any following rules for this packet. This option is a
|
|
mandatory requirement for the modernized rules processing
|
|
logic.</para>
|
|
|
|
<para><literal>on</literal> indicates the interface name to be
|
|
incorporated into the selection parameters. Interface names
|
|
are as displayed by &man.ifconfig.8;. Using this option, the
|
|
rule will only match if the packet is going through that
|
|
interface in the specified direction (in/out). This option
|
|
is a mandatory requirement for the modernized rules
|
|
processing logic.</para>
|
|
|
|
<para>When a packet is logged, the headers of the packet are
|
|
written to the <acronym>IPL</acronym> packet logging pseudo-device.
|
|
Immediately following the <literal>log</literal> keyword, the following
|
|
qualifiers may be used (in this order):</para>
|
|
|
|
<para><literal>body</literal> indicates that the first 128
|
|
bytes of the packet contents will be logged after the
|
|
headers.</para>
|
|
|
|
<para><literal>first</literal> If the <literal>log</literal>
|
|
keyword is being used in conjunction with a <literal>keep
|
|
state</literal> option, it is recommended that this option is
|
|
also applied so that only the triggering packet is logged and
|
|
not every packet which thereafter matches the <quote>keep
|
|
state</quote> information.</para>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>SELECTION</title>
|
|
|
|
<para>The keywords described in this section are used to
|
|
describe attributes of the packet to be checked when
|
|
determining whether rules match or not. There is a
|
|
keyword subject, and it has sub-option keywords, one of
|
|
which has to be selected. The following general-purpose
|
|
attributes are provided for matching, and must be used in
|
|
this order:</para>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>PROTO</title>
|
|
|
|
<para><literal>proto</literal> is the subject keyword and must
|
|
be coded along with one of its corresponding keyword
|
|
sub-option values. The value allows a specific protocol to
|
|
be matched against. This option is a mandatory requirement
|
|
for the modernized rules processing logic.</para>
|
|
|
|
<para><literal>tcp/udp | udp | tcp | icmp</literal> or any
|
|
protocol names found in <filename>/etc/protocols</filename>
|
|
are recognized and may be used. The special protocol keyword
|
|
<literal>tcp/udp</literal> may be used to match either a
|
|
<acronym>TCP</acronym> or a <acronym>UDP</acronym> packet, and has been added as
|
|
a convenience to save duplication of otherwise identical
|
|
rules.</para>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>SRC_ADDR/DST_ADDR</title>
|
|
|
|
<para>The <literal>all</literal> keyword is essentially a
|
|
synonym for <quote>from any to any</quote> with no other
|
|
match parameters.</para>
|
|
|
|
<para><literal>from src to dst</literal>: the <literal>from</literal> and <literal>to</literal>
|
|
keywords are used to match against IP addresses. Rules must
|
|
specify <emphasis>both</emphasis> source and destination parameters.
|
|
<literal>any</literal> is a special keyword that matches any
|
|
IP address. Examples of use: <literal>from any to any</literal>
|
|
or <literal>from 0.0.0.0/0 to any</literal> or <literal>from any to
|
|
0.0.0.0/0</literal> or <literal>from 0.0.0.0 to any</literal> or
|
|
<literal>from any to 0.0.0.0</literal>.</para>
|
|
|
|
|
|
<para>There is no way to match ranges of IP addresses which
|
|
do not express themselves easily using the dotted numeric
|
|
form / mask-length notation. The <filename
|
|
role="package">net-mgmt/ipcalc</filename> port may be used to
|
|
ease up the calculations. Additional information is available in
|
|
the utility's web page: <ulink
|
|
url="http://jodies.de/ipcalc"></ulink>.</para>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>PORT</title>
|
|
|
|
<para>If a port match is included, for either or both of source
|
|
and destination, then it is only applied to
|
|
<acronym>TCP</acronym> and <acronym>UDP</acronym> packets. When composing port
|
|
comparisons, either the service name from
|
|
<filename>/etc/services</filename> or an integer port number
|
|
may be used. When the port appears as part of the <literal>from</literal>
|
|
object, it matches the source port number; when it appears
|
|
as part of the <literal>to</literal> object, it matches the destination port
|
|
number. The use of the port option with the
|
|
<literal>to</literal> object is a mandatory requirement for
|
|
the modernized rules processing logic. Example of use:
|
|
<literal>from any to any port = 80</literal></para>
|
|
|
|
<!-- XXX: Rewritten, but probably needs more changes -->
|
|
|
|
<para>Single port comparisons may be done in a number of ways, using
|
|
a number of different comparison operators. Port ranges may also be
|
|
specified.</para>
|
|
|
|
<para>port "=" | "!=" | "<" | ">" | "<=" | ">=" |
|
|
"eq" | "ne" | "lt" | "gt" | "le" | "ge".</para>
|
|
|
|
<para>To specify port ranges, port "<>" |
|
|
"><"</para>
|
|
|
|
<warning>
|
|
<para>Following the source and destination matching
|
|
parameters, the following two parameters are mandatory
|
|
requirements for the modernized rules processing
|
|
logic.</para>
|
|
</warning>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title><acronym>TCP</acronym>_FLAG</title>
|
|
|
|
<para>Flags are only effective for <acronym>TCP</acronym>
|
|
filtering. The letters represent one of the possible flags
|
|
that can be matched against the <acronym>TCP</acronym> packet
|
|
header.</para>
|
|
|
|
<para>The modernized rules processing logic uses the
|
|
<literal>flags S</literal> parameter to identify the tcp
|
|
session start request.</para>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>STATEFUL</title>
|
|
|
|
<para><literal>keep state</literal> indicates that on a pass
|
|
rule, any packets that match the rules selection parameters
|
|
should activate the stateful filtering facility.</para>
|
|
|
|
<note>
|
|
<para>This option is a mandatory requirement for the
|
|
modernized rules processing logic.</para>
|
|
</note>
|
|
</sect3>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Stateful Filtering</title>
|
|
|
|
<indexterm>
|
|
<primary>IPFILTER</primary>
|
|
|
|
<secondary>stateful filtering</secondary>
|
|
</indexterm>
|
|
|
|
<!-- XXX: duplicated -->
|
|
|
|
<para>Stateful filtering treats traffic as a bi-directional
|
|
exchange of packets comprising a session conversation. When
|
|
activated, keep-state dynamically generates internal rules for
|
|
each anticipated packet being exchanged during the
|
|
bi-directional session conversation. It has sufficient matching
|
|
capabilities to determine if the session conversation between the
|
|
originating sender and the destination are following the valid
|
|
procedure of bi-directional packet exchange. Any packets that
|
|
do not properly fit the session conversation template are
|
|
automatically rejected as impostors.</para>
|
|
|
|
<para>Keep state will also allow <acronym>ICMP</acronym> packets related to a
|
|
<acronym>TCP</acronym> or <acronym>UDP</acronym> session through. So if you get
|
|
<acronym>ICMP</acronym> type 3 code 4 in response to some web surfing allowed out
|
|
by a keep state rule, they will be automatically allowed in.
|
|
Any packet that IPF can be certain is part of an active
|
|
session, even if it is a different protocol, will be let
|
|
in.</para>
|
|
|
|
<para>What happens is:</para>
|
|
|
|
<para>Packets destined to go out through the interface connected to the
|
|
public Internet are first checked against the dynamic state
|
|
table. If the packet matches the next expected packet
|
|
comprising an active session conversation, then it exits the
|
|
firewall and the state of the session conversation flow is
|
|
updated in the dynamic state table. Packets that do not belong to
|
|
an already active session, are simply checked against the outbound
|
|
ruleset.</para>
|
|
|
|
<para>Packets coming in from the interface connected to the public
|
|
Internet are first checked against the dynamic state table. If
|
|
the packet matches the next expected packet comprising an
|
|
active session conversation, then it exits the firewall and
|
|
the state of the session conversation flow is updated in the
|
|
dynamic state table. Packets that do not belong to an already active
|
|
session, are simply checked against the inbound ruleset.</para>
|
|
|
|
<para>When the conversation completes it is removed from the
|
|
dynamic state table.</para>
|
|
|
|
<para>Stateful filtering allows you to focus on blocking/passing
|
|
new sessions. If the new session is passed, all its subsequent
|
|
packets will be allowed through automatically and any impostors
|
|
automatically rejected. If a new session is blocked, none of
|
|
its subsequent packets will be allowed through. Stateful
|
|
filtering has technically advanced matching abilities
|
|
capable of defending against the flood of different attack
|
|
methods currently employed by attackers.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<!-- XXX: This section needs a rewrite -->
|
|
|
|
<title>Inclusive Ruleset Example</title>
|
|
|
|
<para>The following ruleset is an example of how to code a very
|
|
secure inclusive type of firewall. An inclusive firewall only
|
|
allows services matching <literal>pass</literal> rules through, and blocks all
|
|
others by default. Firewalls intended to protect other machines,
|
|
also called <quote>network firewalls</quote>, should have at least
|
|
two interfaces, which are generally configured to trust one side
|
|
(the <acronym>LAN</acronym>) and not the other (the public Internet). Alternatively,
|
|
a firewall might be configured to protect only the system it is
|
|
running on—this is called a
|
|
<quote>host based firewall</quote>, and is particularly appropriate
|
|
for servers on an untrusted network.</para>
|
|
|
|
<para>All &unix; flavored systems including &os; are designed to
|
|
use interface <devicename>lo0</devicename> and IP address
|
|
<hostid role="ipaddr">127.0.0.1</hostid> for internal
|
|
communication within the operating system. The firewall rules
|
|
must contain rules to allow free unmolested movement of these
|
|
special internally used packets.</para>
|
|
|
|
<para>The interface which faces the public Internet is the one
|
|
to place the rules that authorize and control access of the outbound
|
|
and inbound connections. This can be your user PPP
|
|
<devicename>tun0</devicename> interface or your NIC that is
|
|
connected to your DSL or cable modem.</para>
|
|
|
|
<para>In cases where one or more NICs are cabled to private network
|
|
segments, those interfaces may require rules to allow packets
|
|
originating from those LAN interfaces transit to each other and/or
|
|
to the outside (Internet).</para>
|
|
|
|
<para>The rules should be organized into three major
|
|
sections: first trusted interfaces, then the public
|
|
interface outbound, and last the public untrusted interface inbound.</para>
|
|
|
|
<para>The rules in each of the public interface sections should
|
|
have the most frequently matched rules placed before less
|
|
commonly matched rules, with the last rule in the section
|
|
blocking and logging all packets on that interface and
|
|
direction.</para>
|
|
|
|
<para>The Outbound section in the following ruleset only
|
|
contains <literal>pass</literal> rules which contain selection values that
|
|
uniquely identify the service that is authorized for public
|
|
Internet access. All the rules have the <literal>quick</literal>, <literal>on</literal>,
|
|
<literal>proto</literal>, <literal>port</literal>, and <literal>keep state</literal> options set. The <literal>proto
|
|
tcp</literal> rules have the <literal>flag</literal> option included to identify the
|
|
session start request as the triggering packet to activate the
|
|
stateful facility.</para>
|
|
|
|
<para>The Inbound section has all the blocking of undesirable
|
|
packets first, for two different reasons. The first is that
|
|
malicious packets may be partial matches for legitimate traffic.
|
|
These packets have to be discarded rather than allowed in, based on
|
|
their partial matches against <literal>allow</literal> rules.
|
|
The second reason is that known and uninteresting rejects may be
|
|
blocked silently, rather than being caught and logged by the last
|
|
rules in the section. The final rule in each section, blocks and
|
|
logs all packets and can be used to create the legal evidence needed
|
|
to prosecute the people who are attacking your system.</para>
|
|
|
|
<para>Another thing that should be taken care of, is to ensure there is no
|
|
response returned for any of the undesirable traffic. Invalid
|
|
packets should just get dropped and vanish. This way the attacker
|
|
has no knowledge if his packets have reached your system. The
|
|
less the attackers can learn about your system, the more
|
|
time they must invest before actually doing something bad.
|
|
Rules that include a <literal>log first</literal> option, will only
|
|
log the event the first time they are triggered. This option is
|
|
included in the sample <literal>nmap OS fingerprint</literal> rule.
|
|
The <filename role="package">security/nmap</filename> utility is
|
|
commonly used by attackers who attempt to identify the operating
|
|
system of your server.</para>
|
|
|
|
<para>Any time there are logged messages on a rule with
|
|
the <literal>log first</literal> option, an <command>ipfstat -hio</command>
|
|
command should be executed to evaluate how many times the rule has
|
|
actually matched. Large number of matches usually indicate that the
|
|
system is being flooded (i.e.: under attack).</para>
|
|
|
|
<para>The <filename>/etc/services</filename> file may be used to
|
|
lookup unknown port numbers. Alternatively,
|
|
visit <ulink
|
|
url="http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers"></ulink>
|
|
and do a port number lookup to find the purpose of a particular
|
|
port number.</para>
|
|
|
|
<para>Check out this link for port numbers used by Trojans <ulink
|
|
url="http://www.sans.org/security-resources/idfaq/oddports.php"></ulink>.</para>
|
|
|
|
<para>The following ruleset creates a complete and very secure
|
|
<literal>inclusive</literal> type of firewall ruleset that has been
|
|
tested on production systems. It can be easily modified for your
|
|
own system. Just comment out any <literal>pass</literal> rules for
|
|
services that should not be authorized.</para>
|
|
|
|
<para>To avoid logging unwanted messages,
|
|
just add a <literal>block</literal> rule in the inbound section.</para>
|
|
|
|
<para>The <devicename>dc0</devicename> interface name has to be changed
|
|
in every rule to the real interface name of the NIC
|
|
card that connects your system to the public Internet. For
|
|
user PPP it would be <devicename>tun0</devicename>.</para>
|
|
|
|
<para>Add the following statements to
|
|
<filename>/etc/ipf.rules</filename>:</para>
|
|
|
|
<programlisting>#################################################################
|
|
# No restrictions on Inside LAN Interface for private network
|
|
# Not needed unless you have LAN
|
|
#################################################################
|
|
|
|
#pass out quick on xl0 all
|
|
#pass in quick on xl0 all
|
|
|
|
#################################################################
|
|
# No restrictions on Loopback Interface
|
|
#################################################################
|
|
pass in quick on lo0 all
|
|
pass out quick on lo0 all
|
|
|
|
#################################################################
|
|
# Interface facing Public Internet (Outbound Section)
|
|
# Match session start requests originating from behind the
|
|
# firewall on the private network
|
|
# or from this gateway server destined for the public Internet.
|
|
#################################################################
|
|
|
|
# Allow out access to my ISP's Domain name server.
|
|
# xxx must be the IP address of your ISP's DNS.
|
|
# Dup these lines if your ISP has more than one DNS server
|
|
# Get the IP addresses from /etc/resolv.conf file
|
|
pass out quick on dc0 proto tcp from any to xxx port = 53 flags S keep state
|
|
pass out quick on dc0 proto udp from any to xxx port = 53 keep state
|
|
|
|
# Allow out access to my ISP's DHCP server for cable or DSL networks.
|
|
# This rule is not needed for 'user ppp' type connection to the
|
|
# public Internet, so you can delete this whole group.
|
|
# Use the following rule and check log for IP address.
|
|
# Then put IP address in commented out rule & delete first rule
|
|
pass out log quick on dc0 proto udp from any to any port = 67 keep state
|
|
#pass out quick on dc0 proto udp from any to z.z.z.z port = 67 keep state
|
|
|
|
|
|
# Allow out non-secure standard www function
|
|
pass out quick on dc0 proto tcp from any to any port = 80 flags S keep state
|
|
|
|
# Allow out secure www function https over TLS SSL
|
|
pass out quick on dc0 proto tcp from any to any port = 443 flags S keep state
|
|
|
|
# Allow out send & get email function
|
|
pass out quick on dc0 proto tcp from any to any port = 110 flags S keep state
|
|
pass out quick on dc0 proto tcp from any to any port = 25 flags S keep state
|
|
|
|
# Allow out Time
|
|
pass out quick on dc0 proto tcp from any to any port = 37 flags S keep state
|
|
|
|
# Allow out nntp news
|
|
pass out quick on dc0 proto tcp from any to any port = 119 flags S keep state
|
|
|
|
# Allow out gateway & LAN users' non-secure FTP ( both passive & active modes)
|
|
# This function uses the IP<acronym>NAT</acronym> built in FTP proxy function coded in
|
|
# the nat rules file to make this single rule function correctly.
|
|
# If you want to use the pkg_add command to install application packages
|
|
# on your gateway system you need this rule.
|
|
pass out quick on dc0 proto tcp from any to any port = 21 flags S keep state
|
|
|
|
# Allow out ssh/sftp/scp (telnet/rlogin/FTP replacements)
|
|
# This function is using SSH (secure shell)
|
|
pass out quick on dc0 proto tcp from any to any port = 22 flags S keep state
|
|
|
|
# Allow out insecure Telnet
|
|
pass out quick on dc0 proto tcp from any to any port = 23 flags S keep state
|
|
|
|
# Allow out FreeBSD CVSup
|
|
pass out quick on dc0 proto tcp from any to any port = 5999 flags S keep state
|
|
|
|
# Allow out ping to public Internet
|
|
pass out quick on dc0 proto icmp from any to any icmp-type 8 keep state
|
|
|
|
# Allow out whois from LAN to public Internet
|
|
pass out quick on dc0 proto tcp from any to any port = 43 flags S keep state
|
|
|
|
# Block and log only the first occurrence of everything
|
|
# else that's trying to get out.
|
|
# This rule implements the default block
|
|
block out log first quick on dc0 all
|
|
|
|
#################################################################
|
|
# Interface facing Public Internet (Inbound Section)
|
|
# Match packets originating from the public Internet
|
|
# destined for this gateway server or the private network.
|
|
#################################################################
|
|
|
|
# Block all inbound traffic from non-routable or reserved address spaces
|
|
block in quick on dc0 from 192.168.0.0/16 to any #RFC 1918 private IP
|
|
block in quick on dc0 from 172.16.0.0/12 to any #RFC 1918 private IP
|
|
block in quick on dc0 from 10.0.0.0/8 to any #RFC 1918 private IP
|
|
block in quick on dc0 from 127.0.0.0/8 to any #loopback
|
|
block in quick on dc0 from 0.0.0.0/8 to any #loopback
|
|
block in quick on dc0 from 169.254.0.0/16 to any #DHCP auto-config
|
|
block in quick on dc0 from 192.0.2.0/24 to any #reserved for docs
|
|
block in quick on dc0 from 204.152.64.0/23 to any #Sun cluster interconnect
|
|
block in quick on dc0 from 224.0.0.0/3 to any #Class D & E multicast
|
|
|
|
##### Block a bunch of different nasty things. ############
|
|
# That I do not want to see in the log
|
|
|
|
# Block frags
|
|
block in quick on dc0 all with frags
|
|
|
|
# Block short tcp packets
|
|
block in quick on dc0 proto tcp all with short
|
|
|
|
# block source routed packets
|
|
block in quick on dc0 all with opt lsrr
|
|
block in quick on dc0 all with opt ssrr
|
|
|
|
# Block nmap OS fingerprint attempts
|
|
# Log first occurrence of these so I can get their IP address
|
|
block in log first quick on dc0 proto tcp from any to any flags FUP
|
|
|
|
# Block anything with special options
|
|
block in quick on dc0 all with ipopts
|
|
|
|
# Block public pings
|
|
block in quick on dc0 proto icmp all icmp-type 8
|
|
|
|
# Block ident
|
|
block in quick on dc0 proto tcp from any to any port = 113
|
|
|
|
# Block all Netbios service. 137=name, 138=datagram, 139=session
|
|
# Netbios is MS/Windows sharing services.
|
|
# Block MS/Windows hosts2 name server requests 81
|
|
block in log first quick on dc0 proto tcp/udp from any to any port = 137
|
|
block in log first quick on dc0 proto tcp/udp from any to any port = 138
|
|
block in log first quick on dc0 proto tcp/udp from any to any port = 139
|
|
block in log first quick on dc0 proto tcp/udp from any to any port = 81
|
|
|
|
# Allow traffic in from ISP's DHCP server. This rule must contain
|
|
# the IP address of your ISP's DHCP server as it's the only
|
|
# authorized source to send this packet type. Only necessary for
|
|
# cable or DSL configurations. This rule is not needed for
|
|
# 'user ppp' type connection to the public Internet.
|
|
# This is the same IP address you captured and
|
|
# used in the outbound section.
|
|
pass in quick on dc0 proto udp from z.z.z.z to any port = 68 keep state
|
|
|
|
# Allow in standard www function because I have apache server
|
|
pass in quick on dc0 proto tcp from any to any port = 80 flags S keep state
|
|
|
|
# Allow in non-secure Telnet session from public Internet
|
|
# labeled non-secure because ID/PW passed over public Internet as clear text.
|
|
# Delete this sample group if you do not have telnet server enabled.
|
|
#pass in quick on dc0 proto tcp from any to any port = 23 flags S keep state
|
|
|
|
# Allow in secure FTP, Telnet, and SCP from public Internet
|
|
# This function is using SSH (secure shell)
|
|
pass in quick on dc0 proto tcp from any to any port = 22 flags S keep state
|
|
|
|
# Block and log only first occurrence of all remaining traffic
|
|
# coming into the firewall. The logging of only the first
|
|
# occurrence avoids filling up disk with Denial of Service logs.
|
|
# This rule implements the default block.
|
|
block in log first quick on dc0 all
|
|
################### End of rules file #####################################</programlisting>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title><acronym>NAT</acronym></title>
|
|
|
|
<indexterm><primary>NAT</primary></indexterm>
|
|
|
|
<indexterm>
|
|
<primary>IP masquerading</primary>
|
|
|
|
<see>NAT</see>
|
|
</indexterm>
|
|
|
|
<indexterm>
|
|
<primary>network address translation</primary>
|
|
|
|
<see>NAT</see>
|
|
</indexterm>
|
|
|
|
<para><acronym>NAT</acronym> stands for <emphasis>Network Address
|
|
Translation</emphasis>. To those familiar with &linux;, this concept is
|
|
called IP Masquerading; <acronym>NAT</acronym> and IP
|
|
Masquerading are the same thing. One of the many things the
|
|
IPF <acronym>NAT</acronym> function enables is the ability to
|
|
have a private Local Area Network (LAN) behind the firewall
|
|
sharing a single ISP assigned IP address on the public
|
|
Internet.</para>
|
|
|
|
<para>You may ask why would someone want to do this. ISPs
|
|
normally assign a dynamic IP address to their non-commercial
|
|
users. Dynamic means that the IP address can be different each
|
|
time you dial in and log on to your ISP, or for cable and DSL
|
|
modem users, when the modem is power cycled. This dynamic IP
|
|
address is used to identify your system to the public Internet.</para>
|
|
|
|
<para>Now lets say you have five PCs at home and each one needs
|
|
Internet access. You would have to pay your ISP for an
|
|
individual Internet account for each PC and have five phone
|
|
lines.</para>
|
|
|
|
<para>With <acronym>NAT</acronym> only a single account is needed
|
|
with your ISP. The other four PCs may then be cabled to a switch and
|
|
the switch to the NIC in your &os; system which is going to
|
|
service your LAN as a gateway. <acronym>NAT</acronym> will
|
|
automatically translate the private LAN IP address for each
|
|
separate PC on the LAN to the single public IP address as it
|
|
exits the firewall bound for the public Internet. It also does
|
|
the reverse translation for returning packets.</para>
|
|
|
|
<para>There is a special range of IP addresses reserved for
|
|
<acronym>NAT</acronym>ed private LANs. According to
|
|
RFC 1918, the following IP ranges may be used for private nets
|
|
which will never be routed directly to the public
|
|
Internet:</para>
|
|
|
|
<informaltable frame="none" pgwide="1">
|
|
<tgroup cols="2">
|
|
<colspec colwidth="1*"/>
|
|
|
|
<colspec colwidth="1*"/>
|
|
|
|
<colspec colwidth="1*"/>
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry>Start IP <hostid role="ipaddr">10.0.0.0</hostid></entry>
|
|
|
|
<entry>-</entry>
|
|
|
|
<entry>Ending IP <hostid role="ipaddr">10.255.255.255</hostid></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>Start IP <hostid role="ipaddr">172.16.0.0</hostid></entry>
|
|
|
|
<entry>-</entry>
|
|
|
|
<entry>Ending IP <hostid role="ipaddr">172.31.255.255</hostid></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>Start IP <hostid role="ipaddr">192.168.0.0</hostid></entry>
|
|
|
|
<entry>-</entry>
|
|
|
|
<entry>Ending IP <hostid role="ipaddr">192.168.255.255</hostid></entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>IP<acronym>NAT</acronym></title>
|
|
|
|
<indexterm>
|
|
<primary>NAT</primary>
|
|
|
|
<secondary>and IPFILTER</secondary>
|
|
</indexterm>
|
|
|
|
<indexterm><primary><command>ipnat</command></primary></indexterm>
|
|
|
|
<para><acronym>NAT</acronym> rules are loaded by using the
|
|
<command>ipnat</command> command. Typically the
|
|
<acronym>NAT</acronym> rules are stored in
|
|
<filename>/etc/ipnat.rules</filename>. See &man.ipnat.1; for
|
|
details.</para>
|
|
|
|
<para>When changing the <acronym>NAT</acronym> rules after
|
|
<acronym>NAT</acronym> has been started, make your changes to
|
|
the file containing the NAT rules, then run the <command>ipnat</command> command with
|
|
the <option>-CF</option> flags to delete the internal in use
|
|
<acronym>NAT</acronym> rules and flush the contents of the
|
|
translation table of all active entries.</para>
|
|
|
|
<para>To reload the <acronym>NAT</acronym> rules issue a command
|
|
like this:</para>
|
|
|
|
<screen>&prompt.root; <userinput>ipnat -CF -f /etc/ipnat.rules</userinput></screen>
|
|
|
|
<para>To display some statistics about your
|
|
<acronym>NAT</acronym>, use this command:</para>
|
|
|
|
<screen>&prompt.root; <userinput>ipnat -s</userinput></screen>
|
|
|
|
<para>To list the <acronym>NAT</acronym> table's current
|
|
mappings, use this command:</para>
|
|
|
|
<screen>&prompt.root; <userinput>ipnat -l</userinput></screen>
|
|
|
|
<para>To turn verbose mode on, and display information relating
|
|
to rule processing and active rules/table entries:</para>
|
|
|
|
<screen>&prompt.root; <userinput>ipnat -v</userinput></screen>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>IP<acronym>NAT</acronym> Rules</title>
|
|
|
|
<para><acronym>NAT</acronym> rules are very flexible and can
|
|
accomplish many different things to fit the needs of commercial
|
|
and home users.</para>
|
|
|
|
<para>The rule syntax presented here has been simplified to what
|
|
is most commonly used in a non-commercial environment. For a
|
|
complete rule syntax description see the &man.ipnat.5; manual
|
|
page.</para>
|
|
|
|
<para>The syntax for a <acronym>NAT</acronym> rule looks
|
|
something like this:</para>
|
|
|
|
<programlisting>map <replaceable>IF</replaceable> <replaceable>LAN_IP_RANGE</replaceable> -> <replaceable>PUBLIC_ADDRESS</replaceable></programlisting>
|
|
|
|
<para>The keyword <literal>map</literal> starts the rule.</para>
|
|
|
|
<para>Replace <replaceable>IF</replaceable> with the external
|
|
interface.</para>
|
|
|
|
<para>The <replaceable>LAN_IP_RANGE</replaceable> is what your
|
|
internal clients use for IP Addressing, usually this is
|
|
something like <hostid
|
|
role="ipaddr">192.168.1.0/24</hostid>.</para>
|
|
|
|
<para>The <replaceable>PUBLIC_ADDRESS</replaceable> can either
|
|
be the external IP address or the special keyword
|
|
<literal>0/32</literal>, which means to use the IP address
|
|
assigned to <replaceable>IF</replaceable>.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>How <acronym>NAT</acronym> works</title>
|
|
|
|
<para>A packet arrives at the firewall from the LAN with a public
|
|
destination. It passes through the outbound filter rules,
|
|
<acronym>NAT</acronym> gets its turn at the packet and applies
|
|
its rules top down, first matching rule wins.
|
|
<acronym>NAT</acronym> tests each of its rules against the
|
|
packet's interface name and source IP address. When a packet's
|
|
interface name matches a <acronym>NAT</acronym> rule then the
|
|
source IP address (i.e.: private LAN IP address) of the packet
|
|
is checked to see if it falls within the IP address range
|
|
specified to the left of the arrow symbol on the
|
|
<acronym>NAT</acronym> rule. On a match the packet has its
|
|
source IP address rewritten with the public IP address
|
|
obtained by the <literal>0/32</literal> keyword.
|
|
<acronym>NAT</acronym> posts an entry in its internal
|
|
<acronym>NAT</acronym> table so when the packet returns from
|
|
the public Internet it can be mapped back to its original
|
|
private IP address and then passed to the filter rules for
|
|
processing.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Enabling IP<acronym>NAT</acronym></title>
|
|
|
|
<para>To enable IP<acronym>NAT</acronym> add these statements to
|
|
<filename>/etc/rc.conf</filename>.</para>
|
|
|
|
<para>To enable your machine to route traffic between
|
|
interfaces:</para>
|
|
|
|
<programlisting>gateway_enable="YES"</programlisting>
|
|
|
|
<para>To start IP<acronym>NAT</acronym> automatically each
|
|
time:</para>
|
|
|
|
<programlisting>ipnat_enable="YES"</programlisting>
|
|
|
|
<para>To specify where to load the IP<acronym>NAT</acronym> rules
|
|
from:</para>
|
|
|
|
<programlisting>ipnat_rules="/etc/ipnat.rules"</programlisting>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title><acronym>NAT</acronym> for a Large LAN</title>
|
|
|
|
<para>For networks that have large numbers of PC's on the LAN or
|
|
networks with more than a single LAN, the process of funneling
|
|
all those private IP addresses into a single public IP address
|
|
becomes a resource problem that may cause problems with the
|
|
same port numbers being used many times across many
|
|
<acronym>NAT</acronym>ed LAN PC's, causing collisions. There
|
|
are two ways to relieve this resource problem.</para>
|
|
|
|
<sect3>
|
|
<title>Assigning Ports to Use</title>
|
|
|
|
<!-- What does it mean ? Is there something missing ?-->
|
|
<!-- XXXBLAH <- Apparently you can't start a sect
|
|
with a <programlisting> tag ?-->
|
|
|
|
<para>A normal NAT rule would look like:</para>
|
|
|
|
<programlisting>map dc0 192.168.1.0/24 -> 0/32</programlisting>
|
|
|
|
<para>In the above rule the packet's source port is unchanged
|
|
as the packet passes through IP<acronym>NAT</acronym>. By
|
|
adding the <literal>portmap</literal> keyword,
|
|
IP<acronym>NAT</acronym> can be directed to only use source ports in the specified range.
|
|
For example the following rule will tell
|
|
IP<acronym>NAT</acronym> to modify the source port to be
|
|
within the range shown:</para>
|
|
|
|
<programlisting>map dc0 192.168.1.0/24 -> 0/32 portmap tcp/udp 20000:60000</programlisting>
|
|
|
|
<para>Additionally we can make things even easier by using the
|
|
<literal>auto</literal> keyword to tell
|
|
IP<acronym>NAT</acronym> to determine by itself which ports
|
|
are available to use:</para>
|
|
|
|
<programlisting>map dc0 192.168.1.0/24 -> 0/32 portmap tcp/udp auto</programlisting>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>Using a Pool of Public Addresses</title>
|
|
|
|
<para>In very large LANs there comes a point where there are just too
|
|
many LAN addresses to fit into a single public address. If a block
|
|
of public IP addresses is available, these addresses can be used as
|
|
a <quote>pool</quote>, and IP<acronym>NAT</acronym> may pick one of
|
|
the public IP addresses as packet-addresses are mapped on their way
|
|
out.</para>
|
|
|
|
<para>For example, instead of mapping all packets through a single
|
|
public IP address, as in:</para>
|
|
|
|
<programlisting>map dc0 192.168.1.0/24 -> 204.134.75.1</programlisting>
|
|
|
|
<para>A range of public IP addresses can be specified either with a
|
|
netmask:</para>
|
|
|
|
<programlisting>map dc0 192.168.1.0/24 -> 204.134.75.0/255.255.255.0</programlisting>
|
|
|
|
<para>or using CIDR notation:</para>
|
|
|
|
<programlisting>map dc0 192.168.1.0/24 -> 204.134.75.0/24</programlisting>
|
|
</sect3>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Port Redirection</title>
|
|
|
|
<para>A very common practice is to have a web server, email
|
|
server, database server and DNS server each segregated to a
|
|
different PC on the LAN. In this case the traffic from these
|
|
servers still have to be <acronym>NAT</acronym>ed, but there
|
|
has to be some way to direct the inbound traffic to the
|
|
correct LAN PCs. IP<acronym>NAT</acronym> has the redirection
|
|
facilities of <acronym>NAT</acronym> to solve this problem.
|
|
For example, assuming a web server operating on LAN address <hostid
|
|
role="ipaddr">10.0.10.25</hostid> and using a single public IP
|
|
address of <hostid role="ipaddr">20.20.20.5</hostid> the rule would
|
|
be coded as follows:</para>
|
|
|
|
<programlisting>rdr dc0 20.20.20.5/32 port 80 -> 10.0.10.25 port 80</programlisting>
|
|
|
|
<para>or:</para>
|
|
|
|
<programlisting>rdr dc0 0.0.0.0/0 port 80 -> 10.0.10.25 port 80</programlisting>
|
|
|
|
<para>or for a LAN DNS Server on LAN address of <hostid
|
|
role="ipaddr">10.0.10.33</hostid> that needs to receive
|
|
public DNS requests:</para>
|
|
|
|
<programlisting>rdr dc0 20.20.20.5/32 port 53 -> 10.0.10.33 port 53 udp</programlisting>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>FTP and <acronym>NAT</acronym></title>
|
|
|
|
<para>FTP is a dinosaur left over from the time before the
|
|
Internet as it is known today, when research universities were
|
|
leased lined together and FTP was used to share files among
|
|
research Scientists. This was a time when data security was
|
|
not a consideration. Over the years the FTP protocol became
|
|
buried into the backbone of the emerging Internet and its
|
|
username and password being sent in clear text was never
|
|
changed to address new security concerns. FTP has two flavors,
|
|
it can run in active mode or passive mode. The difference is
|
|
in how the data channel is acquired. Passive mode is more
|
|
secure as the data channel is acquired by the ordinal ftp
|
|
session requester. For a real good explanation of FTP and the
|
|
different modes see <ulink
|
|
url="http://www.slacksite.com/other/ftp.html"></ulink>.</para>
|
|
|
|
<sect3>
|
|
<title>IP<acronym>NAT</acronym> Rules</title>
|
|
|
|
<para>IP<acronym>NAT</acronym> has a special built in FTP proxy
|
|
option which can be specified on the <acronym>NAT</acronym>
|
|
map rule. It can monitor all outbound packet traffic for FTP
|
|
active or passive start session requests and dynamically
|
|
create temporary filter rules containing only the port number
|
|
really in use for the data channel. This eliminates the
|
|
security risk FTP normally exposes the firewall to from
|
|
having large ranges of high order port numbers open.</para>
|
|
|
|
<para>This rule will handle all the traffic for the internal
|
|
LAN:</para>
|
|
|
|
<programlisting>map dc0 10.0.10.0/29 -> 0/32 proxy port 21 ftp/tcp</programlisting>
|
|
|
|
<para>This rule handles the FTP traffic from the
|
|
gateway:</para>
|
|
|
|
<programlisting>map dc0 0.0.0.0/0 -> 0/32 proxy port 21 ftp/tcp</programlisting>
|
|
|
|
<para>This rule handles all non-FTP traffic from the internal
|
|
LAN:</para>
|
|
|
|
<programlisting>map dc0 10.0.10.0/29 -> 0/32</programlisting>
|
|
|
|
<para>The FTP map rule goes before our regular map rule. All
|
|
packets are tested against the first rule from the top.
|
|
Matches on interface name, then private LAN source IP
|
|
address, and then is it a FTP packet. If all that matches
|
|
then the special FTP proxy creates temp filter rules to let
|
|
the FTP session packets pass in and out, in addition to also
|
|
<acronym>NAT</acronym>ing the FTP packets. All LAN packets
|
|
that are not FTP do not match the first rule and fall
|
|
through to the third rule and are tested, matching on
|
|
interface and source IP, then are
|
|
<acronym>NAT</acronym>ed.</para>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>IP<acronym>NAT</acronym> FTP Filter Rules</title>
|
|
|
|
<para>Only one filter rule is needed for FTP if the
|
|
<acronym>NAT</acronym> FTP proxy is used.</para>
|
|
|
|
<para>Without the FTP Proxy, the following three rules will be
|
|
needed:</para>
|
|
|
|
<programlisting># Allow out LAN PC client FTP to public Internet
|
|
# Active and passive modes
|
|
pass out quick on rl0 proto tcp from any to any port = 21 flags S keep state
|
|
|
|
# Allow out passive mode data channel high order port numbers
|
|
pass out quick on rl0 proto tcp from any to any port > 1024 flags S keep state
|
|
|
|
# Active mode let data channel in from FTP server
|
|
pass in quick on rl0 proto tcp from any to any port = 20 flags S keep state</programlisting>
|
|
</sect3>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 id="firewalls-ipfw">
|
|
<title>IPFW</title>
|
|
|
|
<indexterm>
|
|
<primary>firewall</primary>
|
|
|
|
<secondary>IPFW</secondary>
|
|
</indexterm>
|
|
|
|
<para>The IPFIREWALL (<acronym>IPFW</acronym>) is a &os; sponsored firewall software
|
|
application authored and maintained by &os; volunteer staff
|
|
members. It uses the legacy stateless rules and a legacy rule
|
|
coding technique to achieve what is referred to as Simple
|
|
Stateful logic.</para>
|
|
|
|
<para>The IPFW sample ruleset (found in
|
|
<filename>/etc/rc.firewall</filename> and
|
|
<filename>/etc/rc.firewall6</filename>) in the standard &os;
|
|
install is rather simple and it is not expected to be used
|
|
directly without modifications. The example does not use
|
|
stateful filtering, which is beneficial in most setups, so it
|
|
will not be used as base for this section.</para>
|
|
|
|
<para>The IPFW stateless rule syntax is empowered with technically
|
|
sophisticated selection capabilities which far surpasses the
|
|
knowledge level of the customary firewall installer. IPFW is
|
|
targeted at the professional user or the advanced technical
|
|
computer hobbyist who have advanced packet selection
|
|
requirements. A high degree of detailed knowledge into how
|
|
different protocols use and create their unique packet header
|
|
information is necessary before the power of the IPFW rules can
|
|
be unleashed. Providing that level of explanation is out of the
|
|
scope of this section of the Handbook.</para>
|
|
|
|
<para>IPFW is composed of seven components, the primary component
|
|
is the kernel firewall filter rule processor and its integrated
|
|
packet accounting facility, the logging facility, the <literal>divert</literal>
|
|
rule which triggers the <acronym>NAT</acronym> facility, and the
|
|
advanced special purpose facilities, the dummynet traffic shaper
|
|
facilities, the <literal>fwd rule</literal> forward facility, the bridge
|
|
facility, and the ipstealth facility. IPFW supports both IPv4
|
|
and IPv6.</para>
|
|
|
|
<sect2 id="firewalls-ipfw-enable">
|
|
<title>Enabling IPFW</title>
|
|
|
|
<indexterm>
|
|
<primary>IPFW</primary>
|
|
|
|
<secondary>enabling</secondary>
|
|
</indexterm>
|
|
|
|
<para>IPFW is included in the basic &os; install as a separate
|
|
run time loadable module. The system will dynamically load the
|
|
kernel module when the <filename>rc.conf</filename> statement
|
|
<literal>firewall_enable="YES"</literal> is used. There is no
|
|
need to compile IPFW into the &os; kernel.</para>
|
|
|
|
<para>After rebooting your system with
|
|
<literal>firewall_enable="YES"</literal> in
|
|
<filename>rc.conf</filename> the following white highlighted
|
|
message is displayed on the screen as part of the boot
|
|
process:</para>
|
|
|
|
<screen>ipfw2 initialized, divert disabled, rule-based forwarding disabled, default to deny, logging disabled</screen>
|
|
|
|
<para>The loadable module does have logging ability
|
|
compiled in. To enable logging and set the verbose logging
|
|
limit, there is a knob that can be set in
|
|
<filename>/etc/sysctl.conf</filename>. By adding these
|
|
statements, logging will be enabled on future reboots:</para>
|
|
|
|
<programlisting>net.inet.ip.fw.verbose=1
|
|
net.inet.ip.fw.verbose_limit=5</programlisting>
|
|
</sect2>
|
|
|
|
<sect2 id="firewalls-ipfw-kernel">
|
|
<title>Kernel Options</title>
|
|
|
|
<indexterm>
|
|
<primary>kernel options</primary>
|
|
|
|
<secondary>IPFIREWALL</secondary>
|
|
</indexterm>
|
|
|
|
<indexterm>
|
|
<primary>kernel options</primary>
|
|
|
|
<secondary>IPFIREWALL_VERBOSE</secondary>
|
|
</indexterm>
|
|
|
|
<indexterm>
|
|
<primary>kernel options</primary>
|
|
|
|
<secondary>IPFIREWALL_VERBOSE_LIMIT</secondary>
|
|
</indexterm>
|
|
|
|
<indexterm>
|
|
<primary>IPFW</primary>
|
|
|
|
<secondary>kernel options</secondary>
|
|
</indexterm>
|
|
|
|
<para>It is not a mandatory requirement to enable IPFW by
|
|
compiling the following options into the &os; kernel. It is
|
|
presented here as background information only.</para>
|
|
|
|
<programlisting>options IPFIREWALL</programlisting>
|
|
|
|
<para>This option enables IPFW as part of the kernel</para>
|
|
|
|
<programlisting>options IPFIREWALL_VERBOSE</programlisting>
|
|
|
|
<para>Enables logging of packets that pass through IPFW and have
|
|
the <literal>log</literal> keyword specified in the ruleset.</para>
|
|
|
|
<programlisting>options IPFIREWALL_VERBOSE_LIMIT=5</programlisting>
|
|
|
|
<para>Limits the number of packets logged through &man.syslogd.8;
|
|
on a per entry basis. This option may be used in
|
|
hostile environments, when firewall activity logging is desired.
|
|
This will close a possible denial of service attack via syslog
|
|
flooding.</para>
|
|
|
|
<indexterm>
|
|
<primary>kernel options</primary>
|
|
|
|
<secondary>IPFIREWALL_DEFAULT_TO_ACCEPT</secondary>
|
|
</indexterm>
|
|
|
|
<programlisting>options IPFIREWALL_DEFAULT_TO_ACCEPT</programlisting>
|
|
|
|
<para>This option will allow everything to pass through the
|
|
firewall by default, which is a good idea when the firewall is being
|
|
set up for the first time.</para>
|
|
|
|
<indexterm>
|
|
<primary>kernel options</primary>
|
|
|
|
<secondary>IPDIVERT</secondary>
|
|
</indexterm>
|
|
|
|
<programlisting>options IPDIVERT</programlisting>
|
|
|
|
<para>This enables the use of <acronym>NAT</acronym>
|
|
functionality.</para>
|
|
|
|
<note>
|
|
<para>The firewall will block all incoming and outgoing packets if
|
|
either the <literal>IPFIREWALL_DEFAULT_TO_ACCEPT</literal> kernel
|
|
option or a rule to explicitly allow these connections are
|
|
missing.</para>
|
|
</note>
|
|
</sect2>
|
|
|
|
<sect2 id="firewalls-ipfw-rc">
|
|
<title><filename>/etc/rc.conf</filename> Options</title>
|
|
|
|
<para>Enable the firewall:</para>
|
|
|
|
<programlisting>firewall_enable="YES"</programlisting>
|
|
|
|
<para>To select one of the default firewall types provided by
|
|
&os;, select one by reading the
|
|
<filename>/etc/rc.firewall</filename> file and place it in
|
|
the following:</para>
|
|
|
|
<programlisting>firewall_type="open"</programlisting>
|
|
|
|
<para>Available values for this setting are:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><literal>open</literal> — pass all traffic.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><literal>client</literal> — will protect only this
|
|
machine.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><literal>simple</literal> — protect the whole
|
|
network.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><literal>closed</literal> — entirely disables IP
|
|
traffic except for the loopback interface.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><literal>UNKNOWN</literal> — disables the loading
|
|
of firewall rules.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><filename><replaceable>filename</replaceable></filename> — absolute path of
|
|
file containing firewall rules.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>It is possible to use two different ways to load custom
|
|
rules for <application>ipfw</application> firewall. One is
|
|
by setting <literal>firewall_type</literal> variable to absolute
|
|
path of file, which contains <emphasis>firewall rules</emphasis>
|
|
without any command-line options for &man.ipfw.8; itself.
|
|
The following is a simple example of a ruleset file that blocks
|
|
all incoming and outgoing traffic:</para>
|
|
|
|
<programlisting>add deny in
|
|
add deny out</programlisting>
|
|
|
|
<para>On the other hand, it is possible to set the
|
|
<literal>firewall_script</literal> variable to the absolute path of an
|
|
executable script that includes <command>ipfw</command> commands
|
|
being executed at system boot time. A valid ruleset script that
|
|
would be equivalent to the ruleset file shown above would
|
|
be the following:</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
|
|
ipfw -q flush
|
|
|
|
ipfw add deny in
|
|
ipfw add deny out</programlisting>
|
|
|
|
<note>
|
|
<para>If <literal>firewall_type</literal> is set to either
|
|
<literal>client</literal> or <literal>simple</literal>, the
|
|
default rules found in <filename>/etc/rc.firewall</filename>
|
|
should be reviewed to fit to the configuration of the given
|
|
machine. Also note that the examples used in this chapter
|
|
expect that the <literal>firewall_script</literal> is set to
|
|
<filename>/etc/ipfw.rules</filename>.</para>
|
|
</note>
|
|
|
|
<para>Enable logging:</para>
|
|
|
|
<programlisting>firewall_logging="YES"</programlisting>
|
|
|
|
<warning>
|
|
<para>The only thing that the
|
|
<varname>firewall_logging</varname> variable will do is
|
|
setting the <varname>net.inet.ip.fw.verbose</varname> sysctl
|
|
variable to the value of <literal>1</literal> (see <xref
|
|
linkend="firewalls-ipfw-enable"/>). There is no
|
|
<filename>rc.conf</filename> variable to set log limitations,
|
|
but it can be set via sysctl variable, manually or from the
|
|
<filename>/etc/sysctl.conf</filename> file:</para>
|
|
|
|
<programlisting>net.inet.ip.fw.verbose_limit=5</programlisting>
|
|
</warning>
|
|
|
|
<para>If your machine is acting as a gateway, i.e., providing
|
|
Network Address Translation (NAT) via &man.natd.8;, please
|
|
refer to <xref linkend="network-natd"/> for information
|
|
regarding the required <filename>/etc/rc.conf</filename>
|
|
options.</para>
|
|
</sect2>
|
|
|
|
<sect2 id="firewalls-ipfw-cmd">
|
|
<title>The IPFW Command</title>
|
|
|
|
<indexterm><primary><command>ipfw</command></primary></indexterm>
|
|
|
|
<para>The <command>ipfw</command> command is the normal vehicle for making manual
|
|
single rule additions or deletions to the active firewall
|
|
internal rules while it is running. The problem with using
|
|
this method is once your system is shutdown or halted all the
|
|
rules that were added, changed or deleted are lost. Writing all
|
|
your rules in a file and using that file to load the rules at
|
|
boot time, or to replace in mass the currently running firewall
|
|
rules with changes you made to the files content, is the
|
|
recommended method used here.</para>
|
|
|
|
<para>The <command>ipfw</command> command is still a very useful way to display the
|
|
running firewall rules to the console screen. The IPFW
|
|
accounting facility dynamically creates a counter for each
|
|
rule that counts each packet that matches the rule. During the
|
|
process of testing a rule, listing the rule with its counter
|
|
is one of the ways of determining if the rule is
|
|
functioning.</para>
|
|
|
|
<para>To list all the rules in sequence:</para>
|
|
|
|
<screen>&prompt.root; <userinput>ipfw list</userinput></screen>
|
|
|
|
<para>To list all the rules with a time stamp of when the last
|
|
time the rule was matched:</para>
|
|
|
|
<screen>&prompt.root; <userinput>ipfw -t list</userinput></screen>
|
|
|
|
<para>The next example lists accounting information, the packet count for
|
|
matched rules along with the rules themselves. The first
|
|
column is the rule number, followed by the number of outgoing
|
|
matched packets, followed by the number of incoming matched
|
|
packets, and then the rule itself.</para>
|
|
|
|
<screen>&prompt.root; <userinput>ipfw -a list</userinput></screen>
|
|
|
|
<para>List the dynamic rules in addition to the static
|
|
rules:</para>
|
|
|
|
<screen>&prompt.root; <userinput>ipfw -d list</userinput></screen>
|
|
|
|
<para>Also show the expired dynamic rules:</para>
|
|
|
|
<screen>&prompt.root; <userinput>ipfw -d -e list</userinput></screen>
|
|
|
|
<para>Zero the counters:</para>
|
|
|
|
<screen>&prompt.root; <userinput>ipfw zero</userinput></screen>
|
|
|
|
<para>Zero the counters for just the rule with number
|
|
<replaceable>NUM</replaceable>:</para>
|
|
|
|
<screen>&prompt.root; <userinput>ipfw zero <replaceable>NUM</replaceable></userinput></screen>
|
|
</sect2>
|
|
|
|
<sect2 id="firewalls-ipfw-rules">
|
|
<title>IPFW Rulesets</title>
|
|
|
|
<!-- This has already appeared once -->
|
|
|
|
<para>A ruleset is a group of IPFW rules coded to allow or deny
|
|
packets based on the values contained in the packet. The
|
|
bi-directional exchange of packets between hosts comprises a
|
|
session conversation. The firewall ruleset processes both the
|
|
packets arriving from the public Internet, as well as the packets
|
|
originating from the system as a response to them.
|
|
Each <acronym>TCP/IP</acronym> service (i.e.: telnet, www,
|
|
mail, etc.) is predefined by its protocol and privileged (listening)
|
|
port. Packets destined for a specific service, originate from the
|
|
source address using an unprivileged (high order) port and target
|
|
the specific service port on the destination address. All the above
|
|
parameters (i.e., ports and addresses) can be used as selection
|
|
criteria to create rules which will pass or block services.</para>
|
|
|
|
<indexterm>
|
|
<primary>IPFW</primary>
|
|
|
|
<secondary>rule processing order</secondary>
|
|
</indexterm>
|
|
|
|
<!-- Needs rewording to include note below -->
|
|
|
|
<para>When a packet enters the firewall it is compared against
|
|
the first rule in the ruleset and progresses one rule at a time
|
|
moving from top to bottom of the set in ascending rule number
|
|
sequence order. When the packet matches the selection parameters
|
|
of a rule, the rules' action field value is executed and the
|
|
search of the ruleset terminates for that packet. This is
|
|
referred to as <quote>the first match wins</quote> search
|
|
method. If the packet does not match any of the rules, it gets
|
|
caught by the mandatory IPFW default rule, number 65535 which
|
|
denies all packets and discards them without any reply back to
|
|
the originating destination.</para>
|
|
|
|
<note>
|
|
<para>The search continues after <literal>count</literal>,
|
|
<literal>skipto</literal> and <literal>tee</literal>
|
|
rules.</para>
|
|
</note>
|
|
|
|
<para>The instructions contained here are based on using rules
|
|
that contain the stateful <literal>keep state</literal>, <literal>limit</literal>, <literal>in</literal>, <literal>out</literal>
|
|
and <literal>via</literal> options. This is the basic framework for coding an
|
|
inclusive type firewall ruleset.</para>
|
|
|
|
<warning>
|
|
<para>Be careful when working with firewall rules, as it is easy to
|
|
end up locking yourself out.</para>
|
|
</warning>
|
|
|
|
<sect3 id="firewalls-ipfw-rules-syntax">
|
|
<title>Rule Syntax</title>
|
|
|
|
<indexterm>
|
|
<primary>IPFW</primary>
|
|
|
|
<secondary>rule syntax</secondary>
|
|
</indexterm>
|
|
|
|
<para>The rule syntax presented here has been simplified to
|
|
what is necessary to create a standard inclusive type
|
|
firewall ruleset. For a complete rule syntax description
|
|
see the &man.ipfw.8; manual page.</para>
|
|
|
|
<para>Rules contain keywords: these keywords have to be coded
|
|
in a specific order from left to right on the line. Keywords
|
|
are identified in bold type. Some keywords have sub-options
|
|
which may be keywords them selves and also include more
|
|
sub-options.</para>
|
|
|
|
<para><literal>#</literal> is used to mark the start of a
|
|
comment and may appear at the end of a rule line or on its
|
|
own lines. Blank lines are ignored.</para>
|
|
|
|
<para><replaceable>CMD RULE_NUMBER ACTION LOGGING SELECTION
|
|
STATEFUL</replaceable></para>
|
|
|
|
<sect4>
|
|
<title>CMD</title>
|
|
|
|
<para>Each new rule has to be prefixed with
|
|
<parameter>add</parameter> to add the
|
|
rule to the internal table.</para>
|
|
</sect4>
|
|
|
|
<sect4>
|
|
<title>RULE_NUMBER</title>
|
|
|
|
<para>Each rule is associated with a rule_number in the range
|
|
1..65535.</para>
|
|
</sect4>
|
|
|
|
<sect4>
|
|
<title>ACTION</title>
|
|
|
|
<para>A rule can be associated with one of the following
|
|
actions, which will be executed when the packet matches
|
|
the selection criterion of the rule.</para>
|
|
|
|
<para><parameter>allow | accept | pass |
|
|
permit</parameter></para>
|
|
|
|
<para>These all mean the same thing which is to allow packets
|
|
that match the rule to exit the firewall rule processing.
|
|
The search terminates at this rule.</para>
|
|
|
|
<para><parameter>check-state</parameter></para>
|
|
|
|
<para>Checks the packet against the dynamic rules table. If
|
|
a match is found, execute the action associated with the
|
|
rule which generated this dynamic rule, otherwise move to
|
|
the next rule. The check-state rule does not have
|
|
selection criterion. If no check-state rule is present in
|
|
the ruleset, the dynamic rules table is checked at the
|
|
first keep-state or limit rule.</para>
|
|
|
|
<para><parameter>deny | drop</parameter></para>
|
|
|
|
<para>Both words mean the same thing which is to discard
|
|
packets that match this rule. The search
|
|
terminates.</para>
|
|
</sect4>
|
|
|
|
<sect4>
|
|
<title>Logging</title>
|
|
|
|
<para><parameter>log</parameter> or
|
|
<parameter>logamount</parameter></para>
|
|
|
|
<para>When a packet matches a rule with the <literal>log</literal> keyword, a
|
|
message will be logged to &man.syslogd.8; with a facility name of
|
|
SECURITY. The logging only occurs if the number of
|
|
packets logged so far for that particular rule does not
|
|
exceed the <literal>logamount</literal> parameter. If no <literal>logamount</literal> is
|
|
specified, the limit is taken from the sysctl variable
|
|
<literal>net.inet.ip.fw.verbose_limit</literal>. In both cases, a value of
|
|
zero removes the logging limit. Once the limit is
|
|
reached, logging can be re-enabled by clearing the
|
|
logging counter or the packet counter for that rule, see
|
|
the <command>ipfw reset log</command> command.</para>
|
|
|
|
<note>
|
|
<para>Logging is done after
|
|
all other packet matching conditions have been
|
|
successfully verified, and before performing the final
|
|
action (accept, deny) on the packet. It is up to you to
|
|
decide which rules you want to enable logging on.</para>
|
|
</note>
|
|
</sect4>
|
|
|
|
<sect4>
|
|
<title>Selection</title>
|
|
|
|
<para>The keywords described in this section are used to
|
|
describe attributes of the packet to be checked when
|
|
determining whether rules match the packet or not.
|
|
The following general-purpose attributes are provided for
|
|
matching, and must be used in this order:</para>
|
|
|
|
<para><parameter>udp | tcp | icmp</parameter></para>
|
|
|
|
<para>Any other protocol names found in
|
|
<filename>/etc/protocols</filename> are also recognized and may
|
|
be used. The value specified is the protocol to be matched
|
|
against. This is a mandatory requirement.</para>
|
|
|
|
<para><parameter>from src to dst</parameter></para>
|
|
|
|
<para>The <literal>from</literal> and <literal>to</literal> keywords are used to match against IP
|
|
addresses. Rules must specify <emphasis>both</emphasis> source and destination
|
|
parameters. <literal>any</literal> is a special keyword
|
|
that matches any IP address. <literal>me</literal> is a
|
|
special keyword that matches any IP address configured on
|
|
an interface in your &os; system to represent the PC the
|
|
firewall is running on (i.e.: this box) as in <literal>from me to
|
|
any</literal> or <literal>from any to me</literal> or <literal>from 0.0.0.0/0 to any</literal> or
|
|
<literal>from any to 0.0.0.0/0</literal> or <literal>from 0.0.0.0 to any</literal> or <literal>from
|
|
any to 0.0.0.0</literal> or <literal>from me to 0.0.0.0</literal>. IP addresses are
|
|
specified as a dotted IP address numeric form/mask-length (CIDR notation),
|
|
or as single dotted IP address numeric form. This is a
|
|
mandatory requirement. The <filename
|
|
role="package">net-mgmt/ipcalc</filename> port may be used to
|
|
ease up the calculations. Additional
|
|
information is available in the utility's web page: <ulink
|
|
url="http://jodies.de/ipcalc"></ulink>.</para>
|
|
|
|
<para><parameter>port number</parameter></para>
|
|
|
|
<para>For protocols which support port numbers (such as
|
|
<acronym>TCP</acronym> and <acronym>UDP</acronym>), it is mandatory to
|
|
code the port number of the service that will be matched.
|
|
Service names (from
|
|
<filename>/etc/services</filename>) may be used instead of
|
|
numeric port values.</para>
|
|
|
|
<para><parameter>in | out</parameter></para>
|
|
|
|
<para>Matches incoming or outgoing packets, respectively.
|
|
The <literal>in</literal> and <literal>out</literal> are keywords and it is mandatory that
|
|
one or the other is coded as part of your rule matching
|
|
criterion.</para>
|
|
|
|
<para><parameter>via IF</parameter></para>
|
|
|
|
<para>Matches packets going through the interface specified
|
|
by exact name. The <literal>via</literal> keyword causes
|
|
the interface to always be checked as part of the match
|
|
process.</para>
|
|
|
|
<para><parameter>setup</parameter></para>
|
|
|
|
<para>This is a mandatory keyword that identifies the session
|
|
start request for <acronym>TCP</acronym> packets.</para>
|
|
|
|
<para><parameter>keep-state</parameter></para>
|
|
|
|
<para>This is a mandatory keyword. Upon a match, the
|
|
firewall will create a dynamic rule, whose default behavior
|
|
is to match bidirectional traffic between source and
|
|
destination IP/port using the same protocol.</para>
|
|
|
|
<para><parameter>limit {src-addr | src-port | dst-addr |
|
|
dst-port}</parameter></para>
|
|
|
|
<para>The firewall will only allow
|
|
<replaceable>N</replaceable> connections with the same set
|
|
of parameters as specified in the rule. One or more of
|
|
source and destination addresses and ports can be
|
|
specified. The <literal>limit</literal> and <literal>keep-state</literal> can not be used on the
|
|
same rule. The <literal>limit</literal> option provides the same stateful function as
|
|
<literal>keep-state</literal>, plus its own functions.</para>
|
|
</sect4>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>Stateful Rule Option</title>
|
|
|
|
<indexterm>
|
|
<primary>IPFW</primary>
|
|
|
|
<secondary>stateful filtering</secondary>
|
|
</indexterm>
|
|
|
|
<!-- XXX: duplicated -->
|
|
|
|
<para>Stateful filtering treats traffic as a bi-directional
|
|
exchange of packets comprising a session conversation. It
|
|
has the matching capabilities to determine if the session
|
|
conversation between the originating sender and the
|
|
destination are following the valid procedure of
|
|
bi-directional packet exchange. Any packets that do not
|
|
properly fit the session conversation template are
|
|
automatically rejected as impostors.</para>
|
|
|
|
<para>The <literal>check-state</literal> option is used to identify where in the IPFW rules
|
|
set the packet is to be tested against the dynamic rules
|
|
facility. On a match the packet exits the firewall to
|
|
continue on its way and a new rule is dynamically created for
|
|
the next anticipated packet being exchanged during this
|
|
bi-directional session conversation. On a no match the
|
|
packet advances to the next rule in the ruleset for
|
|
testing.</para>
|
|
|
|
<para>The dynamic rules facility is vulnerable to resource
|
|
depletion from a SYN-flood attack which would open a huge
|
|
number of dynamic rules. To counter this attack, &os;
|
|
added another new option named <literal>limit</literal>. This
|
|
option is used to limit the number of simultaneous session
|
|
conversations by checking the rules source or
|
|
destinations fields as directed by the <literal>limit</literal> option and
|
|
using the packet's IP address found there, in a search of
|
|
the open dynamic rules counting the number of times this
|
|
rule and IP address combination occurred, if this count is
|
|
greater that the value specified on the <literal>limit</literal> option, the
|
|
packet is discarded.</para>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>Logging Firewall Messages</title>
|
|
|
|
<indexterm>
|
|
<primary>IPFW</primary>
|
|
|
|
<secondary>logging</secondary>
|
|
</indexterm>
|
|
|
|
<para>The benefits of logging are obvious: it provides the
|
|
ability to review after the fact the rules you activated
|
|
logging on which provides information like, what packets had
|
|
been dropped, what addresses they came from and where they were
|
|
going, giving you a significant edge in tracking down
|
|
attackers.</para>
|
|
|
|
<para>Even with the logging facility enabled, IPFW will not
|
|
generate any rule logging on it's own. The firewall
|
|
administrator decides what rules in the ruleset will be
|
|
logged, and adds the <literal>log</literal> verb to those rules. Normally only
|
|
deny rules are logged, like the deny rule for incoming
|
|
<acronym>ICMP</acronym> pings. It is very customary to
|
|
duplicate the <quote>ipfw default deny everything</quote> rule with the
|
|
<literal>log</literal> verb included as your last rule in the ruleset. This
|
|
way it is possible to see all the packets that did not match any
|
|
of the rules in the ruleset.</para>
|
|
|
|
<para>Logging is a two edged sword, if you are not careful, you
|
|
can lose yourself in the over abundance of log data and fill
|
|
your disk up with growing log files. DoS attacks that fill
|
|
up disk drives is one of the oldest attacks around. These
|
|
log messages are not only written to <application>syslogd</application>, but also are
|
|
displayed on the root console screen and soon become very
|
|
annoying.</para>
|
|
|
|
<para>The <literal>IPFIREWALL_VERBOSE_LIMIT=5</literal>
|
|
kernel option limits the number of consecutive messages
|
|
sent to the system logger &man.syslogd.8;, concerning the packet
|
|
matching of a given rule. When this option is enabled in
|
|
the kernel, the number of consecutive messages concerning
|
|
a particular rule is capped at the number specified. There
|
|
is nothing to be gained from 200 log messages saying the
|
|
same identical thing. For instance, five consecutive
|
|
messages concerning a particular rule would be logged to
|
|
<application>syslogd</application>, the remainder identical consecutive messages would
|
|
be counted and posted to <application>syslogd</application> with a phrase like
|
|
the following:</para>
|
|
|
|
<programlisting>last message repeated 45 times</programlisting>
|
|
|
|
<para>All logged packets messages are written by default to
|
|
<filename>/var/log/security</filename> file, which is defined
|
|
in the <filename>/etc/syslog.conf</filename> file.</para>
|
|
</sect3>
|
|
|
|
<sect3 id="firewalls-ipfw-rules-script">
|
|
<title>Building a Rule Script</title>
|
|
|
|
<para>Most experienced IPFW users create a file containing the
|
|
rules and code them in a manner compatible with running them
|
|
as a script. The major benefit of doing this is the firewall
|
|
rules can be refreshed in mass without the need of rebooting
|
|
the system to activate them. This method is very
|
|
convenient in testing new rules as the procedure can be
|
|
executed as many times as needed. Being a script,
|
|
symbolic substitution can be used to code frequent used values and
|
|
substitute them in multiple rules. This is shown in
|
|
the following example.</para>
|
|
|
|
<para>The script syntax used here is compatible with the &man.sh.1;,
|
|
&man.csh.1;, &man.tcsh.1; shells. Symbolic substitution fields are
|
|
prefixed with a dollar sign $. Symbolic fields do not
|
|
have the $ prefix. The value to populate the symbolic
|
|
field must be enclosed in "double quotes".</para>
|
|
|
|
<para>Start your rules file like this:</para>
|
|
|
|
<programlisting>############### start of example ipfw rules script #############
|
|
#
|
|
ipfw -q -f flush # Delete all rules
|
|
# Set defaults
|
|
oif="tun0" # out interface
|
|
odns="192.0.2.11" # ISP's DNS server IP address
|
|
cmd="ipfw -q add " # build rule prefix
|
|
ks="keep-state" # just too lazy to key this each time
|
|
$cmd 00500 check-state
|
|
$cmd 00502 deny all from any to any frag
|
|
$cmd 00501 deny tcp from any to any established
|
|
$cmd 00600 allow tcp from any to any 80 out via $oif setup $ks
|
|
$cmd 00610 allow tcp from any to $odns 53 out via $oif setup $ks
|
|
$cmd 00611 allow udp from any to $odns 53 out via $oif $ks
|
|
################### End of example ipfw rules script ############</programlisting>
|
|
|
|
<para>That is all there is to it. The rules are not important
|
|
in this example, how the symbolic substitution field are
|
|
populated and used are.</para>
|
|
|
|
<para>If the above example was in the
|
|
<filename>/etc/ipfw.rules</filename> file, the rules could be
|
|
reloaded by entering the following on the command line.</para>
|
|
|
|
<screen>&prompt.root; <userinput>sh /etc/ipfw.rules</userinput></screen>
|
|
|
|
<para>The <filename>/etc/ipfw.rules</filename> file could be
|
|
located anywhere you want and the file could be named any
|
|
thing you would like.</para>
|
|
|
|
<para>The same thing could also be accomplished by running
|
|
these commands by hand:</para>
|
|
|
|
<screen>&prompt.root; <userinput>ipfw -q -f flush</userinput>
|
|
&prompt.root; <userinput>ipfw -q add check-state</userinput>
|
|
&prompt.root; <userinput>ipfw -q add deny all from any to any frag</userinput>
|
|
&prompt.root; <userinput>ipfw -q add deny tcp from any to any established</userinput>
|
|
&prompt.root; <userinput>ipfw -q add allow tcp from any to any 80 out via tun0 setup keep-state</userinput>
|
|
&prompt.root; <userinput>ipfw -q add allow tcp from any to 192.0.2.11 53 out via tun0 setup keep-state</userinput>
|
|
&prompt.root; <userinput>ipfw -q add 00611 allow udp from any to 192.0.2.11 53 out via tun0 keep-state</userinput></screen>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>Stateful Ruleset</title>
|
|
|
|
<para>The following non-<acronym>NAT</acronym>ed ruleset is an
|
|
example of how to code a very secure 'inclusive' type of
|
|
firewall. An inclusive firewall only allows services
|
|
matching pass rules through and blocks all other by default.
|
|
Firewalls designed to protect entire network segments, have at minimum two interfaces which must
|
|
have rules to allow the firewall to function.</para>
|
|
|
|
<para>All &unix; flavored operating systems, &os; included, are
|
|
designed to use interface <devicename>lo0</devicename> and IP
|
|
address <hostid role="ipaddr">127.0.0.1</hostid> for internal
|
|
communication with in the operating system. The firewall
|
|
rules must contain rules to allow free unmolested movement of
|
|
these special internally used packets.</para>
|
|
|
|
<para>The interface which faces the public Internet is the one
|
|
to place the rules that authorize and control access of the
|
|
outbound and inbound connections. This can be your user
|
|
<acronym>PPP</acronym>
|
|
<devicename>tun0</devicename> interface or your NIC that is
|
|
connected to your DSL or cable modem.</para>
|
|
|
|
<para>In cases where one or more than one NICs are connected to
|
|
a private LAN behind the firewall, those interfaces must
|
|
have rules coded to allow free unmolested movement of
|
|
packets originating from those LAN interfaces.</para>
|
|
|
|
<para>The rules should be first organized into three major
|
|
sections, all the free unmolested interfaces, public
|
|
interface outbound, and the public interface inbound.</para>
|
|
|
|
<para>The order of the rules in each of the public interface
|
|
sections should be in order of the most used rules being
|
|
placed before less often used rules with the last rule in
|
|
the section blocking and logging all packets on that interface
|
|
and direction.</para>
|
|
|
|
<para>The Outbound section in the following ruleset only
|
|
contains <literal>allow</literal> rules which contain selection values that
|
|
uniquely identify the service that is authorized for public
|
|
Internet access. All the rules have the <literal>proto</literal>, <literal>port</literal>,
|
|
<literal>in/out</literal>, <literal>via</literal> and <literal>keep state</literal> option coded. The <literal>proto tcp</literal>
|
|
rules have the <literal>setup</literal> option included to identify the start
|
|
session request as the trigger packet to be posted to the
|
|
keep state stateful table.</para>
|
|
|
|
<para>The Inbound section has all the blocking of undesirable
|
|
packets first, for two different reasons. The first is that
|
|
malicious packets may be partial matches for legitimate traffic.
|
|
These packets have to be discarded rather than allowed in, based on
|
|
their partial matches against <literal>allow</literal> rules.
|
|
The second reason is that known and uninteresting rejects may be
|
|
blocked silently, rather than being caught and logged by the last
|
|
rules in the section. The final rule in each section, blocks and
|
|
logs all packets and can be used to create the legal evidence needed
|
|
to prosecute the people who are attacking your system.</para>
|
|
|
|
<para>Another thing that should be taken care of, is to insure there
|
|
is no response returned for any of the undesirable stuff. Invalid
|
|
packets should just get dropped and vanish. This way the attacker
|
|
has no knowledge if his packets have reached your system.
|
|
The less the attackers can learn about your system, the more
|
|
secure it is. Packets with unrecognized port numbers may be looked
|
|
up in <filename>/etc/services/</filename> or go to <ulink
|
|
url="http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers"></ulink>
|
|
and do a port number lookup to find the purpose of the particular
|
|
port number is. Check out this link for port numbers used by
|
|
Trojans: <ulink
|
|
url="http://www.sans.org/security-resources/idfaq/oddports.php"></ulink>.</para>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>An Example Inclusive Ruleset</title>
|
|
|
|
<para>The following non-<acronym>NAT</acronym>ed ruleset is a
|
|
complete inclusive type ruleset. It is safe to use this ruleset
|
|
on your own systems. Just comment out any <literal>pass</literal>
|
|
rules for services that are not required. To avoid logging
|
|
undesired messages, add a <literal>deny</literal> rule in the
|
|
inbound section. The <devicename>dc0</devicename> interface will
|
|
have to be changed in every rule, with the actual name of the
|
|
interface (NIC) that connects your system to the public Internet.
|
|
For user <acronym>PPP</acronym>, this would be
|
|
<devicename>tun0</devicename>.</para>
|
|
|
|
<para>There is a noticeable pattern in the usage of these
|
|
rules.</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>All statements that are a request to start a session
|
|
to the public Internet use <literal>keep-state</literal>.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>All the authorized services that originate from the
|
|
public Internet have the <literal>limit</literal> option to stop
|
|
flooding.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>All rules use <literal>in</literal> or <literal>out</literal> to clarify direction.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>All rules use <literal>via</literal> <replaceable>interface-name</replaceable> to specify the
|
|
interface the packet is traveling over.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>The following rules go into
|
|
<filename>/etc/ipfw.rules</filename>.</para>
|
|
|
|
<programlisting>################ Start of IPFW rules file ###############################
|
|
# Flush out the list before we begin.
|
|
ipfw -q -f flush
|
|
|
|
# Set rules command prefix
|
|
cmd="ipfw -q add"
|
|
pif="dc0" # public interface name of NIC
|
|
# facing the public Internet
|
|
|
|
#################################################################
|
|
# No restrictions on Inside LAN Interface for private network
|
|
# Not needed unless you have LAN.
|
|
# Change xl0 to your LAN NIC interface name
|
|
#################################################################
|
|
#$cmd 00005 allow all from any to any via xl0
|
|
|
|
#################################################################
|
|
# No restrictions on Loopback Interface
|
|
#################################################################
|
|
$cmd 00010 allow all from any to any via lo0
|
|
|
|
#################################################################
|
|
# Allow the packet through if it has previous been added to the
|
|
# the "dynamic" rules table by a allow keep-state statement.
|
|
#################################################################
|
|
$cmd 00015 check-state
|
|
|
|
#################################################################
|
|
# Interface facing Public Internet (Outbound Section)
|
|
# Interrogate session start requests originating from behind the
|
|
# firewall on the private network or from this gateway server
|
|
# destined for the public Internet.
|
|
#################################################################
|
|
|
|
# Allow out access to my ISP's Domain name server.
|
|
# x.x.x.x must be the IP address of your ISP.s DNS
|
|
# Dup these lines if your ISP has more than one DNS server
|
|
# Get the IP addresses from /etc/resolv.conf file
|
|
$cmd 00110 allow tcp from any to x.x.x.x 53 out via $pif setup keep-state
|
|
$cmd 00111 allow udp from any to x.x.x.x 53 out via $pif keep-state
|
|
|
|
# Allow out access to my ISP's DHCP server for cable/DSL configurations.
|
|
# This rule is not needed for .user ppp. connection to the public Internet.
|
|
# so you can delete this whole group.
|
|
# Use the following rule and check log for IP address.
|
|
# Then put IP address in commented out rule & delete first rule
|
|
$cmd 00120 allow log udp from any to any 67 out via $pif keep-state
|
|
#$cmd 00120 allow udp from any to x.x.x.x 67 out via $pif keep-state
|
|
|
|
# Allow out non-secure standard www function
|
|
$cmd 00200 allow tcp from any to any 80 out via $pif setup keep-state
|
|
|
|
# Allow out secure www function https over TLS SSL
|
|
$cmd 00220 allow tcp from any to any 443 out via $pif setup keep-state
|
|
|
|
# Allow out send & get email function
|
|
$cmd 00230 allow tcp from any to any 25 out via $pif setup keep-state
|
|
$cmd 00231 allow tcp from any to any 110 out via $pif setup keep-state
|
|
|
|
# Allow out FBSD (make install & CVSUP) functions
|
|
# Basically give user root "GOD" privileges.
|
|
$cmd 00240 allow tcp from me to any out via $pif setup keep-state uid root
|
|
|
|
# Allow out ping
|
|
$cmd 00250 allow icmp from any to any out via $pif keep-state
|
|
|
|
# Allow out Time
|
|
$cmd 00260 allow tcp from any to any 37 out via $pif setup keep-state
|
|
|
|
# Allow out nntp news (i.e., news groups)
|
|
$cmd 00270 allow tcp from any to any 119 out via $pif setup keep-state
|
|
|
|
# Allow out secure FTP, Telnet, and SCP
|
|
# This function is using SSH (secure shell)
|
|
$cmd 00280 allow tcp from any to any 22 out via $pif setup keep-state
|
|
|
|
# Allow out whois
|
|
$cmd 00290 allow tcp from any to any 43 out via $pif setup keep-state
|
|
|
|
# deny and log everything else that.s trying to get out.
|
|
# This rule enforces the block all by default logic.
|
|
$cmd 00299 deny log all from any to any out via $pif
|
|
|
|
#################################################################
|
|
# Interface facing Public Internet (Inbound Section)
|
|
# Check packets originating from the public Internet
|
|
# destined for this gateway server or the private network.
|
|
#################################################################
|
|
|
|
# Deny all inbound traffic from non-routable reserved address spaces
|
|
$cmd 00300 deny all from 192.168.0.0/16 to any in via $pif #RFC 1918 private IP
|
|
$cmd 00301 deny all from 172.16.0.0/12 to any in via $pif #RFC 1918 private IP
|
|
$cmd 00302 deny all from 10.0.0.0/8 to any in via $pif #RFC 1918 private IP
|
|
$cmd 00303 deny all from 127.0.0.0/8 to any in via $pif #loopback
|
|
$cmd 00304 deny all from 0.0.0.0/8 to any in via $pif #loopback
|
|
$cmd 00305 deny all from 169.254.0.0/16 to any in via $pif #DHCP auto-config
|
|
$cmd 00306 deny all from 192.0.2.0/24 to any in via $pif #reserved for docs
|
|
$cmd 00307 deny all from 204.152.64.0/23 to any in via $pif #Sun cluster interconnect
|
|
$cmd 00308 deny all from 224.0.0.0/3 to any in via $pif #Class D & E multicast
|
|
|
|
# Deny public pings
|
|
$cmd 00310 deny icmp from any to any in via $pif
|
|
|
|
# Deny ident
|
|
$cmd 00315 deny tcp from any to any 113 in via $pif
|
|
|
|
# Deny all Netbios service. 137=name, 138=datagram, 139=session
|
|
# Netbios is MS/Windows sharing services.
|
|
# Block MS/Windows hosts2 name server requests 81
|
|
$cmd 00320 deny tcp from any to any 137 in via $pif
|
|
$cmd 00321 deny tcp from any to any 138 in via $pif
|
|
$cmd 00322 deny tcp from any to any 139 in via $pif
|
|
$cmd 00323 deny tcp from any to any 81 in via $pif
|
|
|
|
# Deny any late arriving packets
|
|
$cmd 00330 deny all from any to any frag in via $pif
|
|
|
|
# Deny ACK packets that did not match the dynamic rule table
|
|
$cmd 00332 deny tcp from any to any established in via $pif
|
|
|
|
# Allow traffic in from ISP's DHCP server. This rule must contain
|
|
# the IP address of your ISP.s DHCP server as it.s the only
|
|
# authorized source to send this packet type.
|
|
# Only necessary for cable or DSL configurations.
|
|
# This rule is not needed for .user ppp. type connection to
|
|
# the public Internet. This is the same IP address you captured
|
|
# and used in the outbound section.
|
|
#$cmd 00360 allow udp from any to x.x.x.x 67 in via $pif keep-state
|
|
|
|
# Allow in standard www function because I have apache server
|
|
$cmd 00400 allow tcp from any to me 80 in via $pif setup limit src-addr 2
|
|
|
|
# Allow in secure FTP, Telnet, and SCP from public Internet
|
|
$cmd 00410 allow tcp from any to me 22 in via $pif setup limit src-addr 2
|
|
|
|
# Allow in non-secure Telnet session from public Internet
|
|
# labeled non-secure because ID & PW are passed over public
|
|
# Internet as clear text.
|
|
# Delete this sample group if you do not have telnet server enabled.
|
|
$cmd 00420 allow tcp from any to me 23 in via $pif setup limit src-addr 2
|
|
|
|
# Reject & Log all incoming connections from the outside
|
|
$cmd 00499 deny log all from any to any in via $pif
|
|
|
|
# Everything else is denied by default
|
|
# deny and log all packets that fell through to see what they are
|
|
$cmd 00999 deny log all from any to any
|
|
################ End of IPFW rules file ###############################</programlisting>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>An Example <acronym>NAT</acronym> and Stateful
|
|
Ruleset</title>
|
|
|
|
<indexterm>
|
|
<primary>NAT</primary>
|
|
|
|
<secondary>and IPFW</secondary>
|
|
</indexterm>
|
|
|
|
<para>There are some additional configuration statements that
|
|
need to be enabled to activate the <acronym>NAT</acronym>
|
|
function of IPFW. The kernel source needs <literal>option IPDIVERT</literal>
|
|
statement added to the other IPFIREWALL statements compiled
|
|
into a custom kernel.</para>
|
|
|
|
<para>In addition to the normal IPFW options in
|
|
<filename>/etc/rc.conf</filename>, the following are
|
|
needed.</para>
|
|
|
|
<programlisting>natd_enable="YES" # Enable <acronym>NAT</acronym>D function
|
|
natd_interface="rl0" # interface name of public Internet NIC
|
|
natd_flags="-dynamic -m" # -m = preserve port numbers if possible</programlisting>
|
|
|
|
<para>Utilizing stateful rules with <literal>divert natd</literal> rule (Network
|
|
Address Translation) greatly complicates the ruleset coding
|
|
logic. The positioning of the <literal>check-state</literal>, and <literal>divert natd</literal>
|
|
rules in the ruleset becomes very critical. This is no
|
|
longer a simple fall-through logic flow. A new action type
|
|
is used, called <literal>skipto</literal>. To use the <literal>skipto</literal> command it is
|
|
mandatory that each rule is numbered, so the
|
|
<literal>skipto</literal> rule number knows exactly where it is jumping
|
|
to.</para>
|
|
|
|
<para>The following is an uncommented example of one coding
|
|
method, selected here to explain the sequence of the packet
|
|
flow through the rulesets.</para>
|
|
|
|
<para>The processing flow starts with the first rule from the
|
|
top of the rule file and progress one rule at a time deeper
|
|
into the file until the end is reached or the packet being
|
|
tested to the selection criteria matches and the packet is
|
|
released out of the firewall. It is important to take notice
|
|
of the location of rule numbers 100 101, 450, 500, and 510.
|
|
These rules control the translation of the outbound and
|
|
inbound packets so their entries in the keep-state dynamic
|
|
table always register the private LAN IP address. Next
|
|
notice that all the allow and deny rules specify the
|
|
direction the packet is going (i.e.: outbound or inbound) and
|
|
the interface. Also notice that the start outbound
|
|
session requests, all <literal>skipto rule 500</literal> for the network address
|
|
translation.</para>
|
|
|
|
<para>Lets say a LAN user uses their web browser to get a web
|
|
page. Web pages are transmitted over port 80. So the
|
|
packet enters the firewall. It does not match rule 100 because it
|
|
is headed out rather than in. It passes rule 101 because this is the
|
|
first packet, so it has not been posted to the keep-state
|
|
dynamic table yet. The packet finally comes to rule 125 a
|
|
matches. It is outbound through the NIC facing the public
|
|
Internet. The packet still has it's source IP address as a
|
|
private LAN IP address. On the match to this rule, two
|
|
actions take place. The <literal>keep-state</literal> option will post this
|
|
rule into the keep-state dynamic rules table and the
|
|
specified action is executed. The action is part of the info
|
|
posted to the dynamic table. In this case it is <literal>skipto rule
|
|
500</literal>. Rule 500 <acronym>NAT</acronym>s the packet IP address
|
|
and out it goes. Remember this, this is very important.
|
|
This packet makes its way to the destination, where a response
|
|
packet is generated and sent back. This new packet
|
|
enters the top of the ruleset. This time it does match rule
|
|
100 and has it destination IP address mapped back to its
|
|
corresponding LAN IP address. It then is processed by the
|
|
<literal>check-state</literal> rule, it is found in the table as an existing
|
|
session conversation and released to the LAN. It goes to the
|
|
LAN PC that sent it and a new packet is sent requesting
|
|
another segment of the data from the remote server. This
|
|
time it gets checked by the <literal>check-state</literal> rule and its outbound
|
|
entry is found, the associated action, <literal>skipto 500</literal>, is
|
|
executed. The packet jumps to rule 500 gets
|
|
<acronym>NAT</acronym>ed and released on it's way out.</para>
|
|
|
|
<para>On the inbound side, everything coming in that is part
|
|
of an existing session conversation is being automatically
|
|
handled by the <literal>check-state</literal> rule and the properly placed
|
|
<literal>divert natd</literal> rules. All we have to address is denying all the
|
|
bad packets and only allowing in the authorized services.
|
|
Lets say there is an apache server running on the firewall box
|
|
and we want people on the public Internet to be able to
|
|
access the local web site. The new inbound start request
|
|
packet matches rule 100 and its IP address is mapped to LAN
|
|
IP for the firewall box. The packet is then matched against
|
|
all the nasty things that need to be checked for and finally matches
|
|
against rule 425. On a match two things occur. The packet
|
|
rule is posted to the keep-state dynamic table but this time
|
|
any new session requests originating from that source IP
|
|
address is limited to 2. This defends against DoS attacks of
|
|
service running on the specified port number. The action is
|
|
<literal>allow</literal> so the packet is released to the LAN.
|
|
The packet generated as a response, is recognized by the
|
|
<literal>check-state</literal> as belonging to an
|
|
existing session conversation. It is then sent to rule 500 for
|
|
<acronym>NAT</acronym>ing and released to the outbound
|
|
interface.</para>
|
|
|
|
<para>Example Ruleset #1:</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
cmd="ipfw -q add"
|
|
skip="skipto 500"
|
|
pif=rl0
|
|
ks="keep-state"
|
|
good_tcpo="22,25,37,43,53,80,443,110,119"
|
|
|
|
ipfw -q -f flush
|
|
|
|
$cmd 002 allow all from any to any via xl0 # exclude LAN traffic
|
|
$cmd 003 allow all from any to any via lo0 # exclude loopback traffic
|
|
|
|
$cmd 100 divert natd ip from any to any in via $pif
|
|
$cmd 101 check-state
|
|
|
|
# Authorized outbound packets
|
|
$cmd 120 $skip udp from any to xx.168.240.2 53 out via $pif $ks
|
|
$cmd 121 $skip udp from any to xx.168.240.5 53 out via $pif $ks
|
|
$cmd 125 $skip tcp from any to any $good_tcpo out via $pif setup $ks
|
|
$cmd 130 $skip icmp from any to any out via $pif $ks
|
|
$cmd 135 $skip udp from any to any 123 out via $pif $ks
|
|
|
|
|
|
# Deny all inbound traffic from non-routable reserved address spaces
|
|
$cmd 300 deny all from 192.168.0.0/16 to any in via $pif #RFC 1918 private IP
|
|
$cmd 301 deny all from 172.16.0.0/12 to any in via $pif #RFC 1918 private IP
|
|
$cmd 302 deny all from 10.0.0.0/8 to any in via $pif #RFC 1918 private IP
|
|
$cmd 303 deny all from 127.0.0.0/8 to any in via $pif #loopback
|
|
$cmd 304 deny all from 0.0.0.0/8 to any in via $pif #loopback
|
|
$cmd 305 deny all from 169.254.0.0/16 to any in via $pif #DHCP auto-config
|
|
$cmd 306 deny all from 192.0.2.0/24 to any in via $pif #reserved for docs
|
|
$cmd 307 deny all from 204.152.64.0/23 to any in via $pif #Sun cluster
|
|
$cmd 308 deny all from 224.0.0.0/3 to any in via $pif #Class D & E multicast
|
|
|
|
# Authorized inbound packets
|
|
$cmd 400 allow udp from xx.70.207.54 to any 68 in $ks
|
|
$cmd 420 allow tcp from any to me 80 in via $pif setup limit src-addr 1
|
|
|
|
|
|
$cmd 450 deny log ip from any to any
|
|
|
|
# This is skipto location for outbound stateful rules
|
|
$cmd 500 divert natd ip from any to any out via $pif
|
|
$cmd 510 allow ip from any to any
|
|
|
|
######################## end of rules ##################</programlisting>
|
|
|
|
<para>The following is pretty much the same as above, but uses
|
|
a self documenting coding style full of description comments
|
|
to help the inexperienced IPFW rule writer to better
|
|
understand what the rules are doing.</para>
|
|
|
|
<para>Example Ruleset #2:</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
################ Start of IPFW rules file ###############################
|
|
# Flush out the list before we begin.
|
|
ipfw -q -f flush
|
|
|
|
# Set rules command prefix
|
|
cmd="ipfw -q add"
|
|
skip="skipto 800"
|
|
pif="rl0" # public interface name of NIC
|
|
# facing the public Internet
|
|
|
|
#################################################################
|
|
# No restrictions on Inside LAN Interface for private network
|
|
# Change xl0 to your LAN NIC interface name
|
|
#################################################################
|
|
$cmd 005 allow all from any to any via xl0
|
|
|
|
#################################################################
|
|
# No restrictions on Loopback Interface
|
|
#################################################################
|
|
$cmd 010 allow all from any to any via lo0
|
|
|
|
#################################################################
|
|
# check if packet is inbound and nat address if it is
|
|
#################################################################
|
|
$cmd 014 divert natd ip from any to any in via $pif
|
|
|
|
#################################################################
|
|
# Allow the packet through if it has previous been added to the
|
|
# the "dynamic" rules table by a allow keep-state statement.
|
|
#################################################################
|
|
$cmd 015 check-state
|
|
|
|
#################################################################
|
|
# Interface facing Public Internet (Outbound Section)
|
|
# Check session start requests originating from behind the
|
|
# firewall on the private network or from this gateway server
|
|
# destined for the public Internet.
|
|
#################################################################
|
|
|
|
# Allow out access to my ISP's Domain name server.
|
|
# x.x.x.x must be the IP address of your ISP's DNS
|
|
# Dup these lines if your ISP has more than one DNS server
|
|
# Get the IP addresses from /etc/resolv.conf file
|
|
$cmd 020 $skip tcp from any to x.x.x.x 53 out via $pif setup keep-state
|
|
|
|
|
|
# Allow out access to my ISP's DHCP server for cable/DSL configurations.
|
|
$cmd 030 $skip udp from any to x.x.x.x 67 out via $pif keep-state
|
|
|
|
# Allow out non-secure standard www function
|
|
$cmd 040 $skip tcp from any to any 80 out via $pif setup keep-state
|
|
|
|
# Allow out secure www function https over TLS SSL
|
|
$cmd 050 $skip tcp from any to any 443 out via $pif setup keep-state
|
|
|
|
# Allow out send & get email function
|
|
$cmd 060 $skip tcp from any to any 25 out via $pif setup keep-state
|
|
$cmd 061 $skip tcp from any to any 110 out via $pif setup keep-state
|
|
|
|
# Allow out FreeBSD (make install & CVSUP) functions
|
|
# Basically give user root "GOD" privileges.
|
|
$cmd 070 $skip tcp from me to any out via $pif setup keep-state uid root
|
|
|
|
# Allow out ping
|
|
$cmd 080 $skip icmp from any to any out via $pif keep-state
|
|
|
|
# Allow out Time
|
|
$cmd 090 $skip tcp from any to any 37 out via $pif setup keep-state
|
|
|
|
# Allow out nntp news (i.e., news groups)
|
|
$cmd 100 $skip tcp from any to any 119 out via $pif setup keep-state
|
|
|
|
# Allow out secure FTP, Telnet, and SCP
|
|
# This function is using SSH (secure shell)
|
|
$cmd 110 $skip tcp from any to any 22 out via $pif setup keep-state
|
|
|
|
# Allow out whois
|
|
$cmd 120 $skip tcp from any to any 43 out via $pif setup keep-state
|
|
|
|
# Allow ntp time server
|
|
$cmd 130 $skip udp from any to any 123 out via $pif keep-state
|
|
|
|
#################################################################
|
|
# Interface facing Public Internet (Inbound Section)
|
|
# Check packets originating from the public Internet
|
|
# destined for this gateway server or the private network.
|
|
#################################################################
|
|
|
|
# Deny all inbound traffic from non-routable reserved address spaces
|
|
$cmd 300 deny all from 192.168.0.0/16 to any in via $pif #RFC 1918 private IP
|
|
$cmd 301 deny all from 172.16.0.0/12 to any in via $pif #RFC 1918 private IP
|
|
$cmd 302 deny all from 10.0.0.0/8 to any in via $pif #RFC 1918 private IP
|
|
$cmd 303 deny all from 127.0.0.0/8 to any in via $pif #loopback
|
|
$cmd 304 deny all from 0.0.0.0/8 to any in via $pif #loopback
|
|
$cmd 305 deny all from 169.254.0.0/16 to any in via $pif #DHCP auto-config
|
|
$cmd 306 deny all from 192.0.2.0/24 to any in via $pif #reserved for docs
|
|
$cmd 307 deny all from 204.152.64.0/23 to any in via $pif #Sun cluster
|
|
$cmd 308 deny all from 224.0.0.0/3 to any in via $pif #Class D & E multicast
|
|
|
|
# Deny ident
|
|
$cmd 315 deny tcp from any to any 113 in via $pif
|
|
|
|
# Deny all Netbios service. 137=name, 138=datagram, 139=session
|
|
# Netbios is MS/Windows sharing services.
|
|
# Block MS/Windows hosts2 name server requests 81
|
|
$cmd 320 deny tcp from any to any 137 in via $pif
|
|
$cmd 321 deny tcp from any to any 138 in via $pif
|
|
$cmd 322 deny tcp from any to any 139 in via $pif
|
|
$cmd 323 deny tcp from any to any 81 in via $pif
|
|
|
|
# Deny any late arriving packets
|
|
$cmd 330 deny all from any to any frag in via $pif
|
|
|
|
# Deny ACK packets that did not match the dynamic rule table
|
|
$cmd 332 deny tcp from any to any established in via $pif
|
|
|
|
# Allow traffic in from ISP's DHCP server. This rule must contain
|
|
# the IP address of your ISP's DHCP server as it's the only
|
|
# authorized source to send this packet type.
|
|
# Only necessary for cable or DSL configurations.
|
|
# This rule is not needed for 'user ppp' type connection to
|
|
# the public Internet. This is the same IP address you captured
|
|
# and used in the outbound section.
|
|
$cmd 360 allow udp from x.x.x.x to any 68 in via $pif keep-state
|
|
|
|
# Allow in standard www function because I have Apache server
|
|
$cmd 370 allow tcp from any to me 80 in via $pif setup limit src-addr 2
|
|
|
|
# Allow in secure FTP, Telnet, and SCP from public Internet
|
|
$cmd 380 allow tcp from any to me 22 in via $pif setup limit src-addr 2
|
|
|
|
# Allow in non-secure Telnet session from public Internet
|
|
# labeled non-secure because ID & PW are passed over public
|
|
# Internet as clear text.
|
|
# Delete this sample group if you do not have telnet server enabled.
|
|
$cmd 390 allow tcp from any to me 23 in via $pif setup limit src-addr 2
|
|
|
|
# Reject & Log all unauthorized incoming connections from the public Internet
|
|
$cmd 400 deny log all from any to any in via $pif
|
|
|
|
# Reject & Log all unauthorized out going connections to the public Internet
|
|
$cmd 450 deny log all from any to any out via $pif
|
|
|
|
# This is skipto location for outbound stateful rules
|
|
$cmd 800 divert natd ip from any to any out via $pif
|
|
$cmd 801 allow ip from any to any
|
|
|
|
# Everything else is denied by default
|
|
# deny and log all packets that fell through to see what they are
|
|
$cmd 999 deny log all from any to any
|
|
################ End of IPFW rules file ###############################</programlisting>
|
|
</sect3>
|
|
</sect2>
|
|
</sect1>
|
|
</chapter>
|