aboutsummaryrefslogtreecommitdiff
path: root/en_US.ISO8859-1/books/handbook/firewalls
diff options
context:
space:
mode:
authorDru Lavigne <dru@FreeBSD.org>2014-02-19 20:02:33 +0000
committerDru Lavigne <dru@FreeBSD.org>2014-02-19 20:02:33 +0000
commit5cfc0defb04364156be97361a3e92b0e432aae4b (patch)
treeb97bc9c49505a4419fcffe148e4aeb3b6b7fdc94 /en_US.ISO8859-1/books/handbook/firewalls
parenta4bb242dc78addea74593475949ad397cf1f1b78 (diff)
downloaddoc-5cfc0defb04364156be97361a3e92b0e432aae4b.tar.gz
doc-5cfc0defb04364156be97361a3e92b0e432aae4b.zip
Initial shuffle to improve the flow of this chapter.
Much, much more to come. Sponsored by: iXsystems
Notes
Notes: svn path=/head/; revision=43995
Diffstat (limited to 'en_US.ISO8859-1/books/handbook/firewalls')
-rw-r--r--en_US.ISO8859-1/books/handbook/firewalls/chapter.xml893
1 files changed, 441 insertions, 452 deletions
diff --git a/en_US.ISO8859-1/books/handbook/firewalls/chapter.xml b/en_US.ISO8859-1/books/handbook/firewalls/chapter.xml
index 4db2e8d29b..c9c8e1ad0e 100644
--- a/en_US.ISO8859-1/books/handbook/firewalls/chapter.xml
+++ b/en_US.ISO8859-1/books/handbook/firewalls/chapter.xml
@@ -1499,33 +1499,36 @@ block drop out quick on $ext_if from any to $martians</programlisting>
</sect1>
<sect1 xml:id="firewalls-ipf">
- <title>The IPFILTER (IPF) Firewall</title>
+ <title>IPFILTER (IPF)</title>
<indexterm>
<primary>firewall</primary>
- <secondary>IPFILTER</secondary>
+ <secondary><application>IPFILTER</application></secondary>
</indexterm>
- <para>IPFILTER is a cross-platform, open source firewall which
- has been ported to &os;, NetBSD, OpenBSD, &sunos;, HP/UX, and
+ <para><application>IPFILTER</application>, also known as
+ <application>IPF</application>, is a cross-platform, open source firewall which
+ has been ported to &os;, NetBSD, OpenBSD, and
&solaris; operating systems.</para>
- <para>IPFILTER is based on a kernel-side firewall and
+ <para><application>IPFILTER</application> is 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 using &man.ipf.8;. The
+ monitored by userland programs. Firewall rules
+ can be set or deleted using <application>ipf</application>,
<acronym>NAT</acronym> rules can be set or deleted using
- &man.ipnat.8;. Run-time statistics for the kernel parts of
- IPFILTER can be printed using &man.ipfstat.8;. To log IPFILTER
- actions to the system log files, use &man.ipmon.8;.</para>
+ <application>ipnat</application>, run-time statistics for the kernel parts of
+ <application>IPFILTER</application> can be printed using
+ <application>ipfstat</application>, and
+ <application>ipmon</application> can be used to log <application>IPFILTER</application>
+ actions to the system log files.</para>
- <para>IPF was originally written using a rule processing logic
+ <para><application>IPF</application> was originally written using a rule processing logic
of <quote>the last matching rule wins</quote> and only used
- stateless rules. Over time, IPF has been enhanced to include a
+ stateless rules. Over time, <application>IPF</application> has been enhanced to include a
<quote>quick</quote> option and a stateful
<quote>keep state</quote> option which modernized the rules
- processing logic. IPF's official documentation covers only the
+ processing logic. <application>IPF</application>'s official documentation covers only the
legacy rule coding parameters and rule file processing logic and
the modernized functions are only included as additional
options.</para>
@@ -1541,7 +1544,7 @@ block drop out quick on $ext_if from any to $martians</programlisting>
and <uri
xlink:href="http://coombs.anu.edu.au/~avalon/ip-filter.html">http://coombs.anu.edu.au/~avalon/ip-filter.html</uri>.</para>
- <para>The IPF FAQ is at <uri
+ <para>The <application>IPF</application> FAQ is at <uri
xlink:href="http://www.phildev.net/ipf/index.html">http://www.phildev.net/ipf/index.html</uri>.</para>
<para>A searchable archive of the IPFilter mailing list is
@@ -1549,32 +1552,22 @@ block drop out quick on $ext_if from any to $martians</programlisting>
xlink:href="http://marc.theaimsgroup.com/?l=ipfilter">http://marc.theaimsgroup.com/?l=ipfilter</uri>.</para>
<sect2>
- <title>Enabling IPF</title>
+ <title>Enabling <application>IPF</application></title>
<indexterm>
- <primary>IPFILTER</primary>
+ <primary><application>IPFILTER</application></primary>
<secondary>enabling</secondary>
</indexterm>
- <para>IPF is included in the basic &os; install as a kernel
- loadable module. The system will dynamically load
- this module at boot time when
- <varname>ipfilter_enable="YES"</varname> is added to
- <filename>rc.conf</filename>. The module enables logging and
- <literal>default pass all</literal>. To change the
- default to <literal>block all</literal>, add a
- <literal>block all</literal> rule at the end of the
- ruleset.</para>
- </sect2>
-
- <sect2>
- <title>Kernel Options</title>
+ <para> is included in the basic &os; install as a kernel
+ loadable module, meaning that a custom kernel is not needed in
+ order to enable <application>IPF</application>.</para>
<indexterm>
<primary>kernel options</primary>
- <secondary>IPFILTER</secondary>
+ <secondary><application>IPFILTER</application></secondary>
</indexterm>
<indexterm>
@@ -1590,22 +1583,22 @@ block drop out quick on $ext_if from any to $martians</programlisting>
</indexterm>
<indexterm>
- <primary>IPFILTER</primary>
+ <primary><application>IPFILTER</application></primary>
<secondary>kernel options</secondary>
</indexterm>
- <para>For users who prefer to statically compile IPF support
- into a custom kernel, the following IPF option statements,
- listed in <filename>/usr/src/sys/conf/NOTES</filename>, are
+ <para>For users who prefer to statically compile <application>IPF</application> support
+ into a custom kernel, refer to the instructions in <xref
+ linkend="kernelconfig"/>. The following <application>IPF</application> option statements are
available:</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>where <literal>options IPFILTER</literal> enables support for
+ <application>IPFILTER</application>.</para>
<para><literal>options IPFILTER_LOG</literal> enables IPF
logging using the <filename>ipl</filename> packet logging
@@ -1616,15 +1609,14 @@ options IPFILTER_DEFAULT_BLOCK</programlisting>
the default behavior so that 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>
+ <para>To configure the system to enable <application>IPF</application>
+ at boot time, add
+ the following entries to
+ <filename>/etc/rc.conf</filename>. These entries will also enable logging and
+ <literal>default pass all</literal>. To change the
+ default to <literal>block all</literal>, add a
+ <literal>block all</literal> rule at the end of the
+ ruleset.</para>
<programlisting>ipfilter_enable="YES" # Start ipf firewall
ipfilter_rules="/etc/ipf.rules" # loads rules definition text file
@@ -1634,20 +1626,50 @@ ipmon_flags="-Ds" # D = start as daemon
# v = log tcp window, ack, seq
# n = map IP &amp; port to names</programlisting>
- <para>If there is a LAN behind the firewall that uses the
- reserved private IP address ranges, the following lines have
- to be added to enable <acronym>NAT</acronym>
- functionality:</para>
+ <para>If <acronym>NAT</acronym>
+ functionality is needed, also add these lines:</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>
+
+ <para>To start <application>IPF</application> now:</para>
+
+ <programlisting>&prompt.root; <command>service ipfilter start</command></programlisting>
+
</sect2>
<sect2>
- <title>IPF</title>
+ <title>IPF Rulesets</title>
+
+ <para>A ruleset contains a group of IPF rules which 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 is predefined by its
+ protocol and listening port. Packets destined for a specific
+ service originate from the source address using an
+ unprivileged port and target the specific service port on the
+ destination address. All the above parameters can be used as
+ selection criteria to create rules which will pass or block
+ services.</para>
- <indexterm><primary><command>ipf</command></primary></indexterm>
+ <indexterm>
+ <primary><application>IPFILTER</application></primary>
+
+ <secondary>rule processing order</secondary>
+ </indexterm>
+
+ <warning>
+ <para>When working with the firewall rules, be <emphasis>very
+ careful</emphasis>. Some configurations <emphasis>can
+ lock the administrator out</emphasis> of the server. To be
+ on the safe side, consider performing the initial firewall
+ configuration from the local console rather than doing it
+ remotely over <application>ssh</application>.</para>
+ </warning>
<para>To load the ruleset file, use &man.ipf.8;. Custom rules
are normally placed in a file, and the following command can
@@ -1678,411 +1700,14 @@ ipnat_rules="/etc/ipnat.rules" # rules definition file for ipnat</programlist
<para>There is a way to build IPF rules that utilize 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
- by applying the 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>Refer to &man.ipfstat.8; for details.</para>
-
- <para>The default &man.ipfstat.8; 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 numbers.</para>
-
- <para><command>ipfstat -on</command> displays the outbound
- internal rules table with rule numbers.</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 options of
- <command>ipfstat</command> is <option>-t</option> which
- displays the state table in a way similar to how &man.top.1;
- shows the &os; running process table. When a firewall is
- under attack, this function provides the ability to identify
- and see the attacking packets. The optional sub-flags give
- the ability to select the destination or source IP, port, or
- protocol to be monitored in real time. Refer to
- &man.ipfstat.8; 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. Native mode
- is the default mode when the command is used without
- <option>-D</option>.</para>
-
- <para>Daemon mode provides a continuous system log file so that
- logging of past events may be reviewed. &os; has a built in
- facility to automatically rotate system logs. This is why
- outputting the log information to &man.syslogd.8; is better
- than the default of outputting to a regular file. The default
- <filename>rc.conf</filename>
- <literal>ipmon_flags</literal> statement uses
- <option>-Ds</option>:</para>
-
- <programlisting>ipmon_flags="-Ds" # D = start as daemon
- # s = log to syslog
- # v = log tcp window, ack, seq
- # n = map IP &amp; port to names</programlisting>
-
- <para>Logging provides the ability to review, after the fact,
- information such as which packets were 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 by default. The firewall
- administrator decides which rules in the ruleset should be
- logged and adds the log keyword to those rules. Normally,
- only deny rules are logged.</para>
-
- <para>It is customary to include a <quote>default deny
- everything</quote> rule with the log keyword included as the
- 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>&man.syslogd.8; uses its own method for segregation of log
- data. It uses groupings called <quote>facility</quote> and
- <quote>level</quote>. By default, IPMON in
- <option>-Ds</option> mode uses <literal>local0</literal> as
- the <quote>facility</quote> name. The following levels can be
- used to further segregate the logged data:</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>In order to setup IPFILTER to log all data to
- <filename>/var/log/ipfilter.log</filename>, first
- create the empty file:</para>
-
- <screen>&prompt.root; <userinput>touch /var/log/ipfilter.log</userinput></screen>
-
- <para>&man.syslogd.8; 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>To write all logged messages to the specified file,
- add the following statement to
- <filename>/etc/syslog.conf</filename>:</para>
-
- <programlisting>local0.* /var/log/ipfilter.log</programlisting>
-
- <para>To activate the changes and instruct &man.syslogd.8;
- to read the modified <filename>/etc/syslog.conf</filename>,
- run <command>service syslogd reload</command>.</para>
-
- <para>Do not forget to change
- <filename>/etc/newsyslog.conf</filename> to rotate the new
- log file.</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.</para>
- </listitem>
-
- <listitem>
- <para>The name of the interface that processed the
- packet.</para>
- </listitem>
-
- <listitem>
- <para>The group and rule number of the rule in the format
- <literal>@0:17</literal>.</para>
- </listitem>
- </orderedlist>
-
- <para>These can be viewed with
- <command>ipfstat -in</command>.</para>
-
- <orderedlist>
- <listitem>
- <para>The action: <literal>p</literal> for passed,
- <literal>b</literal> for blocked, <literal>S</literal> for
- a short packet, <literal>n</literal> did not match any
- rules, and <literal>L</literal> for a log rule. The order
- of precedence in showing flags is: <literal>S</literal>,
- <literal>p</literal>, <literal>b</literal>,
- <literal>n</literal>, <literal>L</literal>. A capital
- <literal>P</literal> or <literal>B</literal> means that
- the packet has been logged due to a global logging
- setting, not a particular rule.</para>
- </listitem>
-
- <listitem>
- <para>The addresses written as three fields: the source
- address and port separated by a comma, the -&gt; symbol,
- and the destination address and port. For example:
- <literal>209.53.17.22,80 -&gt;
- 198.73.220.17,1722</literal>.</para>
- </listitem>
-
- <listitem>
- <para><literal>PR</literal> followed by the protocol name
- or number: for example, <literal>PR tcp</literal>.</para>
- </listitem>
-
- <listitem>
- <para><literal>len</literal> followed by the header length
- and total length of the packet: for example,
- <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. Refer to
- &man.ipf.5; 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. For example: ICMP 3/3 for a port
- unreachable message.</para>
- </sect2>
-
- <sect2 xml: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
- <literal>&dollar;</literal>.</para>
-
- <para>Symbolic fields do not have the &dollar; prefix.</para>
-
- <para>The value to populate the symbolic field must be enclosed
- between double quotes (<literal>"</literal>).</para>
-
- <para>Start the 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 &gt; /etc/ipf.rules &lt;&lt; EOF
-#
-# 2) This can be used to run script "as is":
-/sbin/ipf -Fa -f - &lt;&lt; EOF
-
-# Allow out access to my ISP's Domain name server.
-pass out quick on &dollar;oif proto tcp from any to &dollar;odns port = 53 &dollar;fks
-pass out quick on &dollar;oif proto udp from any to &dollar;odns port = 53 &dollar;ks
-
-# Allow out non-secure standard www function
-pass out quick on &dollar;oif proto tcp from &dollar;myip to any port = 80 &dollar;fks
-
-# Allow out secure www function https over TLS SSL
-pass out quick on &dollar;oif proto tcp from &dollar;myip to any port = 443 &dollar;fks
-EOF
-################## End of IPF rules script ########################</programlisting>
-
- <para>The rules are not important in this example as it instead
- focuses on how the symbolic substitution fields are populated.
- If this example was in a file named
- <filename>/etc/ipf.rules.script</filename>, these rules could
- be reloaded by running:</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>, and run the script
- once after each modification to create or update
- <filename>/etc/ipf.rules</filename>.</para>
- </listitem>
-
- <listitem>
- <para>Disable IPFILTER in the system startup scripts by
- adding <literal>ipfilter_enable="NO"</literal>to
- <filename>/etc/rc.conf</filename>.</para>
-
- <para>Then, add a script like the following to
- <filename>/usr/local/etc/rc.d/</filename>. The script
- should have an obvious name like
- <filename>ipf.loadrules.sh</filename>, where 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
- <systemitem class="username">root</systemitem>:</para>
-
- <screen>&prompt.root; <userinput>chmod 700 /usr/local/etc/rc.d/ipf.loadrules.sh</userinput></screen>
- </listitem>
- </itemizedlist>
-
- <para>Now, when the system boots, the IPF rules will be
- loaded.</para>
- </sect2>
-
- <sect2>
- <title>IPF Rulesets</title>
-
- <para>A ruleset contains a group of IPF rules which 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 is predefined by its
- protocol and listening port. Packets destined for a specific
- service originate from the source address using an
- unprivileged port and target the specific service port on the
- destination address. All the above parameters 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>
-
- <warning>
- <para>When working with the firewall rules, be <emphasis>very
- careful</emphasis>. Some configurations <emphasis>can
- lock the administrator out</emphasis> of the server. To be
- on the safe side, consider performing the initial firewall
- configuration from the local console rather than doing it
- remotely over <application>ssh</application>.</para>
- </warning>
+ <xref linkend="firewalls-ipf-rules-script"/>.</para>
</sect2>
<sect2>
<title>Rule Syntax</title>
<indexterm>
- <primary>IPFILTER</primary>
+ <primary><application>IPFILTER</application></primary>
<secondary>rule syntax</secondary>
</indexterm>
@@ -2323,7 +1948,7 @@ sh /etc/ipf.rules.script</programlisting>
<title>Stateful Filtering</title>
<indexterm>
- <primary>IPFILTER</primary>
+ <primary><application>IPFILTER</application></primary>
<secondary>stateful filtering</secondary>
</indexterm>
@@ -2646,6 +2271,116 @@ block in log first quick on dc0 all
################### End of rules file #####################################</programlisting>
</sect2>
+ <sect2 xml: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
+ <literal>&dollar;</literal>.</para>
+
+ <para>Symbolic fields do not have the &dollar; prefix.</para>
+
+ <para>The value to populate the symbolic field must be enclosed
+ between double quotes (<literal>"</literal>).</para>
+
+ <para>Start the 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 &gt; /etc/ipf.rules &lt;&lt; EOF
+#
+# 2) This can be used to run script "as is":
+/sbin/ipf -Fa -f - &lt;&lt; EOF
+
+# Allow out access to my ISP's Domain name server.
+pass out quick on &dollar;oif proto tcp from any to &dollar;odns port = 53 &dollar;fks
+pass out quick on &dollar;oif proto udp from any to &dollar;odns port = 53 &dollar;ks
+
+# Allow out non-secure standard www function
+pass out quick on &dollar;oif proto tcp from &dollar;myip to any port = 80 &dollar;fks
+
+# Allow out secure www function https over TLS SSL
+pass out quick on &dollar;oif proto tcp from &dollar;myip to any port = 443 &dollar;fks
+EOF
+################## End of IPF rules script ########################</programlisting>
+
+ <para>The rules are not important in this example as it instead
+ focuses on how the symbolic substitution fields are populated.
+ If this example was in a file named
+ <filename>/etc/ipf.rules.script</filename>, these rules could
+ be reloaded by running:</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>, and run the script
+ once after each modification to create or update
+ <filename>/etc/ipf.rules</filename>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Disable <application>IPFILTER</application> in the system startup scripts by
+ adding <literal>ipfilter_enable="NO"</literal>to
+ <filename>/etc/rc.conf</filename>.</para>
+
+ <para>Then, add a script like the following to
+ <filename>/usr/local/etc/rc.d/</filename>. The script
+ should have an obvious name like
+ <filename>ipf.loadrules.sh</filename>, where 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
+ <systemitem class="username">root</systemitem>:</para>
+
+ <screen>&prompt.root; <userinput>chmod 700 /usr/local/etc/rc.d/ipf.loadrules.sh</userinput></screen>
+ </listitem>
+ </itemizedlist>
+
+ <para>Now, when the system boots, the IPF rules will be
+ loaded.</para>
+ </sect2>
+
<sect2>
<title><acronym>NAT</acronym></title>
@@ -2706,7 +2441,7 @@ block in log first quick on dc0 all
<indexterm>
<primary>NAT</primary>
- <secondary>and IPFILTER</secondary>
+ <secondary>and <application>IPFILTER</application></secondary>
</indexterm>
<indexterm><primary><command>ipnat</command></primary></indexterm>
@@ -2980,6 +2715,260 @@ pass out quick on rl0 proto tcp from any to any port &gt; 1024 flags S keep stat
pass in quick on rl0 proto tcp from any to any port = 20 flags S keep state</programlisting>
</sect3>
</sect2>
+
+ <sect2>
+ <title>IPFSTAT</title>
+
+ <indexterm><primary><command>ipfstat</command></primary></indexterm>
+
+ <indexterm>
+ <primary><application>IPFILTER</application></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
+ by applying the 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>Refer to &man.ipfstat.8; for details.</para>
+
+ <para>The default &man.ipfstat.8; 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 numbers.</para>
+
+ <para><command>ipfstat -on</command> displays the outbound
+ internal rules table with rule numbers.</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 options of
+ <command>ipfstat</command> is <option>-t</option> which
+ displays the state table in a way similar to how &man.top.1;
+ shows the &os; running process table. When a firewall is
+ under attack, this function provides the ability to identify
+ and see the attacking packets. The optional sub-flags give
+ the ability to select the destination or source IP, port, or
+ protocol to be monitored in real time. Refer to
+ &man.ipfstat.8; for details.</para>
+ </sect2>
+
+ <sect2>
+ <title>IPMON</title>
+
+ <indexterm><primary><command>ipmon</command></primary></indexterm>
+
+ <indexterm>
+ <primary><application>IPFILTER</application></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. Native mode
+ is the default mode when the command is used without
+ <option>-D</option>.</para>
+
+ <para>Daemon mode provides a continuous system log file so that
+ logging of past events may be reviewed. &os; has a built in
+ facility to automatically rotate system logs. This is why
+ outputting the log information to &man.syslogd.8; is better
+ than the default of outputting to a regular file. The default
+ <filename>rc.conf</filename>
+ <literal>ipmon_flags</literal> statement uses
+ <option>-Ds</option>:</para>
+
+ <programlisting>ipmon_flags="-Ds" # D = start as daemon
+ # s = log to syslog
+ # v = log tcp window, ack, seq
+ # n = map IP &amp; port to names</programlisting>
+
+ <para>Logging provides the ability to review, after the fact,
+ information such as which packets were 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 by default. The firewall
+ administrator decides which rules in the ruleset should be
+ logged and adds the log keyword to those rules. Normally,
+ only deny rules are logged.</para>
+
+ <para>It is customary to include a <quote>default deny
+ everything</quote> rule with the log keyword included as the
+ 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>&man.syslogd.8; uses its own method for segregation of log
+ data. It uses groupings called <quote>facility</quote> and
+ <quote>level</quote>. By default, IPMON in
+ <option>-Ds</option> mode uses <literal>local0</literal> as
+ the <quote>facility</quote> name. The following levels can be
+ used to further segregate the logged data:</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>In order to setup <application>IPFILTER</application> to log all data to
+ <filename>/var/log/ipfilter.log</filename>, first
+ create the empty file:</para>
+
+ <screen>&prompt.root; <userinput>touch /var/log/ipfilter.log</userinput></screen>
+
+ <para>&man.syslogd.8; 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>To write all logged messages to the specified file,
+ add the following statement to
+ <filename>/etc/syslog.conf</filename>:</para>
+
+ <programlisting>local0.* /var/log/ipfilter.log</programlisting>
+
+ <para>To activate the changes and instruct &man.syslogd.8;
+ to read the modified <filename>/etc/syslog.conf</filename>,
+ run <command>service syslogd reload</command>.</para>
+
+ <para>Do not forget to change
+ <filename>/etc/newsyslog.conf</filename> to rotate the new
+ log file.</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.</para>
+ </listitem>
+
+ <listitem>
+ <para>The name of the interface that processed the
+ packet.</para>
+ </listitem>
+
+ <listitem>
+ <para>The group and rule number of the rule in the format
+ <literal>@0:17</literal>.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>These can be viewed with
+ <command>ipfstat -in</command>.</para>
+
+ <orderedlist>
+ <listitem>
+ <para>The action: <literal>p</literal> for passed,
+ <literal>b</literal> for blocked, <literal>S</literal> for
+ a short packet, <literal>n</literal> did not match any
+ rules, and <literal>L</literal> for a log rule. The order
+ of precedence in showing flags is: <literal>S</literal>,
+ <literal>p</literal>, <literal>b</literal>,
+ <literal>n</literal>, <literal>L</literal>. A capital
+ <literal>P</literal> or <literal>B</literal> means that
+ the packet has been logged due to a global logging
+ setting, not a particular rule.</para>
+ </listitem>
+
+ <listitem>
+ <para>The addresses written as three fields: the source
+ address and port separated by a comma, the -&gt; symbol,
+ and the destination address and port. For example:
+ <literal>209.53.17.22,80 -&gt;
+ 198.73.220.17,1722</literal>.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>PR</literal> followed by the protocol name
+ or number: for example, <literal>PR tcp</literal>.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>len</literal> followed by the header length
+ and total length of the packet: for example,
+ <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. Refer to
+ &man.ipf.5; 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. For example: ICMP 3/3 for a port
+ unreachable message.</para>
+ </sect2>
</sect1>
<sect1 xml:id="firewalls-ipfw">