# Network Address Translation (NAT)

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.

This chapter will introduce two types of NAT available under linux. One, full NAT or stateless NAT, is available under kernel 2.2 and kernel 2.4 via the &iproute2; userspace interface. Available only under kernel 2.4, destination NAT (DNAT) is an important derivative of full NAT. DNAT configuration from userspace is accomplished via the `iptables` 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 , although many concepts involved in the special purpose SNAT and masquerading will be introduced in this chapter.

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, NAT, 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 (destination NAT) and SNAT (source NAT).

Michael Hasenstein's seminal paper on network address translation is available courtesy of SuSe Linux AG here.

## Rationale for and Introduction to NAT

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 If using stateless NAT, the inbound and outbound translations can occur on more than one device, provided that all of the devices are performing the same translation. .

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 for a discussion of these cases.

Here are a few common reasons to consider NAT along with potential NAT solution candidates shown in parentheses.

- 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. (NAT, DNAT, PAT with DNAT PAT from userspace)

- An application requires inbound and outbound connections. In this case SNAT/masquerading will not suffice. See also . (NAT, SNAT and application-aware connection tracking)

- 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. (NAT, DNAT)

- 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. (NAT, DNAT, SNAT)

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 .

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.

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.

The simplest form of NAT under linux is &iproute2; NAT. This type of NAT requires two matching commands, one to cause the kernel to rewrite the inbound packets (`ip route add nat $NATIP via $REAL`) and one to rewrite the outbound packets (`ip rule add from $REAL nat $NATIP`). 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.

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 `ipmasqadm`, `ipnatadm` and `ipportfw` across the Internet in older documentation, these tools have been superseded in functionality and widespread deployment by the netfilter engine and its userspace partner, `iptables`.

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. DNAT 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.

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.

One other less common technique for furnishing inbound services is the use of port redirection. Although there are higher layer tools which can perform transparent application layer proxying (e.g. Squid), these are outside the scope of this documentation.

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.

server NAT IP
NAT IP

  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.

real IP
server IP
hidden IP
private IP
internal IP

  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.

client IP

  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.

The above terms will be used below and in general discussions of NAT.

## Application Layer Protocols with Embedded Network Information

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.

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.

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.

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.

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.

## Stateless NAT with &iproute2;

Stateless NAT, occasionally maligned as dumb NAT In the kernel code tree, stateless NAT, &iproute2; NAT can be located in the file `net/ipv4/ip_nat_dumb.c`. Even in the kernel, it has this reputation. , 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 simulated with netfilter.

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 . This can be considered, alternatively, a benefit or a misfeature of the kernel support for NAT. The `nat` entry in the local routing table causes the kernel to reply for ARP requests to the NAT IP. Conversely, netfilter DNAT makes no ARP entry or provision for neighbor advertisement.

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 a simple example and an explanation of the required commands, then an example of using NAT with the RPDB and using NAT with a packet filter.

NAT with iproute2 can be used in conjunction with the routing policy database (cf. RPDB) to support conditional NAT, e.g. only perform NAT if the source IP falls within a certain range. See .

### Stateless NAT Packet Capture and Introduction

Assume that example company in example network 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.

#### Stateless NAT Packet Capture If you are having some difficulty understanding the output of `tcpdump`, please see the section on tcpdump.

    [root@masq-gw]# tcpdump -qnn
    19:30:17.824853 eth1 < 64.70.12.210.35131 > 205.254.211.17.25: tcp 0 (DF)
    19:30:17.824976 eth0 > 64.70.12.210.35131 > 192.168.100.17.25: tcp 0 (DF)
    19:30:17.825400 eth0 < 192.168.100.17.25 > 64.70.12.210.35131: tcp 0 (DF)
    19:30:17.825568 eth1 > 205.254.211.17.25 > 64.70.12.210.35131: tcp 0 (DF)

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.

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 `nat` entry in the `local` routing table (`ip route`). See also .

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 (`ip rule`). See also .

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.

### Stateless NAT Practicum

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 and ) as shown above in .

#### Basic commands to create a stateless NAT

    [root@masq-gw]# ip route add nat 205.254.211.17 via 192.168.100.17
    [root@masq-gw]# ip rule add nat 205.254.211.17 from 192.168.100.17
    [root@masq-gw]# ip route flush cache
    [root@masq-gw]# ip route show table all | grep ^nat
    nat 205.254.211.17 via 192.168.100.17  table local  scope host
    [root@masq-gw]# ip rule show
    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

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.

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.

The kernel maintains a routing cache to handle routing decisions more quickly (). After making changes to the routing tables on a system, it is good practice to empty the routing cache with `ip route flush cache`. Once the cache is empty, the kernel is guaranteed to consult the routing tables again instead of the routing cache.

These two commands allow the user to inspect the routing policy database and the `local` routing table to determine if the NAT routes and rules were added correctly.

### Conditional Stateless NAT

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.

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.

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 . The routing policy database can be manipulated with the `ip rule` command. In order to successfully configure NAT, familiarity with the `ip rule` command is required.

#### Conditional Stateless NAT (not performing NAT for a specified destination network)

    [root@masq-gw]# ip rule add to 192.168.99.0/24 from 192.168.100.17
    [root@masq-gw]# ip route flush cache
    [root@masq-gw]# ip rule show
    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

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.

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.

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.

Naturally, you may not wish to create these rules manually every time you want to use NAT on every device. A standard SysV initialization script and configuration file can ease the burden of managing a number of NAT IPs on your system.

## Stateless NAT and Packet Filtering

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.

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 `ipchains` packet path as illustrated in the `ipchains` HOWTO to understand the packet path when using `ipchains`. Keep in mind when viewing the ASCII diagram that stateless NAT will always occur in the routing stage. Also consult the kernel packet traveling diagram for a good picture of a 2.4 kernel packet path.

identifies the IP addresses on a packet traversing each of the input, forward and output chains in an `ipchains` installation.

### Filtering an &iproute2; NAT packet with `ipchains`

Inbound to the NAT IP
Chain | Source IP | Destination IP
--- | --- | ---
input | 64.70.12.210 | 205.254.211.17
Routing Stage
forward | 64.70.12.210 | 192.168.100.17
output | 64.70.12.210 | 192.168.100.17
Outbound from the real IP
Chain | Source IP | Destination IP
input | 192.168.100.17 | 64.70.12.210
Routing Stage
forward | 205.254.211.17 | 64.70.12.210
output | 205.254.211.17 | 64.70.12.210

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 , the following set of chains is required and will restrict access to only port 25 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 `ipchains` chains. .

### Using an `ipchains` packet filter with stateless NAT

    [root@masq-gw]# ipchains -I input  -i eth1 -p tcp -l -y -s 0/0 1024:65535    -d 205.254.211.17 25 -j ACCEPT
    [root@masq-gw]# ipchains -I input  -i eth1 -p tcp  ! -y -s 0/0 1024:65535    -d 205.254.211.17 25 -j ACCEPT
    [root@masq-gw]# ipchains -I forward        -p tcp       -s 0/0 1024:65535    -d 192.168.100.17 25 -j ACCEPT
    [root@masq-gw]# ipchains -I output -i eth0 -p tcp       -s 0/0 1024:65535    -d 192.168.100.17 25 -j ACCEPT
    [root@masq-gw]# ipchains -I input  -i eth0 -p tcp  ! -y -s 192.168.100.17 25 -d 0/0 1024:65535    -j ACCEPT
    [root@masq-gw]# ipchains -I forward        -p tcp       -s 205.254.211.17 25 -d 0/0 1024:65535    -j ACCEPT
    [root@masq-gw]# ipchains -I output -i eth1 -p tcp       -s 205.254.211.17 25 -d 0/0 1024:65535    -j ACCEPT
    [root@masq-gw]# for icmptype in \
    > destination-unreachable source-quench time-exceeded parameter-problem; do
    > ipchains -I input  -i eth1 -p icmp -s 0/0 $icmptype            -d 205.254.211.17 -j ACCEPT
    > ipchains -I forward        -p icmp -s 0/0 $icmptype            -d 192.168.100.17 -j ACCEPT
    > ipchains -I output -i eth0 -p icmp -s 0/0 $icmptype            -d 192.168.100.17 -j ACCEPT
    > ipchains -I input  -i eth0 -p icmp -s 192.168.100.17 $icmptype -d 0/0            -j ACCEPT
    > ipchains -I forward        -p icmp -s 205.254.211.17 $icmptype -d 0/0            -j ACCEPT
    > ipchains -I output -i eth1 -p icmp -s 205.254.211.17 $icmptype -d 0/0            -j ACCEPT
    > done

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 `ipchains` please see the `ipchains` HOWTO. 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.

The first two lines cover all inbound TCP packets, the first line as a special case of the second, indicating (`-l`) 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.

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.

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.

These rules are the minimum set of `ipchains` 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 `ipchains`. 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.

## Destination NAT with netfilter (DNAT)

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 `iptables` 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.

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 answering ARP requests for the NAT IP.

### Using DNAT for all protocols (and ports) on one IP

    [root@real-server]# iptables -t nat -A PREROUTING -d 10.10.20.99 -j DNAT --to-destination 10.10.14.2

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.

### Using DNAT for a single port

    [root@real-server]# iptables -t nat -A PREROUTING -p tcp -d 10.10.20.99 --dport 80 -j DNAT --to-destination 10.10.14.2

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.

### Simulating full NAT with SNAT and DNAT

    [root@real-server]# iptables -t nat -A PREROUTING -d 205.254.211.17 -j DNAT --to-destination 192.168.100.17
    [root@real-server]# iptables -t nat -A POSTROUTING -s 192.168.100.17 -j SNAT --to-destination 205.254.211.17

### Port Address Translation with DNAT

## Port Address Translation (PAT) from Userspace

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.

PAT will break in strange and wonderful ways if there is an alternate route between the two hosts connected by the port address translation.

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.

## Transparent PAT from Userspace