In the section on RFC 1918 IP addresses, I mentioned that the problem is crossing the boundary between public (non-RFC 1918) IP addresses and private (RFC 1918) IP addresses. There are three ways to do it: Source Network Address Translation (SNAT)1, Destination Network Address Translation (DNAT)2 and virtual servers (VS – also called a Virtual IP or VIP).

Network Address Translation (NAT) occurs when one of the IP addresses in an IP packet header is changed. In a SNAT, the destination IP address is maintained and the source IP address is changed. Most commonly, a SNAT allows a host on the “inside” of the NAT, in an RFC 1918 IP address space, to initiate a connection to a host on the “outside” of the NAT. A DNAT, by way of contrast, occurs when the destination address is changed and the source IP address is maintained. A DNAT allows a host on the “outside” to connect to a host on the “inside”. In both cases, the NAT has to maintain a connection table which tells the NAT where to route returning packets. An important difference between a SNAT and a DNAT is that a SNAT allows multiple hosts on the “inside” to get to any host on the “outside”. By way of contrast, a DNAT allows any host on the “outside” to get to a single host on the “inside”.

For example, suppose we have a SNAT with IP address and destination IP address Suppose a host on the “inside” with IP address wishes to connect to the The host first sends a query to its name server to get the IP address of, which might be (the IP address of my nameservers is in /etc/resolv.conf). The destination port is 53 as always and the source port might be 3345. Because the default gateway of the host is set to the IP address of the SNAT, the packet is sent to with source IP address and destination IP address The SNAT then creates a new packet with source address:port and destination IP address The SNAT also creates an entry in the connection table which maps address:port back to A few milliseconds later, the nameserver sends a response back to the SNAT's IP address:port The SNAT checks its connection table, finds the entry, and sends the packet to In the unlikely event that something else is already in the connection table, then the SNAT will also change the source port, but this is unusual.

Once the host knows where is, it can initiate a TCP connection to it. It sends a packet with the SYN bit set to

One of the challenges in designing and operating a SNAT is telling when a connection may be dropped (entry removed from the table). In the case of UDP, it is very hard to know because UDP is connectionless. In the case of TCP, it is easier because there are three ways to close a connection: send a FIN packet, send a RESET packet, or just quietly drop the connection. This last is problematical, because the connection table can overflow which would be A Bad Thing. So to handle UDP and TCP quiet drops, there is a connection timer which breaks the connection after a certain amount of time has elapsed, typically 5 minutes.

1F5 Networks calls it a Secure Network Address Translation because the only way to get to a host on the inside is if the host initiates a connection to the outside.

2F5 networks calls it a NAT, Network Address Translation but I prefer Destination Network Address Translation which I think is more descriptive.