Section on IPFW NAT now reads better.

Unfortunately, it is outdated as of 7.x.
Will need to review EXAMPLES in ipfw(8) and address PR121952.
Will hold off rest of commits to this chapter until someone gets
a chance to do so.

Sponsored by: iXsystems
This commit is contained in:
Dru Lavigne 2014-03-04 20:10:55 +00:00
parent ce8e9956a4
commit 3b05ed577e
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/head/; revision=44120

View file

@ -2163,12 +2163,12 @@ pif="dc0" # interface name of NIC attached to Internet</programlisting>
<para>To do this, the &os; machine connected to the Internet
must act as a gateway. This system must have two
<acronym>NIC</acronym>s, where one is connected to the Internet
and the other is connected to the internal <acronym>LAN</acronym>. All the
machines connected to the <acronym>LAN</acronym> should be assigned
an <acronym>IP</acronym> addresses in the private network space,
and the other is connected to the internal <acronym>LAN</acronym>. Each
machine connected to the <acronym>LAN</acronym> should be assigned
an <acronym>IP</acronym> address in the private network space,
as defined by <link
xlink:href="ftp://ftp.isi.edu/in-notes/rfc1918.txt">RFC
1918</link>, and have their default gateway set to the
1918</link>, and have the default gateway set to the
&man.natd.8; system's internal <acronym>IP</acronym>
address.</para>
@ -2177,7 +2177,7 @@ pif="dc0" # interface name of NIC attached to Internet</programlisting>
<application>IPFW</application>. If the system has a custom
kernel, the kernel configuration file needs to include
<literal>option IPDIVERT</literal> along with the other
<literal>IPFIREWALL</literal> options.</para>
<literal>IPFIREWALL</literal> options described in <xref linkend="firewalls-ipfw-enable"/>.</para>
<para>To enable <acronym>NAT</acronym> support at
boot time, the following must be in
@ -2224,127 +2224,100 @@ redirect_port tcp 192.168.0.3:80 80</programlisting>
used to reduce the number of rules:</para>
<programlisting>#!/bin/sh
ipfw -q -f flush
cmd="ipfw -q add"
skip="skipto 500"
pif=rl0
pif=dc0
ks="keep-state"
good_tcpo="22,25,37,43,53,80,443,110,119"
good_tcpo="22,25,37,53,80,443,110"</programlisting>
ipfw -q -f flush</programlisting>
<para>The <acronym>NAT</acronym> rule is inserted
<para>The inbound <acronym>NAT</acronym> rule is inserted
<emphasis>after</emphasis> the two rules which allow all
traffic on the trusted internal interface and on the loopback
interface and <emphasis>before</emphasis> the
<literal>check-state</literal> rule. It is important that the
rule number selected for the <acronym>NAT</acronym> rule, in
rule number selected for this <acronym>NAT</acronym> rule, in
this example <literal>100</literal>, is higher than the first
two rules and lower than the <literal>check-state</literal>
rule:</para>
<programlisting>&dollar;cmd 005 allow all from any to any via xl0 # exclude LAN traffic
&dollar;cmd 010 allow all from any to any via lo0 # exclude loopback traffic
# NAT any inbound packets
&dollar;cmd 100 divert natd ip from any to any in via &dollar;pif
&dollar;cmd 100 divert natd ip from any to any in via &dollar;pif # NAT any inbound packets
# Allow the packet through if it has an existing entry in the dynamic rules table
&dollar;cmd 101 check-state</programlisting>
<para>The processing flow starts with the first rule from the
top of the ruleset and progresses one rule at a time until
the end is reached or the packet matches and the packet is
released out of the firewall. Take note of the location of
rule numbers 100 101, 450, 500, and 510. These rules
control the translation of the outbound and inbound packets
so that their entries in the dynamic keep-state table always
register the private LAN IP address. All the allow and deny
rules specify the direction of the packet and the interface.
All start outbound session requests will
<literal>skipto rule 500</literal> to undergo NAT.</para>
<para>The outbound rules are modified to replace the
<literal>allow</literal> action with the
<literal>&dollar;skip</literal> variable, indicating that rule
processing will continue at rule <literal>500</literal>. The
seven <literal>tcp</literal> rules have been replaced by rule
<literal>125</literal> as the
<literal>&dollar;good_tcpo</literal> variable contains the
seven allowed outbound ports.</para>
<para>Consider a web browser which initializes a new HTTP
session over port 80. When the first outbound 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, and it has not been posted to the
dynamic keep-state table yet. The packet finally matches
rule 125 as it is outbound through the NIC facing the
Internet and has a source IP address as a private LAN IP
address. On matching this rule, two actions take place.
<literal>keep-state</literal> adds this rule to the dynamic
keep-state rules table and the specified action is executed
and posted as part of the info in the dynamic table. In
this case, the action is <literal>skipto rule 500</literal>.
Rule 500 <acronym>NAT</acronym>s the packet IP address and
sends it out to the Internet. This packet makes its way to
the destination web server, where a response packet is
generated and sent back. This new packet enters the top of
the ruleset. It matches rule 100 and has it destination IP
address mapped back to the corresponding LAN IP address. It
then is processed by the <literal>check-state</literal>
rule, is found in the table as an existing session, and is
released to the LAN. It goes to the LAN system that sent it
and a new packet is sent requesting another segment of the
data from the remote server. This time it matches the
<literal>check-state</literal> rule, its outbound entry is
found, and the associated action,
<literal>skipto 500</literal>, is executed. The packet
jumps to rule 500, gets <acronym>NAT</acronym>ed, and is
released to the Internet.</para>
<para>On the inbound side, everything coming in that is part of
an existing session is automatically handled by the
<literal>check-state</literal> rule and the properly placed
<literal>divert natd</literal> rules. The ruleset only has
to deny bad packets and allow only authorized services.
Consider a web server running on the firewall where web
requests from the Internet should have access to the local
web site. An inbound start request packet will match rule
100 and its IP address will be mapped to the LAN IP address
of the firewall. The packet is then matched against all the
nasty things that need to be checked and finally matches
rule 425 where two actions occur. The packet rule is posted
to the dynamic keep-state table but this time, any new
session requests originating from that source IP address are
limited to 2. This defends against DoS attacks against the
service running on the specified port number. The action is
<literal>allow</literal>, so the packet is released to the
LAN. The packet generated as a response is recognized by the
<literal>check-state</literal> as belonging to an existing
session. It is then sent to rule 500 for
<acronym>NAT</acronym>ing and released to the outbound
interface.</para>
<programlisting># Authorized outbound packets
&dollar;cmd 120 &dollar;skip udp from any to xx.168.240.2 53 out via &dollar;pif &dollar;ks
&dollar;cmd 121 &dollar;skip udp from any to xx.168.240.5 53 out via &dollar;pif &dollar;ks
<programlisting># Authorized outbound packets
&dollar;cmd 120 &dollar;skip udp from any to x.x.x.x 53 out via &dollar;pif &dollar;ks
&dollar;cmd 121 &dollar;skip udp from any to x.x.x.x 67 out via &dollar;pif &dollar;ks
&dollar;cmd 125 &dollar;skip tcp from any to any &dollar;good_tcpo out via &dollar;pif setup &dollar;ks
&dollar;cmd 130 &dollar;skip icmp from any to any out via &dollar;pif &dollar;ks
&dollar;cmd 135 &dollar;skip udp from any to any 123 out via &dollar;pif &dollar;ks
&dollar;cmd 130 &dollar;skip icmp from any to any out via &dollar;pif &dollar;ks</programlisting>
<para>The inbound rules remain the same, except for the very
last rule which removes the <literal> via $pif</literal> in
order to catch both inbound and outbound rules. The
<acronym>NAT</acronym> rule must follow this last outbound
rule, must have a higher number than that last rule, and the
rule number must be referenced by the
<literal>skipto</literal> action. In this ruleset,
rule number <literal>500</literal> diverts all
packets which match the outbound rules to &man.natd.8; for
<acronym>NAT</acronym> processing. The next rule allows any
packet which has undergone <acronym>NAT</acronym> processing
to pass.</para>
# Deny all inbound traffic from non-routable reserved address spaces
&dollar;cmd 300 deny all from 192.168.0.0/16 to any in via &dollar;pif #RFC 1918 private IP
&dollar;cmd 301 deny all from 172.16.0.0/12 to any in via &dollar;pif #RFC 1918 private IP
&dollar;cmd 302 deny all from 10.0.0.0/8 to any in via &dollar;pif #RFC 1918 private IP
&dollar;cmd 303 deny all from 127.0.0.0/8 to any in via &dollar;pif #loopback
&dollar;cmd 304 deny all from 0.0.0.0/8 to any in via &dollar;pif #loopback
&dollar;cmd 305 deny all from 169.254.0.0/16 to any in via &dollar;pif #DHCP auto-config
&dollar;cmd 306 deny all from 192.0.2.0/24 to any in via &dollar;pif #reserved for docs
&dollar;cmd 307 deny all from 204.152.64.0/23 to any in via &dollar;pif #Sun cluster
&dollar;cmd 308 deny all from 224.0.0.0/3 to any in via &dollar;pif #Class D &amp; E multicast
# Authorized inbound packets
&dollar;cmd 400 allow udp from xx.70.207.54 to any 68 in &dollar;ks
&dollar;cmd 420 allow tcp from any to me 80 in via &dollar;pif setup limit src-addr 1
&dollar;cmd 450 deny log ip from any to any
# This is skipto location for outbound stateful rules
&dollar;cmd 500 divert natd ip from any to any out via &dollar;pif
<programlisting>&dollar;cmd 499 deny log all from any to any
&dollar;cmd 500 divert natd ip from any to any out via &dollar;pif # skipto location for outbound stateful rules
&dollar;cmd 510 allow ip from any to any</programlisting>
<para>In this example, rules <literal>100</literal>,
<literal>101</literal>, <literal>125</literal>,
<literal>500</literal>, and <literal>510</literal>
control the address translation of the outbound and inbound packets
so that the entries in the dynamic state table always
register the private <acronym>LAN</acronym>
<acronym>IP</acronym> address.</para>
<para>Consider an internal web browser which initializes a new outbound <acronym>HTTP</acronym>
session over port 80. When the first outbound packet enters
the firewall, it does not match rule <literal>100</literal> because it is
headed out rather than in. It passes rule <literal>101</literal> because this
is the first packet and it has not been posted to the
dynamic state table yet. The packet finally matches
rule <literal>125</literal> as it is outbound on an allowed port
and has a source <acronym>IP</acronym> address from the internal <acronym>LAN</acronym>.
On matching this rule, two actions take place.
First, the <literal>keep-state</literal> action adds an entry to the dynamic
state table and the specified action, <literal>skipto rule 500</literal>, is executed.
Next, the packet undergoes <acronym>NAT</acronym> and
is sent out to the Internet. This packet makes its way to
the destination web server, where a response packet is
generated and sent back. This new packet enters the top of
the ruleset. It matches rule <literal>100</literal> and has it destination <acronym>IP</acronym>
address mapped back to the original internal address. It
then is processed by the <literal>check-state</literal>
rule, is found in the table as an existing session, and is
released to the <acronym>LAN</acronym>.</para>
<para>On the inbound side, the ruleset has
to deny bad packets and allow only authorized services.
A packet which matches an inbound rule
is posted
to the dynamic state table and the packet is released to the
<acronym>LAN</acronym>. The packet generated as a response is recognized by the
<literal>check-state</literal> rule as belonging to an existing
session. It is then sent to rule <literal>500</literal> to undergo
<acronym>NAT</acronym> before being released to the outbound
interface.</para>
<sect3>
<title>Port Redirection</title>