I have a test VDS box with real IP. If i start web server on physical interface port 80, it can be opened from another computer via it's ip address (and default port 80):

python -m SimpleHTTPServer 80

But if i try to reditect port 80 from physical interface eth0 to loopback port 8080 i can connect it from another computer on port 8080, but can't connect on port 80, it's just endless 'connecting'. Seems like no redirection occurs:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination
python -m SimpleHTTPServer 8080

What i'm doing wrong? :(

P.S. Binding server on '' produce same result, but it does not matter since server running on '' will accept connection redirected to ''. AFAIK. :(

iptables -L result:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

iptables -t nat -L result:

target     prot opt source               destination         
DNAT       tcp  --  anywhere             anywhere             tcp dpt:http to:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

target     prot opt source               destination

netstat -nlp result:

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0    *               LISTEN      676/sshd        
tcp6       0      0 :::22                   :::*                    LISTEN      676/sshd        
Active UNIX domain sockets (only servers)
Proto RefCnt Flags       Type       State         I-Node   PID/Program name    Path
unix  2      [ ACC ]     STREAM     LISTENING     7964     600/acpid           /var/run/acpid.socket
unix  2      [ ACC ]     STREAM     LISTENING     6590     1/init              @/com/ubuntu/upstart
unix  2      [ ACC ]     SEQPACKET  LISTENING     6760     231/udevd           /run/udev/control
unix  2      [ ACC ]     STREAM     LISTENING     7030     345/dbus-daemon     /var/run/dbus/system_bus_socket

ifconfig -a result:

eth0      Link encap:Ethernet  HWaddr 00:16:3e:da:1a:98  
          inet addr:  Bcast:  Mask:
          inet6 addr: fe80::140:3eff:febe:201a/64 Scope:Link
          RX packets:371264 errors:0 dropped:59 overruns:0 frame:0
          TX packets:2093 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:17377545 (17.3 MB)  TX bytes:214428 (214.4 KB)

lo        Link encap:Local Loopback  
          inet addr:  Mask:
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:10 errors:0 dropped:0 overruns:0 frame:0
          TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:552 (552.0 B)  TX bytes:552 (552.0 B)
  • What are your chain policies? Type iptables -L and iptables -t nat -L
    – Halfgaar
    Dec 28, 2012 at 18:23
  • @Halfgaar Empty before i enter iptables command. One rule after i enter it.
    – grigoryvp
    Dec 28, 2012 at 18:31
  • I meant policies, not rule. Is it ACCEPT or DROP?
    – Halfgaar
    Dec 28, 2012 at 19:15
  • @Halfgaar All policies are 'ACCEPT'
    – grigoryvp
    Dec 28, 2012 at 20:18
  • There must be a DROP going on, because otherwise it would give a 'connection error' right away. But instead it's 'connecting' all the time. Could you post the output of iptables -L, iptables -t nat -L and `netstat -lnp'?
    – Halfgaar
    Dec 29, 2012 at 9:27

4 Answers 4


I have been trying to solve this problem for a while now, and while I ultimately decided not to bind my server process to localhost (I used, for a while I was unsure of where my incoming packets were actually going given I thought I had the right NAT rule.

The answer was that the kernel was intercepting them as martian packets, and discarding them to the side.

This site has a pretty easy set of instructions for setting up logging of martian packets, should you want to see if this was happening to you.

Another solution is to use nginx as a reverse proxy. In that case, you would allow packets with a destination port of 80 through the iptables firewall (check to make sure you are not dropping during the FILTER and the NAT stages -- you can check by running sudo iptables -t nat -L -v or sudo iptables -t filter -L -v). From there nginx listens across all interfaces for traffic destined for port 80. Finding some related to the incoming HTTP request, you can then have nginx forward this request for you to localhost:8080 ( using the proxy_pass directive.

@MonomiDev's post here provides you the actual nginx config that would allow you to do this -- and then if you don't have nginx installed there are tons of tutorials both here on Stack and online to get you started.


Simply replace your rule with this one.

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080

It should work. This will redirect all your 80 port traffic on eth0 to 8080 port of localhost where you are running tomcat.

One other way of doing this without iptables (as I am not even sure whether it's possible with iptables) is using the xinetd services. To use this, install xinetd on your machine (usually it is by default installed). Create a file like this:

 # vim /etc/xinted.d/tomcat

Put this content in the file:

service tomcat
    socket_type             = stream
        wait                    = no
        user                    = root
        redirect                = 8080
        bind                    = 80

Just restart the xinted service.

 # service xinetd restart

And it will work like charm.

  • I have tried this - it redirects to, not Application that is bound to is redirected, application that is bound to is not redirected.
    – grigoryvp
    Dec 29, 2012 at 21:00
  • So, after reading a lot of online help/tutorials/blogs, I am not able to do it. I am now not even sure whether this is even possible (though people are saying that they have done it). But, there is one other way of doing this, which I have edited in my answer.
    – Napster_X
    Dec 30, 2012 at 17:17

What if you do this:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j REDIRECT --to-port 80  --match comment --comment "Explain."
  • I need to add this rule replacing my own or alongside with it? It seems to map 8080 -> 80, how it can help?
    – grigoryvp
    Dec 28, 2012 at 18:24
  • I meant replacing your rule. And the remap, isn't that what you want?
    – Halfgaar
    Dec 28, 2012 at 19:15
  • Same effect, not working :(
    – grigoryvp
    Dec 28, 2012 at 19:25

The last time I use a DNAT rule like that, I also had to put in an SNAT rule on POSTROUTING to make it work correctly.

  • Maybe you can hint how second rule with SNAT look like? Unfortunately, i'm not very good with iptables :(
    – grigoryvp
    Dec 28, 2012 at 18:21
  • Aren't you confused with when you have a masquerading router? To make a port-forward to an internal machine available on a NAT router's WAN IP from within the LAN as well, you indeed need an SNAT rule.
    – Halfgaar
    Dec 28, 2012 at 18:22
  • It's been long enough since I did SNAT/DNAT stuff that I'm useless as to what the rule should look like.
    – John
    Dec 28, 2012 at 18:28
  • I think he means this, but that's not relevant here.
    – Halfgaar
    Dec 28, 2012 at 19:14

You must log in to answer this question.

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