1

I'm trying to forward all HTTP traffic from one EC2 linux server (external IP 11.11.11.11) to another one (external IP 22.22.22.22), these rules set:

sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 22.22.22.22:80
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
sudo service iptables save
sudo service iptables restart

But when running CURL from a client, the destination server sees 11.11.11.11 as origin IP of the request. So I've tried what was offered in a similar question, added a -d 11.11.11.11 to the first command, so it looks like this:

sudo iptables -t nat -A PREROUTING -d 11.11.11.11 -p tcp --dport 80 -j DNAT --to-destination 22.22.22.22:80

But now trying to CURL to 11.11.11.11 results in a Connection refused error.

Any idea why the second command fails and how to do this right?

1
  • When you do MASQUERADE, the source IP is replaced on the packet. You need to try HTTP proxying, where you put the original source IP to a HTTP header which can then be used by the destination server. Jul 8, 2015 at 17:59

1 Answer 1

1

Changing IP addresses is how NAT works. That's essentially the purpose of Network Address Translation. If the source address didn't change, the target machine would try to reply directly to the original client, which would fail, either because the client would see that reply as coming from an unexpected place (reply from the "wrong" IP address) and reject it, or a stateful firewall would block it (detecting it as a continuation of a session that had never been established) or the destination host would have no route back to the sender to begin with.

To preserve the identity of the original host, you have to preserve that information elsewhere, other than the IP packets.

Probably the most common approach is an HTTP reverse proxy; HAProxy, squid, varnish, apache, nginx, and many other solutions to this exist. They work by inserting a new header, typically X-Forwarded-For: into the http request headers, identifying the connecting client to the destination web server.

That is your simplest solution. NAT does not seem like a fit for what you need.

Alternately, HAProxy and probably some other platforms support something called the PROXY Protocol which transmits the client IP and port (and the original destination IP and port) in a pseudo-out-of-band format before cutting through the actual payload over the connection. Unlike the X-Fowarded-For: solution, which can be interpreted by your application (by accessing the http request headers) if not supported by the actual web server, the PROXY Protocol requires the destination server to understand that protocol. On the plus side, this alternative works with most TCP stream-based protocols (in addition to http) since it doesn't need to modify the actual request itself.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .