3

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 127.0.0.1 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 127.0.0.1:8080
python -m SimpleHTTPServer 8080

What i'm doing wrong? :(

P.S. Binding server on '127.0.0.1:8080' produce same result, but it does not matter since server running on '0.0.0.0:8080' will accept connection redirected to '127.0.0.1:8080'. 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:

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       tcp  --  anywhere             anywhere             tcp dpt:http to:127.0.0.1:8080

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
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 0.0.0.0:22              0.0.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:5.14.223.181  Bcast:5.14.223.255  Mask:255.255.255.0
          inet6 addr: fe80::140:3eff:febe:201a/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          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)
          Interrupt:25 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          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)
grigoryvp
  • 3,655
  • 11
  • 39
  • 59
  • What are your chain policies? Type iptables -L and iptables -t nat -L – Halfgaar Dec 28 '12 at 18:23
  • @Halfgaar Empty before i enter `iptables` command. One rule after i enter it. – grigoryvp Dec 28 '12 at 18:31
  • I meant policies, not rule. Is it ACCEPT or DROP? – Halfgaar Dec 28 '12 at 19:15
  • @Halfgaar All policies are 'ACCEPT' – grigoryvp Dec 28 '12 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 '12 at 09:27
  • @Halfgaar i have added results, but they are default since it's absolutely clean VDS box with Ubuntu 12.04, i reset OS before tests. – grigoryvp Dec 29 '12 at 10:45
  • Hmm. Add the output of `ifconfig -a` and `brctl show`. Maybe that'll show something. Why do you want to do what you're trying to do? – Halfgaar Dec 29 '12 at 13:14
  • Added requested info to post. `brctl show` is empty. Need this for some third-party apps that binds on '127.0.0.1' - i was sure it's better to forward port via little NAT compared to app source code modification. Now i'm unsure :(. – grigoryvp Dec 29 '12 at 20:59
  • Your application isn't listening, according to netstat. Did you start it? – Halfgaar Dec 30 '12 at 10:16

4 Answers4

5

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                = 127.0.0.1 8080
        bind                    = 10.31.33.101 80
}

Just restart the xinted service.

 # service xinetd restart

And it will work like charm.

Napster_X
  • 3,373
  • 18
  • 20
  • I have tried this - it redirects to `0.0.0.0:8080`, not `127.0.0.1:8080`. Application that is bound to `0.0.0.0:8080` is redirected, application that is bound to `127.0.0.1:8080` is not redirected. – grigoryvp Dec 29 '12 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 '12 at 17:17
2

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 0.0.0.0:PORT), 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 (127.0.0.1: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.

JacobWuzHere
  • 136
  • 2
1

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."
Halfgaar
  • 8,084
  • 6
  • 45
  • 86
0

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.

John
  • 9,070
  • 1
  • 29
  • 34
  • Maybe you can hint how second rule with `SNAT` look like? Unfortunately, i'm not very good with iptables :( – grigoryvp Dec 28 '12 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 '12 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 '12 at 18:28
  • I think he means [this](http://blog.bigsmoke.us/2010/07/23/making-a-port-forwarded-machine-available-from-within-the-lan), but that's not relevant here. – Halfgaar Dec 28 '12 at 19:14