Source and Destination Network Address Translation (SNAT / DNAT) with iptables

A colleague of mine approached me with a need to do some IP address translation.

He had a machine (A) with an IP of 10.10.10.99 and he wanted any connections coming to this machine to get rerouted to another machine (B) with an IP address of 192.168.1.101.

Machine A was a linux system and was the default gateway for machine B (*). This was a perfect fit for a  SNAT/DNAT using iptables.

The reason it is important for machine B to see machine A as a router is that not only do we need to modify the packets going to machine A to look like they were intended for machine B, but we also want to translate the return traffic from machine B to look like it came from machine A. Otherwise someone connecting to machine A from outside the network would see replies coming from machine B and their TCP/IP stack would reject these replies as the source address (B) for them would not match what they were expecting to see (A).

There are three things we need to do on machine A.

  1. Enable ip forwarding.
  2. Apply the DNAT rule
  3. Apply the SNAT rule

Enable IP forwarding

The first is easy, check the contents of /proc/sys/net/ipv4/ip_forward

cat /proc/sys/net/ipv4/ip_forward

An output of 0 indicates IP forwarding is disabled, a value of 1 indicates IP forwarding is enabled.

If it is disabled, edit /etc/sysctl.conf with a text editor and change the value of net.ipv4.ip_forward to 1. After making the change, do a

/etc/init.d/network restart

Destination NAT

Destination NAT means, we translate the destination address of a packet to make it go somewhere else instead of where it was originally addressed. For our scenario, it is:

iptables -t nat -A  PREROUTING -d 10.10.10.99/32 -j DNAT –to-destination 192.168.1.101

Now all IP packets coming to our machine’s (A) IP address of 10.10.10.99 will be rewritten and sent to 192.168.1.101 instead. This translation is transparent to the machine the connection is originating from and to machine B.

So if you connect from, say, 172.16.1.10 to 10.10.10.99, the packet will be rewritten upon reaching machine A and be sent to machine B. Machine B will see it coming from 172.16.1.10, it will have no idea that the connection was redirected by 10.10.10.99. This is important because when machine B replies, the FROM address in it’s reply will be it’s own IP address of 192.168.1.101.

This will cause a protocol error on your machine because your machine (172.16.1.10) will be expecting a reply from 10.10.10.99 and instead will receive a reply from 192.168.1.101.

To fix this, we now need to do SNAT – Source Network Address Translation.

SNAT

We want to do SNAT to translate the from address of our reply packets to make them look like they’re coming from 10.10.10.99 instead of 192.168.1.101. To do this, we need to apply a SNAT iptables rule on a router along the path these reply packets will take. Since our machine A is the default gateway for machine B, we will do the SNAT on machine A as well.

iptables -t nat -A POSTROUTING -s 192.168.1.101/32 -j SNAT –to-source 10.10.10.99

This rewrites our source address to look like the packets are coming from 10.10.10.99 instead of 192.168.1.101.

At this point, try to connect to machine A using SSH and log in using credentials for machine B.

Once you’ve confirmed this works, you can save your iptables configuration with:

service iptables save

You can then configure iptables to run at startup automatically.

/sbin/chkconfig –level 3 iptables on

/sbin/chkconfig –level 5 iptables on

And that concludes a basic DNAT/SNAT configuration. In most situations you may want to narrow down the match criteria to specific protocols or ports. e.g. you can use the “-p tcp –dport 22” flags to match only SSH traffic.

If you’d like me to expand upon any of this further, please leave a comment asking for details.

Advertisements

10 Responses to Source and Destination Network Address Translation (SNAT / DNAT) with iptables

  1. Pingback: iptables command returned with an error

  2. Pingback: iptables command returned with an error

  3. Matt says:

    This was a really helpful article! Thank you very much!

  4. itamar sh says:

    Thank You Very Much

    this artice had helped me a lot.
    ive searched all over the net about it for an exercise in my Computer Communication course
    you gave me all the info i needed.

    be well.

  5. Ah, the SNAT section helped so much. I have a VPN server that has a GRE tunnel hanging off of it and I couldn’t get VPN clients to get traffic out through the GRE tunnel. Using SNAT to make them look like they’re coming from the internal router interface fixed the problem immediately.

    Thanks!

  6. viswa says:

    This is really good and very useful.

  7. Ace says:

    Will the reply really cause a protocol error if you don’t add an SNAT rule? Or will the source address of return packets get automatically translated back to the IP address of the source host (auto De-SNAT). And does the same apply for SNAT (The destination address of return packets is automatically translated back to the IP address of the source host).

    http://www.brocade.com/content/html/en/vrouter5600/35r6/vrouter-35r6-nat/GUID-9B182474-0CFE-40DD-B37F-ABFC8A02E123.html

    http://www.iptables.info/en/structure-of-iptables.html

  8. Pingback: Iptables Tutorial for Beginners - Key Concepts

  9. Pingback: SNAT and DNAT with IPTables | 0ddn1x: tricks with *nix

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: