3491 lines
137 KiB
XML
3491 lines
137 KiB
XML
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
<!--
|
|
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>service 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>service 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.8; 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.munk.me.uk/ipf/ipf-howto.html"></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
|
|
using <command>ipf -Z</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
|
|
<command>ipfstat</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>, 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 <filename>/etc/syslog.conf</filename>.
|
|
This 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>service 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) to <filename>/etc/rc.conf</filename>.</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,
|
|
<command>ipfstat -hio</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 is 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>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
|
|
<command>ipnat</command>. Typically the
|
|
<acronym>NAT</acronym> rules are stored in
|
|
<filename>/etc/ipnat.rules</filename>. See &man.ipnat.8; 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
|
|
<command>ipnat</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
|
|
<filename>/etc/rc.firewall</filename> 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 blocksall 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 <filename>/etc/sysctl.conf</filename>:</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, use <command>ipfw reset log</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 its 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>, which is
|
|
defined in <filename>/etc/syslog.conf</filename>.</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
|
|
<filename>/etc/ipfw.rules</filename>, 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>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
|
|
its 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 its 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. 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 anexisting 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 is 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>
|