I have a Linux machine in my local network that I use as a gateway, so all of my network traffic passes it (the machine has only one network interface which I use for incoming and outgoing traffic). I need to forward all HTTP packages coming in on port 7080 to port 80. Furthermore I want to redirect the HTTP responses back to the client that sent the request.

I tried to achieve that using the following iptables rules:

iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 7080 -j ACCEPT
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT

iptables -t nat -A OUTPUT -p tcp --dport 7080 -j REDIRECT --to-ports 80
iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-ports 7080

When those rules are active I do not receive any HTTP responses on a client.

Does anybody have an idea what I am doing wrong, or how I could solve this problem?

migrated from stackoverflow.com Nov 25 '13 at 18:10

This question came from our site for professional and enthusiast programmers.


You're applying the wrong chains. Packets that are received are first processed by PREROUTING; if they are identified as going to "this" machine, they are handed to INPUT, otherwise to FORWARD and POSTROUTING. The OUTPUT chain only ever applies to packets that are generated locally. The iptables tutorial has a fantastic chapter on this.

Based on an example elsewhere on the internet, to answer your question as posed, you probably just need to do this:

# Packets that arrive for port 7080 should be redirected to port 80
iptables -t nat -A PREROUTING -p tcp --dport 7080 -j REDIRECT --to-ports 80

# Separately, all packets that leave this machine that go to port 80
# (which will include the ones redirected above) should be masqueraded,
# i.e. use NAT:
iptables -t nat -A POSTROUTING -p tcp --dport 80 -j MSAQUERADE

I'm pretty sure that what you want to do is more complicated, not least because you don't actually say in which direction you want this to happen. If what you actually want to do is just set up a port forward so that your external IP address (let's pretend it's looks to the Internet as if it had a webserver running on its port 7080 - but you're actually serving that from an internal machine (let's say on port 80. That's also easy, just different, and even closer to the example already mentioned:

# Anything sent to your external IP:port gets redirected to the internal one:
iptables -t nat -A PREROUTING -d -p tcp --dport 7080 \
    -j DNAT --to-destination

# Make sure those connections actually work, by rewriting everything back,
# again simply using NAT:
iptables -t nat -A POSTROUTING -d -p tcp -dport 80 -j MASQUERADE

INPUT means only the packets, which will be processed by your userspace.

You should use not INPUT, but the PREROUTING chain in the nat table.

A tcpdump is very useful to debug, what really happens to your packets.


You have to do 3 changes to tcp packet: SourceNAT,DestinationNAT with port changing. This is not allowed to the same packet. But you can use third party application like nginx and simply redirect packet by this application.

  • This is incorrect; you can make any number of changes. – Gabe Dec 6 '13 at 16:13

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.