I would like do some NAT in iptables. So that, all the packets coming to and port 80 will be forwarded to port 80.

How to do this with iptables?


Any other ways to achieve the same?

  • @Matthewlfe, For some reason, I need to forward all the apache request from ( to (
    – sat
    Apr 3, 2014 at 18:08
  • 1
    @Matthewlfe, I have two production servers. One is connected with public static ip address. Due to some connectivity issues, I am not able to connect to DB and other systems from So, I need to forward all the request to
    – sat
    Apr 3, 2014 at 18:24
  • @lain, I am not familiar with iptables. And, I seen some examples. But, It seems to be require two ethernet. Link: revsys.com/writings/quicktips/nat.html
    – sat
    Apr 3, 2014 at 18:27
  • You could also use proxy mode in your web server config to send requests to from (if your webserver supports it)
    – krisFR
    Apr 3, 2014 at 18:44
  • askapache.com/htaccess/…
    – dmourati
    Apr 3, 2014 at 22:00

2 Answers 2


These rules should work, assuming that iptables is running on server :


echo 1 > /proc/sys/net/ipv4/ip_forward

iptables -F
iptables -t nat -F
iptables -X

iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination
iptables -t nat -A POSTROUTING -p tcp -d --dport 80 -j SNAT --to-source

You have to DNAT incoming traffic on port 80, but you will also need to SNAT the traffic back.

Alternative (and best approach IMHO) :

Depending on what your Web Server is (Apache, NGinx) you should consider an HTTP Proxy on your front-end server ( :

  • Works as long as ufw is disabled, even though the port is allows in ufw, but if ufw is enabled, this forwarding stuff doesnt work, any idea ?
    – Sudhir N
    Sep 25, 2016 at 11:35
  • 2
    Great question with great answer. Another use-case this is useful for is if you need to temporarily redirect all the traffic coming to one service, say squid, to another ip/port so as to perform some maintenance on original service without the need to reconfigure all the clients! Very handy!
    – PF4Public
    Dec 15, 2016 at 19:20
  • 4
    " but you will also need to SNAT the traffic back." -> You saved my day. Thank you
    – obayhan
    Feb 27, 2017 at 14:11
  • This solution isnt working for me. I need to forward from eth0 to a virtual network (virb0) which is used by a KVM-guest. I tried adding the -i and -o options but -o isnt allowed for prerouting. Any suggestions? Dec 23, 2017 at 16:37
  • 3
    Be careful with this solution. I completely lost access to my remote machine now.
    – Soren
    Dec 25, 2018 at 8:03

The reason a seemingly obvious iptables -t nat -A PREROUTING -d -p tcp --dport 80 -j DNAT --to-destination will not work is how the return packets will be routed.

You can set up rules that will cause the packets send to to simply be NATted to, but will then send replies directly back to the client. Those replies will not go through the host where your iptables rule is doing NAT, hence the packets in one direction are translated, but packets in the other direction are not.

There are three approaches to solving this problem.

  1. On the first host don't just do DNAT, but also do SNAT such that return traffic will be send back through the first host. The rule could look something like iptables -t NAT -A POSTROUTING -d -p tcp --dport 80 -j SNAT --to-source
  2. Take inspiration from DSR load balancing and DNAT the packets at Ethernet layer instead of at IP layer. By replacing the destination MAC of the packets with the MAC of and sending it on the Ethernet without touching the IP layer, then could have configured on a dummy interface and thus be able to terminate the TCP connection with the server IP known to the client.
  3. Use the naive (but not working) solution on the first host. Then handle the return packets on the second host by doing a SNAT on the return traffic. A rule could look like iptables -t nat -A OUTPUT -p tcp --sport 80 -j SNAT --to-source

Each of those three solutions have drawbacks, so you need to carefully consider, if you really need to do this particular forwarding.

  1. Using SNAT will lose the client IP, so host number 2 will think all connections came from Additionally you'll use bandwidth through host number 1 for all reply packets, which would take a more direct route with the other approaches.
  2. The DSR approach will break all other communication between the two nodes. The DSR approach is really only appropriate when the server address is not the primary IP of any of the hosts. Each host need to have a primary IP, which is not the DSR IP.
  3. Using connection tracking on one host to translate in one direction and connection tracking on another host to translate in the other direction is plain ugly, and there are various ways it could break. For example if port numbers are modified by NAT on either host, there is no way to reconstruct those. It is also not a given, that connection tracking will work correctly, if the first packet it sees is a SYN-ACK rather than an ACK.

Of the three approaches I think the first is the one, which is most likely to work. So if you don't need to know the client IP addresses, that is the one I would recommend.

You can also choose to forget about NAT altogether and not try to solve the problem on MAC or IP layer. You can go all the way up to the HTTP layer and look for a solution there. In that case the solution you will find is an HTTP proxy. If you install an HTTP proxy on and configure it appropriately, you can have it forward the requests to and forward the answers back. Additionally it can insert an X-Forwarded-For header preserving the original client IP. The server on then need to be configured to trust the X-Forwarded-For header from

  • 1
    I'm surprised -j MASQUERADE is not mentioned here; isn't it the usual approach with DNAT?
    – remram
    Dec 4, 2015 at 19:11
  • 6
    @remram I mentioned SNAT instead of MASQUERADE, because that is what the documentation says. The exact wording in the documentation is: It should only be used with dynamically assigned IP (dialup) connections: if you have a static IP address, you should use the SNAT target.
    – kasperd
    Dec 4, 2015 at 22:17

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