Supposing I have two servers:

-->Server A has the IP XXX.XXX.XXX.XXX

-->Server B has the IP YYY.YYY.YYY.YYY

What I want is to redirect trafic from server A (port 80) to server B (port 80).

A simple way to do that is to put the following rule with iptables in server A :

iptables -t nat -A PREROUTING -p tcp --dport port -j DNAT --to-destination server B:80

However, this simple rule does not work. We must add the following rule:

iptables -t nat -A POSTROUTING -j MASQUERADE

Why so? Why do we need to add a POSTROUTING rule? After the PREROUTING, the packet must go automatically to server B right?

  • 1
    You're right! After PREROUTING the packet go automatically to B. The problem is, that the tcp is not a oneway connection, so if you wanna establish the connection then you have to enable the traffic at both sides. PREROUTING is one side, and POSTROUTING is the other side. – Ipor Sircer Nov 13 '16 at 5:21
  • Ok I thought that after PREROUTING, the outcome was automatically handled :) – Duke Nukem Nov 13 '16 at 13:08
  • With MASQUERADE does server B see the IP of the original client or the IP of A? – Wouter Jul 11 '19 at 12:08

* I'm not an expert in iptables or Linux Network Scheduling, but I'll try to help!

Looking at iptables manual page user@host:~$ man 8 iptables we can see in nat (Network Address Translation) table description:

"This table is consulted when a packet that creates a new connection is encountered. It consists of three built-ins: PREROUTING (for altering packets as soon as they come in), OUTPUT (for altering locally-generated packets before routing), and POSTROUTING (for altering packets as they are about to go out)."

It's POSTROUTING chain :-)

The MASQUERADE explanation below I got from The Linux Documentation Project and I've also put your information to make sense:

  • I tell machine B that my PPP or Ethernet connected Linux box A is its gateway.
  • When a packet comes into the Linux box A from B, it will assign the packet to a new TCP/IP source port number and insert its own IP address inside the packet header, saving the originals. The MASQ server will then send the modified packet over the PPP/ETH interface onto the Internet.
  • When a packet returns from the Internet into the Linux box A, Linux examines if the port number is one of those ports that was assigned above. If so, the MASQ server will then take the original port and IP address, put them back in the returned packet header, and send the packet to B.
  • The host that sent the packet will never know the difference.
| improve this answer | |
  • This doesn't answer the question of why the rule is needed. – plugwash Mar 6 '18 at 19:49
  • @plugwash Yes it does! iptables -t nat -A POSTROUTING -j MASQUERADE means do the MASQUERADE thing when packets are about to go out (POSTROUTING) – Ricardo Biehl Pasquali Mar 11 '18 at 19:44

Your question breaks down into two parts.

  1. Why do we need the MASQUERADE rule.
  2. Why does it need to be in the POSTROUING chain.
  3. Is there any altenative?

To answer the first question we must first understand how iptables NAT works. The NAT tables are used on the first packet of a connection to determine what translations should be applied to that connection. Once the first packet is processed an internal mapping table entry is created which is used to process later packets of the connection but a box can only process packets that it sees.

So lets assume that XXX.XXX.XXX.XXX and YYY.YYY.YYY.YYY are both servers on the Internet with no special routing configured. Lets assume that the client is also on the open internet with no firewalls and has an IP of ZZZ.ZZZ.ZZZ.ZZZ . Lets look at what happens without the MASQURADE rule.

  • The client sends an initial packet ZZZ.ZZZ.ZZZ.ZZZ:1234 -> XXX.XXX.XXX.XXX:80
  • The packet arrives at server A which performs destination NAT, so the packet is now ZZZ.ZZZ.ZZZ.ZZZ:1234 -> YYY.YYY.YYY.YYY:80 it creates the connection tracking entry and puts the packet back out on the network.
  • The ISP may block the packet at this point for "spoofing" or they may deliver it to sever B. Lets assume that they do deliver it to server B.
  • The packet arrives at server B which crafts a response YYY.YYY.YYY.YYY:80 -> ZZZ.ZZZ.ZZZ.ZZZ:1234
  • The response is delivered to the client.
  • The client looks up the response in it's table of sockets but it fails to find a match and discards the packet (possibly sending an ICMP error in response).

How does this change if we add the MASQUERADE rule?

  • The client sends an initial packet ZZZ.ZZZ.ZZZ.ZZZ:1234 -> XXX.XXX.XXX.XXX:80
  • The packet arrives at server A which performs destination NAT and MASQURADING, so the packet is now XXX.XXX.XXX.XXX:5678 -> YYY.YYY.YYY.YYY:80 it puts it back out on the network.
  • The ISP delivers the packet to server B
  • The packet arrives at server B which crafts a response YYY.YYY.YYY.YYY:80 -> XXX.XXX.XXX.XXX:5678
  • The response is delivered to server A
  • Server A looks the packet up in it's connection tracking tables and changes it's source and destination to XXX.XXX.XXX.XXX:80 -> ZZZ.ZZZ.ZZZ.ZZZ:1234
  • The network delivers the response to the client.
  • The client looks up the response in it's table of sockets and finds a match. The connection is succesfully established.

For question 2 I don't really have an answer, iptables insists that SNAT/MASQUERADE can only be done in POSTROUTING but I don't see any good technical justification for why this should be the case.

We might reasonablly want to avoid using MASQUERADE. It has serveral problems, firstly we lose the information on the original source of the traffic which we would like to have for abuse control. Secondly server A has a limited supply of ports.

This can be solved but only if both servers are under our control. The soloution involves three steps.

  • We establish a tunnel of some sort between servers A and B. The tunnel endpoints are assigned private IP addresses.
  • On server A we DNAT the traffic to the tunnel IP of server B.
  • On server B we use policy routing so that traffic coming from server B's private IP is sent down the tunnel to server A rather than being sent back out on to the internet.
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.