mirror of https://github.com/tLDP/LDP
902 lines
42 KiB
XML
902 lines
42 KiB
XML
<!-- $Id$ -->
|
|
|
|
<chapter id="ch-nat">
|
|
<title>Network Address Translation (NAT)</title>
|
|
<para>
|
|
Network Address Translation (NAT) is a deceptively simple concept. NAT is
|
|
the technique of rewriting addresses on a packet as it passes through a
|
|
routing device. There are far reaching ramifications
|
|
on network design and protocol compatibility wherever NAT is used.
|
|
</para>
|
|
<para>
|
|
This chapter will introduce two types of NAT available under linux. One,
|
|
<link linkend="nat-stateless">full NAT or stateless NAT</link>, is
|
|
available under kernel 2.2 and kernel 2.4 via the
|
|
&iproute2; userspace interface. Available only under
|
|
kernel 2.4,
|
|
<link linkend="nat-dnat">destination NAT (DNAT)</link> is an important
|
|
derivative of full NAT. DNAT configuration from userspace is accomplished
|
|
via the <command>iptables</command> utility.
|
|
The experienced network administrator is probably puzzling about absent
|
|
references to source NAT (SNAT) and masquerading. These prominent and
|
|
prevalent uses of NAT are covered in
|
|
<xref linkend="ch-snat"/>, although many concepts involved in the special
|
|
purpose SNAT and masquerading will be introduced in this chapter.
|
|
</para>
|
|
<para>
|
|
Network address translation is known by a number of names in the
|
|
networking world: full NAT, one-to-one NAT and inbound NAT.
|
|
As used in this chapter and throughout this documentation,
|
|
<wordasword>NAT</wordasword>, when unqualified,
|
|
will refer to full network address translation or one-to-one NAT.
|
|
NAT techniques derived from full NAT, such as destination or source NAT,
|
|
will be described as DNAT
|
|
(<link linkend="nat-dnat">destination NAT</link>) and SNAT
|
|
(<link linkend="ch-snat">source NAT</link>).
|
|
</para>
|
|
<para>
|
|
Michael Hasenstein's seminal paper on network address translation
|
|
is available courtesy of SuSe Linux AG
|
|
<ulink url="http://www.suse.de/~mha/linux-ip-nat/diplom/nat.html">here</ulink>.
|
|
</para>
|
|
<section id="nat-overview">
|
|
<title>Rationale for and Introduction to NAT</title>
|
|
<para>
|
|
Network address translation (NAT) is a technique of transparently mapping
|
|
an IP address or range to another IP address or range. Any routing
|
|
device situated between two endpoints can perform this transformation of
|
|
the packet. Network designers must however take one key element under
|
|
consideration when laying out a network with NAT in mind. The router(s)
|
|
performing NAT must have an opportunity to rewrite the packet upon entry
|
|
to the network and upon exit from the network
|
|
<footnote>
|
|
<para>
|
|
If using
|
|
<link linkend="nat-stateless">stateless NAT</link>, the inbound and
|
|
outbound translations can occur on more than one device, provided
|
|
that all of the devices are performing the same translation.
|
|
</para>
|
|
</footnote>.
|
|
</para>
|
|
<para>
|
|
Because network address translation manipulates the addressing of a
|
|
packet, the NAT transformation becomes a passive but
|
|
critical part of the conversation between hosts exchanging packets.
|
|
NAT is by necessity transparent to the application layer endpoints
|
|
and operates on any type of IP packet. There are some application and
|
|
even network layer protocols which will break as a result of this
|
|
rewriting. Consult
|
|
<xref linkend="nat-break"/> for a discussion of these cases.
|
|
</para>
|
|
<para>
|
|
Here are a few common reasons to consider NAT along with potential
|
|
NAT solution candidates shown in parentheses.
|
|
</para>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
Publicly accessible services need to be provided on registered
|
|
Internet IPs which change or might change. NAT allows the
|
|
separation of internal IP addressing schemes from the public IP
|
|
space, easing the burden of changing internal addressing
|
|
or external IPs.
|
|
<emphasis>
|
|
(<link linkend="nat-stateless">NAT</link>,
|
|
<link linkend="nat-dnat">DNAT</link>,
|
|
<link linkend="nat-dnat-pat">PAT with DNAT</link>
|
|
<link linkend="nat-pat-userspace">PAT from userspace</link>)
|
|
</emphasis>
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
An application requires inbound and outbound connections.
|
|
In this case
|
|
<link linkend="ch-snat">SNAT/masquerading</link> will not suffice.
|
|
See also
|
|
<xref linkend="snat-break"/>.
|
|
<emphasis>
|
|
(<link linkend="nat-stateless">NAT</link>,
|
|
<link linkend="state-conntrack">SNAT and application-aware
|
|
connection tracking</link>)
|
|
</emphasis>
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
The network numbering scheme is changing. Clever use of NAT
|
|
allows reachability of services on both IP addresses or IP address
|
|
ranges during the network numbering migration.
|
|
<emphasis>
|
|
(<link linkend="nat-stateless">NAT</link>,
|
|
<link linkend="nat-dnat">DNAT</link>)
|
|
</emphasis>
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
Two networks share the same IP addressing space and need to
|
|
exchange packets. Using network address translation to publish
|
|
NAT network spaces with different numbering schemes would
|
|
allow each network to retain the addressing scheme while accessing
|
|
the other network.
|
|
<emphasis>
|
|
(<link linkend="nat-stateless">NAT</link>,
|
|
<link linkend="nat-dnat">DNAT</link>,
|
|
<link linkend="ch-snat">SNAT</link>)
|
|
</emphasis>
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<para>
|
|
These are the commonest reasons to consider and implement NAT. Other
|
|
niche applications of NAT, notably as part of load balancing systems,
|
|
exist although this chapter will concentrate on the use of NAT
|
|
to hide, isolate or renumber networks. It will also cover
|
|
inbound connections,
|
|
leaving the discussion of many-to-one NAT, SNAT and masquerading for
|
|
<xref linkend="ch-snat"/>.
|
|
</para>
|
|
<para>
|
|
One motivator for deploying NAT in a network is the benefit of
|
|
virtualizing the network. By isolating services provided in one network
|
|
from changes in other networks, the effects of such changes can be
|
|
minimized. The disadvantage of
|
|
virtualizing the network in this way is the increased reliance on the
|
|
NAT device.
|
|
</para>
|
|
<para>
|
|
Providing inbound services via NAT can be accomplished in several
|
|
different ways. Two common techniques are to use
|
|
&iproute2; NAT and netfilter DNAT.
|
|
Less common (and possibly less desirable) one can use port redirection
|
|
tools. Depending on which tool is employed,
|
|
different characteristics of a packet can trigger the address
|
|
transformation.
|
|
</para>
|
|
<para>
|
|
The simplest form of NAT under linux is
|
|
<link linkend="nat-stateless">&iproute2; NAT</link>.
|
|
This type of NAT requires two matching commands, one to cause the kernel
|
|
to rewrite the inbound packets (<userinput>ip route add nat $NATIP
|
|
via $REAL</userinput>)
|
|
and one to rewrite the outbound packets (<userinput>ip rule add from
|
|
$REAL nat $NATIP</userinput>). The router configured in this fashion will
|
|
retain no state for connections. It will simply transform any packets
|
|
passing through. By contrast, netfilter is capable of retaining state
|
|
on connections passing through the router and selecting packets more
|
|
granularly than is possible with only &iproute2; tools.
|
|
</para>
|
|
<para>
|
|
Before the advent of the netfilter engine in the linux kernel, there
|
|
were several tools available to administer NAT, DNAT and PAT.
|
|
These tools were not included in many distributions and weren't
|
|
adopted broadly in the community. Although you may find references to
|
|
<command>ipmasqadm</command>, <command>ipnatadm</command> and
|
|
<command>ipportfw</command> across the Internet in older documentation,
|
|
these tools have been superseded in functionality and widespread
|
|
deployment by the netfilter engine and its userspace partner,
|
|
<command>iptables</command>.
|
|
</para>
|
|
<para>
|
|
The netfilter engine provides a more flexible
|
|
language for selection of packets to be transformed than that provided
|
|
by the &iproute2; suite and kernel routing functionality.
|
|
Additionally, any
|
|
NAT services provided by the netfilter engine come with the labor-saving
|
|
and resource-consuming connection tracking mechanism.
|
|
<link linkend="nat-dnat">DNAT</link> translates the address on an
|
|
inbound packet and creates an entry in the connection tracking state
|
|
table. For even modest machines, the connection tracking resource
|
|
consumption should not be problematic.
|
|
</para>
|
|
<!-- FIXME; next paragraph needs to be rewritten -->
|
|
<para>
|
|
Netfilter DNAT allows the user to select packets based on
|
|
characteristics such as destination port. This blurs the distinction
|
|
between network address translation and port address translation.
|
|
NAT always transforms the layer 3 contents of a packet. Port
|
|
redirection operates at layer 4. From a practical perspective, there is
|
|
little difference between a port redirection and a netfilter DNAT which
|
|
has selected a single port. The manner in which the packet and contents
|
|
are retransmitted, however, is tremendously different.
|
|
</para>
|
|
<para>
|
|
One other less common technique for furnishing inbound services is
|
|
the use of
|
|
<link linkend="nat-pat-userspace">port redirection</link>. Although
|
|
there are higher layer tools which can perform transparent application
|
|
layer proxying (e.g.
|
|
<ulink url="http://www.squid-cache.org/">Squid</ulink>), these are
|
|
outside the scope of this documentation.
|
|
</para>
|
|
<para>
|
|
There are a number of IP addresses involved in any NAT transformations
|
|
or connection states. The following list identifies these names and the
|
|
convention used to describe each IP address. Beware that the prevalance
|
|
of NAT to publish services on the Internet via public IP addresses has
|
|
lead to the server/client lingo common in discussions of NAT.
|
|
</para>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>server NAT IP</term>
|
|
<term>NAT IP</term>
|
|
<listitem>
|
|
<para>
|
|
The IP address to which packets are addressed. This is the
|
|
address on the packet before the device performing NAT
|
|
manipulates it.
|
|
This is frequently also described as the public IP, although
|
|
any given application of NAT knows no distinction between public
|
|
and private address ranges.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>real IP</term>
|
|
<term>server IP</term>
|
|
<term>hidden IP</term>
|
|
<term>private IP</term>
|
|
<term>internal IP</term>
|
|
<listitem>
|
|
<para>
|
|
The IP address after the NAT device has performed its
|
|
transformation. Frequently, this is described as the private IP,
|
|
although any given application of NAT knows no distinction between
|
|
public and private address ranges.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>client IP</term>
|
|
<listitem>
|
|
<para>
|
|
The source address of the initial packet. The client IP in a NAT
|
|
transformation does not change; this IP is the source IP address
|
|
on any inbound packets both before and after the translation. It
|
|
is also the destination address on the outbound packet.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
The above terms will be used below and in general discussions of NAT.
|
|
</para>
|
|
</section>
|
|
<section id="nat-break">
|
|
<title>Application Layer Protocols with Embedded Network Information</title>
|
|
<para>
|
|
Network address translation is beautifully invisible when it works,
|
|
but has adverse effects on some protocols.
|
|
Some network applications, e.g., FTP, SNMP, H323, LDAP, IRC, make use of
|
|
embedded IP information in the application layer protocol or data
|
|
stream. Since the 2.0.x kernel
|
|
series (which is not covered here), linux has supported modules which
|
|
inspect and manipulate packet contents on particular types of packets
|
|
when used with NAT or masquerading.
|
|
</para>
|
|
<para>
|
|
FTP is the classic example. Within the FTP control channel
|
|
(usually established to destination port tcp/21) the client and the
|
|
server exchange IP address and port information. If the network address
|
|
translation device doesn't manipulate this data, the FTP server will not
|
|
be able to contact the client to provide the data.
|
|
</para>
|
|
<para>
|
|
Passive mode FTP provides the possibility for a network layer which
|
|
requires only outbound TCP connections. This results in a more NAT
|
|
friendly and firewall friendly protocol, because the connections are
|
|
initiated from the client.
|
|
</para>
|
|
<para>
|
|
Not only are there network applications which break when NAT is involved
|
|
but also network layer protocols. IPSec is a standards-based
|
|
network-layer security protocol commonly used in VPNs and IPv6 networks.
|
|
There are many different ways to use IPSec, but, when used in AH
|
|
(Authentication Header) mode, NAT will break IPSec functionality.
|
|
</para>
|
|
<para>
|
|
This underscores the importance of determining if NAT is the best
|
|
solution for the problem. There are kernel modules to help handle many
|
|
(though not all) of the application layer protocol when using NAT, but
|
|
some protocols, such as IPSec in AH mode simply cannot be used with NAT.
|
|
</para>
|
|
</section>
|
|
<section id="nat-stateless">
|
|
<title>Stateless NAT with &iproute2;</title>
|
|
<para>
|
|
Stateless NAT, occasionally maligned as dumb NAT
|
|
<footnote>
|
|
<para>
|
|
In the kernel code tree, stateless NAT, &iproute2; NAT can be
|
|
located in the file <filename>net/ipv4/ip_nat_dumb.c</filename>.
|
|
Even in the kernel, it has this reputation.
|
|
</para>
|
|
</footnote>,
|
|
is the simplest form of
|
|
NAT. It involves rewriting addresses passing through a
|
|
routing device:
|
|
inbound packets will undergo destination address rewriting and
|
|
outbound packets will undergo source address rewriting.
|
|
The &iproute2; suite of tools provides the two commands
|
|
required to configure the kernel to perform stateless NAT.
|
|
This section will cover only
|
|
stateless NAT, which can only be accomplished under linux with the
|
|
&iproute2; tools, although it can be
|
|
<link linkend="ex-nat-dnat-full">simulated with netfilter</link>.
|
|
</para>
|
|
<anchor id="nat-stateless-arp"/>
|
|
<para>
|
|
Creating an &iproute2; NAT mapping has the side
|
|
effect of causing the kernel to answer ARP requests for the NAT IP.
|
|
For more detail on ARP filtering, suppression and conditional ARP, see
|
|
<xref linkend="ch-ether"/>. This can be considered, alternatively, a
|
|
benefit or a misfeature of the kernel support for NAT.
|
|
The <constant>nat</constant> entry in the local routing table causes
|
|
the kernel to reply for ARP requests to the NAT IP.
|
|
Conversely,
|
|
<link linkend="nat-dnat">netfilter DNAT</link> makes no ARP entry or
|
|
provision for neighbor advertisement.
|
|
</para>
|
|
<para>
|
|
</para>
|
|
<para>
|
|
Whether or not it is using a packet filter, a linux machine can perform
|
|
NAT using the &iproute2; suite of tools. This chapter
|
|
will document the use of &iproute2; tools for NAT with
|
|
<link linkend="nat-stateless-simple">a simple example</link> and
|
|
<link linkend="nat-stateless-howto">an explanation of the required
|
|
commands</link>, then an example of
|
|
<link linkend="nat-stateless-rpdb">using NAT with the RPDB</link> and
|
|
<link linkend="nat-stateless-pf-interaction">using NAT with a packet
|
|
filter</link>.
|
|
</para>
|
|
<para>
|
|
NAT with iproute2 can be used in conjunction with the routing policy
|
|
database (cf. <link linkend="nat-stateless-rpdb">RPDB</link>) to support
|
|
conditional NAT, e.g. only perform NAT if the source IP falls within
|
|
a certain range. See <xref linkend="nat-stateless-rpdb"/>.
|
|
</para>
|
|
<section id="nat-stateless-simple">
|
|
<title>Stateless NAT Packet Capture and Introduction</title>
|
|
<para>
|
|
Assume that example company in
|
|
<link linkend="ax-example-network">example network</link> wants to
|
|
provide SMTP service on a public IP (205.254.211.0/24) but plans to
|
|
move to a different IP addressing space in the near future. Network
|
|
address translation can assist example company prepare for the move.
|
|
The administrator will select an IP on the internal network
|
|
(192.168.100.0/24) and configure the router to accept and translate
|
|
packets for the publicly reachable IP into the private IP.
|
|
</para>
|
|
<example id="ex-nat-basic">
|
|
<title>
|
|
Stateless NAT Packet Capture
|
|
<footnote>
|
|
<para>
|
|
If you are having some difficulty understanding the
|
|
output of <command>tcpdump</command>, please see the
|
|
section on <link linkend="tools-tcpdump">tcpdump</link>.
|
|
</para>
|
|
</footnote>
|
|
</title>
|
|
<programlisting>
|
|
<prompt>[root@masq-gw]# </prompt><userinput>tcpdump -qnn</userinput>
|
|
<computeroutput>19:30:17.824853 eth1 < 64.70.12.210.35131 > 205.254.211.17.25: tcp 0 (DF) <co id="ex-nb-public-in" linkends="ex-nb-public-in-text"/>
|
|
19:30:17.824976 eth0 > 64.70.12.210.35131 > 192.168.100.17.25: tcp 0 (DF) <co id="ex-nb-private-out" linkends="ex-nb-private-out-text"/>
|
|
19:30:17.825400 eth0 < 192.168.100.17.25 > 64.70.12.210.35131: tcp 0 (DF) <co id="ex-nb-private-in" linkends="ex-nb-private-in-text"/>
|
|
19:30:17.825568 eth1 > 205.254.211.17.25 > 64.70.12.210.35131: tcp 0 (DF) <co id="ex-nb-public-out" linkends="ex-nb-public-out-text"/></computeroutput>
|
|
</programlisting>
|
|
<calloutlist>
|
|
<callout
|
|
arearefs="ex-nb-public-in"
|
|
id="ex-nb-public-in-text">
|
|
<simpara>
|
|
The first packet comes in on eth1, &masq-gw;'s
|
|
outside interface. The packet is addressed to the NAT IP,
|
|
205.254.211.17 on tcp/25. This is the IP/port pair on which
|
|
which our service runs. This is a snapshot
|
|
of the packet before it has been handled by the NAT code.
|
|
</simpara>
|
|
</callout>
|
|
<callout
|
|
arearefs="ex-nb-private-out"
|
|
id="ex-nb-private-out-text">
|
|
<simpara>
|
|
The next line is the "same" packet leaving eth0, &masq-gw;'s
|
|
inside interface, bound for the internal network.
|
|
The NAT code has substituted the real IP of the server,
|
|
192.168.100.17. This rewriting is handled by the
|
|
<constant>nat</constant> entry in the
|
|
<constant>local</constant> routing table (<userinput>ip
|
|
route</userinput>). See also
|
|
<xref linkend="ex-nat-basic-commands"/>.
|
|
</simpara>
|
|
</callout>
|
|
<callout
|
|
arearefs="ex-nb-private-in"
|
|
id="ex-nb-private-in-text">
|
|
<simpara>
|
|
The SMTP server then sends a return packet which arrives on
|
|
eth0. This is the packet before the NAT code on &masq-gw;
|
|
has rewritten the outbound packet. This rewriting is handled
|
|
by the RPDB entry (<userinput>ip rule</userinput>). See also
|
|
<xref linkend="ex-nat-basic-commands"/>.
|
|
</simpara>
|
|
</callout>
|
|
<callout
|
|
arearefs="ex-nb-public-out"
|
|
id="ex-nb-public-out-text">
|
|
<simpara>
|
|
Finally, the return packet is transmitted on eth1 after having
|
|
been rewritten. The source IP address on the packet is now
|
|
the public IP on which the service is published.
|
|
</simpara>
|
|
</callout>
|
|
</calloutlist>
|
|
</example>
|
|
<para>
|
|
</para>
|
|
</section>
|
|
<section id="nat-stateless-howto">
|
|
<title>Stateless NAT Practicum</title>
|
|
<para>
|
|
There are only a few commands which are required to enable stateless
|
|
NAT on a linux routing device. The commands below will configure
|
|
the host &masq-gw; (see
|
|
<xref linkend="example-network-netmap"/> and
|
|
<xref linkend="example-network-addressing"/>) as shown above in
|
|
<xref linkend="ex-nat-basic"/>.
|
|
</para>
|
|
<example id="ex-nat-basic-commands">
|
|
<title>Basic commands to create a stateless NAT</title>
|
|
<programlisting>
|
|
<prompt>[root@masq-gw]# </prompt><userinput>ip route add nat 205.254.211.17 via 192.168.100.17</userinput> <co id="ex-nbc-routenat" linkends="ex-nbc-routenat-text"/>
|
|
<prompt>[root@masq-gw]# </prompt><userinput>ip rule add nat 205.254.211.17 from 192.168.100.17</userinput> <co id="ex-nbc-rulenat" linkends="ex-nbc-rulenat-text"/>
|
|
<prompt>[root@masq-gw]# </prompt><userinput>ip route flush cache</userinput> <co id="ex-nbc-flushcache" linkends="ex-nbc-flushcache-text"/>
|
|
<prompt>[root@masq-gw]# </prompt><userinput>ip route show table all | grep ^nat</userinput> <co id="ex-nbc-routeshow" linkends="ex-nbc-routeruleshow-text"/>
|
|
<computeroutput>nat 205.254.211.17 via 192.168.100.17 table local scope host</computeroutput>
|
|
<prompt>[root@masq-gw]# </prompt><userinput>ip rule show</userinput> <co id="ex-nbc-ruleshow" linkends="ex-nbc-routeruleshow-text"/>
|
|
<computeroutput>0: from all lookup local
|
|
32765: from 192.168.100.17 lookup main map-to 205.254.211.17
|
|
32766: from all lookup main
|
|
32767: from all lookup 253</computeroutput>
|
|
</programlisting>
|
|
<calloutlist>
|
|
<callout
|
|
arearefs="ex-nbc-routenat"
|
|
id="ex-nbc-routenat-text">
|
|
<simpara>
|
|
This command tells the kernel to perform network
|
|
address translation on any packet bound for
|
|
205.254.211.17. The parameter via tells the NAT code
|
|
to rewrite the packet bound for 205.254.211.17 with the
|
|
new destination address 192.168.100.17. Note, that this
|
|
only handles inbound packets; that is, packets whose
|
|
destination address contains 205.254.211.17.
|
|
</simpara>
|
|
</callout>
|
|
<callout
|
|
arearefs="ex-nbc-rulenat"
|
|
id="ex-nbc-rulenat-text">
|
|
<simpara>
|
|
This command enters the corresponding rule for the
|
|
outbound traffic into the RPDB (kernel 2.2 and up).
|
|
This rule will cause the kernel rewrite any packet from
|
|
192.168.100.17 with the specified source address
|
|
(205.254.211.17). Any packet originating from
|
|
192.168.100.17 which passes through this router
|
|
will trigger this rule. In short, this command rewrites the
|
|
source address of outbound packets so that they appear to
|
|
originate from the NAT IP.
|
|
</simpara>
|
|
</callout>
|
|
<callout
|
|
arearefs="ex-nbc-flushcache"
|
|
id="ex-nbc-flushcache-text">
|
|
<simpara>
|
|
The kernel maintains a routing cache to handle routing
|
|
decisions more quickly
|
|
(<xref linkend="routing-cache"/>). After making changes
|
|
to the routing tables on a system, it is good practice to
|
|
empty the routing cache with <userinput>ip route flush
|
|
cache</userinput>. Once the cache is empty, the
|
|
kernel is guaranteed to consult the routing tables again
|
|
instead of the routing cache.
|
|
</simpara>
|
|
</callout>
|
|
<callout
|
|
arearefs="ex-nbc-routeshow ex-nbc-ruleshow"
|
|
id="ex-nbc-routeruleshow-text">
|
|
<simpara>
|
|
These two commands allow the user to inspect the
|
|
routing policy database and the <constant>local</constant>
|
|
routing table to determine if the NAT routes and rules were
|
|
added correctly.
|
|
</simpara>
|
|
</callout>
|
|
</calloutlist>
|
|
</example>
|
|
<para>
|
|
</para>
|
|
</section>
|
|
<section id="nat-stateless-rpdb">
|
|
<title>Conditional Stateless NAT</title>
|
|
<para>
|
|
NAT introduces a complexity to the network in which it is
|
|
used because a service is reachable on a public and a private IP.
|
|
Usually, this is a reasonable tradeoff or else stateless NAT would
|
|
fail in the selection process.
|
|
In the case that the linux routing device is connected to a public
|
|
network and more than one private
|
|
network, there is more work to do.
|
|
</para>
|
|
<para>
|
|
Though the service is available to the public network on
|
|
a public (NAT) IP, internal users may need to connect to the private
|
|
or internal IP.
|
|
</para>
|
|
<para>
|
|
This is accomplished by use of the routing policy database (RPDB),
|
|
which allows conditional routing based on packet characteristics.
|
|
For a more complete explanation of the RPDB, see
|
|
<xref linkend="routing-rpdb"/>. The routing policy database can
|
|
be manipulated with the <link linkend="tools-ip-rule"><command>
|
|
ip rule</command></link> command.
|
|
In order to successfully configure NAT, familiarity with the
|
|
<command> ip rule</command> command is required.
|
|
</para>
|
|
<example id="ex-nat-stateless-rpdb">
|
|
<title>Conditional Stateless NAT (not performing NAT for a
|
|
specified destination network)</title>
|
|
<programlisting>
|
|
<prompt>[root@masq-gw]# </prompt><userinput>ip rule add to 192.168.99.0/24 from 192.168.100.17</userinput>
|
|
<prompt>[root@masq-gw]# </prompt><userinput>ip route flush cache</userinput>
|
|
<prompt>[root@masq-gw]# </prompt><userinput>ip rule show</userinput>
|
|
<computeroutput>0: from all lookup local
|
|
32764: from 192.168.100.17 to 192.168.99.0/24 lookup main
|
|
32765: from 192.168.100.17 lookup main map-to 205.254.211.17
|
|
32766: from all lookup main
|
|
32767: from all lookup 253</computeroutput>
|
|
</programlisting>
|
|
</example>
|
|
<para>
|
|
Note that we now have an entry of higher priority in the RPDB
|
|
for any packets returning from 192.168.100.17 bound for
|
|
192.168.99.0/24. The rule tells the kernel to find the route
|
|
for 192.168.99.0/24 (from 192.168.100.17) in the main
|
|
routing table. This exception to the NAT mapping of our public
|
|
IP to our internal server will allow the hosts in our second
|
|
internal network to reach the host named &isolde; on
|
|
its private IP address.
|
|
</para>
|
|
<para>
|
|
If &tristan; were to initiate a connection to &isolde; now, the
|
|
packet would return from IP 192.168.100.17 instead of being
|
|
rewritten from 205.254.211.17.
|
|
</para>
|
|
<para>
|
|
Now we have had success creating a NAT mapping with the iproute2
|
|
tools and we have successfully made an exception for another
|
|
internal network which is connected to our linux router. Now,
|
|
supposing we learn that we will be losing our IP space
|
|
next week, we are prepared to change our NAT rules without
|
|
readdressing our server network.
|
|
</para>
|
|
<para>
|
|
Naturally, you may not wish to create these rules manually every time
|
|
you want to use NAT on every device. A standard
|
|
<link linkend="ex-sc-nat">SysV initialization script</link> and
|
|
<link linkend="ex-sc-static-nat">configuration file</link>
|
|
can ease the burden of managing a number of NAT IPs on your system.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
<section id="nat-stateless-pf-interaction">
|
|
<title>Stateless NAT and Packet Filtering</title>
|
|
<para>
|
|
Because NAT rewrites the packet as it passes through the IP stack,
|
|
packet filtering can become complex. With attentiveness to the
|
|
addressing of the packet at each stage
|
|
in its journey through the packet filtering code, you can ease the
|
|
burden of writing a packet filter.
|
|
</para>
|
|
<para>
|
|
All of the below requirements can be deduced from an understanding of
|
|
NAT and the path a packet takes through the kernel. Consult also the
|
|
<ulink url="http://www.tldp.org/HOWTO/IPCHAINS-HOWTO-4.html#ss4.1"><command>ipchains</command>
|
|
packet path</ulink> as illustrated in the
|
|
<ulink url="http://www.tldp.org/HOWTO/IPCHAINS-HOWTO.html"><command>ipchains</command>
|
|
HOWTO</ulink> to understand the packet path when using
|
|
<command>ipchains</command>. Keep in mind when viewing the ASCII
|
|
diagram that stateless NAT will always occur in the routing stage. Also
|
|
consult the
|
|
<ulink url="http://docum.org/stef.coene/qos/kptd/">kernel packet
|
|
traveling diagram</ulink> for a good picture of a 2.4 kernel packet
|
|
path.
|
|
</para>
|
|
<para>
|
|
<xref linkend="tb-nat-pf-ipchains"/> identifies the IP addresses
|
|
on a packet traversing each of the input,
|
|
forward and output chains in an <command>ipchains</command>
|
|
installation.
|
|
</para>
|
|
<table id="tb-nat-pf-ipchains">
|
|
<title>Filtering an &iproute2; NAT packet with
|
|
<command>ipchains</command></title>
|
|
<tgroup cols="3" align="center" colsep="1" rowsep="1">
|
|
<colspec colname="c1"/>
|
|
<colspec colname="c2"/>
|
|
<colspec colname="c3"/>
|
|
<spanspec spanname="fullspan" namest="c1" nameend="c3" align="center"/>
|
|
<thead>
|
|
<row>
|
|
<entry spanname="fullspan">Inbound to the NAT IP</entry>
|
|
</row>
|
|
<row>
|
|
<entry>Chain</entry>
|
|
<entry>Source IP</entry>
|
|
<entry>Destination IP</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>input</entry>
|
|
<entry>64.70.12.210</entry>
|
|
<entry>205.254.211.17</entry>
|
|
</row>
|
|
<row>
|
|
<entry spanname="fullspan">Routing Stage</entry>
|
|
</row>
|
|
<row>
|
|
<entry>forward</entry>
|
|
<entry>64.70.12.210</entry>
|
|
<entry>192.168.100.17</entry>
|
|
</row>
|
|
<row>
|
|
<entry>output</entry>
|
|
<entry>64.70.12.210</entry>
|
|
<entry>192.168.100.17</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
<tgroup cols="3" align="center" colsep="1" rowsep="1">
|
|
<colspec colname="c1"/>
|
|
<colspec colname="c2"/>
|
|
<colspec colname="c3"/>
|
|
<spanspec spanname="fullspan" namest="c1" nameend="c3" align="center"/>
|
|
<thead>
|
|
<row>
|
|
<entry spanname="fullspan">Outbound from the real IP</entry>
|
|
</row>
|
|
<row>
|
|
<entry>Chain</entry>
|
|
<entry>Source IP</entry>
|
|
<entry>Destination IP</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>input</entry>
|
|
<entry>192.168.100.17</entry>
|
|
<entry>64.70.12.210</entry>
|
|
</row>
|
|
<row>
|
|
<entry spanname="fullspan">Routing Stage</entry>
|
|
</row>
|
|
<row>
|
|
<entry>forward</entry>
|
|
<entry>205.254.211.17</entry>
|
|
<entry>64.70.12.210</entry>
|
|
</row>
|
|
<row>
|
|
<entry>output</entry>
|
|
<entry>205.254.211.17</entry>
|
|
<entry>64.70.12.210</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<para>
|
|
A firewall implementing a tight policy (deny all, selectively allow)
|
|
will require a large number of individual rules to allow the NAT packets
|
|
to traverse the firewall packet filter.
|
|
Assuming the configuration detailed in
|
|
<xref linkend="ex-nat-basic"/>, the following set of chains is
|
|
required and will restrict access to only port 25
|
|
<footnote>
|
|
<para>
|
|
I assume here that the user has a restrictive default policy on the
|
|
firewalling device. I suggest a policy of DENY on each of the built
|
|
in <command>ipchains</command> chains.
|
|
</para>
|
|
</footnote>.
|
|
</para>
|
|
<!--
|
|
#
|
|
# XREF to minimum ICMP required from packetfilter.xml
|
|
#
|
|
-->
|
|
<example id="ex-nat-pf-ipchains">
|
|
<title>Using an <command>ipchains</command> packet filter with
|
|
stateless NAT</title>
|
|
<programlisting>
|
|
<prompt>[root@masq-gw]# </prompt><userinput>ipchains -I input -i eth1 -p tcp -l -y -s 0/0 1024:65535 -d 205.254.211.17 25 -j ACCEPT</userinput>
|
|
<prompt>[root@masq-gw]# </prompt><userinput>ipchains -I input -i eth1 -p tcp ! -y -s 0/0 1024:65535 -d 205.254.211.17 25 -j ACCEPT</userinput>
|
|
<prompt>[root@masq-gw]# </prompt><userinput>ipchains -I forward -p tcp -s 0/0 1024:65535 -d 192.168.100.17 25 -j ACCEPT</userinput>
|
|
<prompt>[root@masq-gw]# </prompt><userinput>ipchains -I output -i eth0 -p tcp -s 0/0 1024:65535 -d 192.168.100.17 25 -j ACCEPT</userinput>
|
|
<prompt>[root@masq-gw]# </prompt><userinput>ipchains -I input -i eth0 -p tcp ! -y -s 192.168.100.17 25 -d 0/0 1024:65535 -j ACCEPT</userinput>
|
|
<prompt>[root@masq-gw]# </prompt><userinput>ipchains -I forward -p tcp -s 205.254.211.17 25 -d 0/0 1024:65535 -j ACCEPT</userinput>
|
|
<prompt>[root@masq-gw]# </prompt><userinput>ipchains -I output -i eth1 -p tcp -s 205.254.211.17 25 -d 0/0 1024:65535 -j ACCEPT</userinput>
|
|
<prompt>[root@masq-gw]# </prompt><userinput>for icmptype in \</userinput>
|
|
<prompt>> </prompt><userinput>destination-unreachable source-quench time-exceeded parameter-problem; do</userinput>
|
|
<prompt>> </prompt><userinput>ipchains -I input -i eth1 -p icmp -s 0/0 $icmptype -d 205.254.211.17 -j ACCEPT</userinput>
|
|
<prompt>> </prompt><userinput>ipchains -I forward -p icmp -s 0/0 $icmptype -d 192.168.100.17 -j ACCEPT</userinput>
|
|
<prompt>> </prompt><userinput>ipchains -I output -i eth0 -p icmp -s 0/0 $icmptype -d 192.168.100.17 -j ACCEPT</userinput>
|
|
<prompt>> </prompt><userinput>ipchains -I input -i eth0 -p icmp -s 192.168.100.17 $icmptype -d 0/0 -j ACCEPT</userinput>
|
|
<prompt>> </prompt><userinput>ipchains -I forward -p icmp -s 205.254.211.17 $icmptype -d 0/0 -j ACCEPT</userinput>
|
|
<prompt>> </prompt><userinput>ipchains -I output -i eth1 -p icmp -s 205.254.211.17 $icmptype -d 0/0 -j ACCEPT</userinput>
|
|
<prompt>> </prompt><userinput>done</userinput>
|
|
</programlisting>
|
|
</example>
|
|
<para>
|
|
Please note that the formatting of the commands is simply for display
|
|
purposes, and to allow for easier reading of a complex set of commands.
|
|
The above set of rules is 31 individual chains. This is most certainly
|
|
a complex set of rules. For further details on how to use
|
|
<command>ipchains</command> please see the
|
|
<ulink url="http://www.tldp.org/HOWTO/IPCHAINS-HOWTO.html"><command>ipchains</command>
|
|
HOWTO</ulink>. The salient detail you should notice from the above set
|
|
of rules is the difference between the IPs used in the input and forward
|
|
chains.
|
|
Since packets are rewritten by the stateless NAT code in the routing
|
|
stage, the transformation of the packet will by complete before the
|
|
forward chain is traversed.
|
|
</para>
|
|
<para>
|
|
The first two lines cover all inbound TCP packets, the first line as a
|
|
special case of the second, indicating (<option>-l</option>) that we
|
|
want to log the packet. After successfully traversing the input chain,
|
|
the packet is routed, at which point the destination address of the
|
|
packet has changed. Now, we need to forward the packet from the public
|
|
source address to the private (or real) internal IP address. Finally,
|
|
we need to allow the packet out on the internal interface.
|
|
</para>
|
|
<para>
|
|
The next set of rules handles all of the TCP return packets. On the
|
|
input rule, we are careful to match only non-SYN packets from our
|
|
internal server bound for the world. Once again, the packet is
|
|
rewritten during the routing stage. Now in the forward chain, the
|
|
packet's source IP is the public IP of the service. Finally, we need to
|
|
let the packet out on our external interface.
|
|
</para>
|
|
<para>
|
|
The next series of lines are required ICMP rules to prevent network
|
|
traffic from breaking terribly. These types of ICMP, particularly
|
|
destination unreachable (ICMP 3) and source quench (ICMP 4) help to
|
|
ensure that TCP sessions run with optimized characteristics.
|
|
</para>
|
|
<para>
|
|
These rules are the minimum set of <command>ipchains</command> rules
|
|
needed to support a NAT'd TCP service. This concludes our discussion of
|
|
publishing a service to the world with &iproute2; based
|
|
NAT and protecting the service with <command>ipchains</command>. As you
|
|
can see, the complexity of supporting NAT with
|
|
&iproute2; can be substantial, which is why we'll
|
|
examine the benefits of inbound NAT (DNAT) with netfilter in the next
|
|
section.
|
|
</para>
|
|
</section>
|
|
<section id="nat-dnat">
|
|
<title>Destination NAT with netfilter (DNAT)</title>
|
|
<para>
|
|
Destination NAT with netfilter is commonly used to publish a service
|
|
from an internal RFC 1918 network to a publicly accessible IP.
|
|
To enable DNAT, at least one <command>iptables</command> command is
|
|
required. The
|
|
connection tracking mechanism of netfilter will ensure that subsequent
|
|
packets exchanged in either direction (which can be identified
|
|
as part of the existing DNAT connection) are also transformed.
|
|
</para>
|
|
<para>
|
|
In a devilishly subtle difference, netfilter DNAT does not cause the
|
|
kernel to answer ARP requests for the NAT IP, where
|
|
&iproute2; NAT automatically begins
|
|
<link linkend="nat-stateless-arp">answering ARP requests</link>
|
|
for the NAT IP.
|
|
</para>
|
|
<example id="ex-nat-dnat-all">
|
|
<title>Using DNAT for all protocols (and ports) on one IP</title>
|
|
<programlisting>
|
|
<prompt>[root@real-server]# </prompt><userinput>iptables -t nat -A PREROUTING -d 10.10.20.99 -j DNAT --to-destination 10.10.14.2</userinput>
|
|
</programlisting>
|
|
</example>
|
|
<para>
|
|
In this example, all packets arriving on the router with a destination
|
|
of 10.10.20.99 will depart from the router with a destination of
|
|
10.10.14.2.
|
|
</para>
|
|
<para>
|
|
</para>
|
|
<para>
|
|
</para>
|
|
<para>
|
|
</para>
|
|
<para>
|
|
</para>
|
|
<example id="ex-nat-dnat-port">
|
|
<title>Using DNAT for a single port</title>
|
|
<programlisting>
|
|
<prompt>[root@real-server]# </prompt><userinput>iptables -t nat -A PREROUTING -p tcp -d 10.10.20.99 --dport 80 -j DNAT --to-destination 10.10.14.2</userinput>
|
|
</programlisting>
|
|
</example>
|
|
<para>
|
|
</para>
|
|
<para>
|
|
</para>
|
|
<para>
|
|
</para>
|
|
<para>
|
|
</para>
|
|
<para>
|
|
</para>
|
|
<para>
|
|
Full network address translation, as performed with
|
|
&iproute2; can be simulated with both netfilter
|
|
SNAT and DNAT, with the potential benefit (and attendent resource
|
|
consumption) of connection tracking.
|
|
</para>
|
|
<example id="ex-nat-dnat-full">
|
|
<title>Simulating full NAT with SNAT and DNAT</title>
|
|
<programlisting>
|
|
<prompt>[root@real-server]# </prompt><userinput>iptables -t nat -A PREROUTING -d 205.254.211.17 -j DNAT --to-destination 192.168.100.17</userinput>
|
|
<prompt>[root@real-server]# </prompt><userinput>iptables -t nat -A POSTROUTING -s 192.168.100.17 -j SNAT --to-destination 205.254.211.17</userinput>
|
|
</programlisting>
|
|
</example>
|
|
<para>
|
|
</para>
|
|
<para>
|
|
</para>
|
|
<para>
|
|
</para>
|
|
<para>
|
|
</para>
|
|
<para>
|
|
</para>
|
|
<section id="nat-dnat-pat">
|
|
<title>Port Address Translation with DNAT</title>
|
|
<para>
|
|
</para>
|
|
<para>
|
|
</para>
|
|
</section>
|
|
</section>
|
|
<section id="nat-pat-userspace">
|
|
<title>Port Address Translation (PAT) from Userspace</title>
|
|
<para>
|
|
Port address translation (hereafter PAT) provides a similar
|
|
functionality to NAT, but is a more specific tool. PAT forwards
|
|
requests for a particular IP and port pair to another IP port pair.
|
|
This feature is commonly used on publicly connected hosts to make an
|
|
internal service available to a larger network.
|
|
</para>
|
|
<para>
|
|
PAT will break in strange and wonderful ways if there is an alternate
|
|
route between the two hosts connected by the port address translation.
|
|
</para>
|
|
<para>
|
|
PAT has one important benefit over NAT (with the
|
|
&iproute2; tools). Let's assume that you have only
|
|
five public IP addresses for which you have paid dearly. Additionally,
|
|
let's assume that you want to run services on standard ports. You had
|
|
hoped to connect four SMTP servers, two SSH servers and five HTTP servers.
|
|
If you had wanted to accomplish this with NAT, you'd need more IP space.
|
|
</para>
|
|
</section>
|
|
<section id="nat-pat-userspace-transparent">
|
|
<title>Transparent PAT from Userspace</title>
|
|
<para>
|
|
</para>
|
|
</section>
|
|
</chapter>
|