如何将外部TCP端口80路由到环回(127.0.0.1)端口8080?

我有一个真正的IPtestingVDS盒。 如果我在物理接口端口80上启动Web服务器,可以通过它的IP地址(和默认端口80)从另一台计算机打开:

python -m SimpleHTTPServer 80 

但是,如果我尝试重新从物理接口eth0端口80到环回127.0.0.1端口8080我可以连接从另一台计算机端口8080,但不能连接在端口80,它只是无尽的“连接”。 似乎没有发生redirect:

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

我做错了什么? 🙁

在“127.0.0.1:8080”上的PS绑定服务器产生相同的结果,但是这并不重要,因为运行在“0.0.0.0:8080”上的服务器将接受redirect到“127.0.0.1:8080”的连接。 据我所知。 🙁

iptables -L结果:

 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结果:

 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结果:

 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结果:

 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) 

我一直在尝试解决这个问题一段时间,而我最终决定不把我的服务器进程绑定到本地主机(我使用0.0.0.0:PORT),有一段时间,我不确定我的传入数据包实际上在哪里因为我认为我有正确的NAT规则。

答案就是内核把它们拦截成火星包 ,丢在一边。

如果你想知道这是否发生在你身上,那么这个站点有一套非常简单的设置logging火星包的指令。

另一个解决scheme是使用nginx作为反向代理。 在这种情况下,您可以通过iptables防火墙允许目标端口为80的数据包(检查以确保您在FILTER和NAT阶段不会丢失 – 可以通过运行sudo iptables -t nat -L -v或者sudo iptables -t filter -L -v )。 从那里,nginx侦听所有接口的80端口stream量。find一些与传入的HTTP请求相关的,然后你可以让nginx使用proxy_pass指令将这个请求转发到localhost:8080(127.0.0.1:8080)。

@ MonomiDev的post在这里给你提供了实际的nginxconfiguration,可以让你做到这一点 – 然后,如果你没有安装nginx,在这里有大量的教程在这里,在网上,让你开始。

简单地用这个replace你的规则。

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

它应该工作。 这会将eth0上的所有80端口stream量redirect到您运行tomcat的本地主机的8080端口。


另外一种不使用iptables的方法(因为我甚至不确定iptables是否可能)使用xinetd服务。 要使用这个,在你的机器上安装xinetd(通常默认安装)。 像这样创build一个文件:

  # vim /etc/xinted.d/tomcat 

把这个内容放在文件中:

 service tomcat { socket_type = stream wait = no user = root redirect = 127.0.0.1 8080 bind = 10.31.33.101 80 } 

只需重新启动xinted服务。

  # service xinetd restart 

它会像魅力一样工作。

如果你这样做:

 iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j REDIRECT --to-port 80 --match comment --comment "Explain." 

上次我使用这样的DNAT规则时,我还必须在POSTROUTING中join一个SNAT规则才能正常工作。