我有一个带有真实 IP 的测试 VDS 盒。如果我在物理接口端口 80 上启动 Web 服务器,它可以通过它的 IP 地址(和默认端口 80)从另一台计算机打开:
python -m SimpleHTTPServer 80
但是,如果我尝试将端口 80 从物理接口重新编辑eth0
到环回 127.0.0.1 端口 8080,我可以从另一台计算机的端口 8080 连接它,但无法连接端口 80,它只是无休止的“连接”。似乎没有发生重定向:
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”上运行的服务器将接受重定向到“127.0.0.1:8080”的连接。AFAIK。:(
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)
只需将您的规则替换为该规则即可。
它应该工作。这会将 eth0 上的所有 80 端口流量重定向到运行 tomcat 的本地主机的 8080 端口。
在没有 iptables 的情况下执行此操作的另一种方法(因为我什至不确定是否可以使用 iptables)是使用 xinetd 服务。要使用它,请在您的机器上安装 xinetd(通常它是默认安装的)。创建一个这样的文件:
将此内容放入文件中:
只需重新启动 xinted 服务即可。
它会像魅力一样工作。
一段时间以来,我一直在尝试解决这个问题,虽然我最终决定不将我的服务器进程绑定到本地主机(我使用 0.0.0.0:PORT),但有一段时间我不确定传入的数据包实际去了哪里鉴于我认为我有正确的 NAT 规则。
答案是内核将它们作为火星数据包拦截,并将它们丢弃到一边。
这个网站有一套非常简单的说明来设置火星数据包的日志记录,如果你想看看这是否发生在你身上。
另一种解决方案是使用 nginx 作为反向代理。在这种情况下,您将允许目标端口为 80 的数据包通过 iptables 防火墙(检查以确保您在 FILTER 和 NAT 阶段没有丢弃——您可以通过运行
sudo iptables -t nat -L -v
或来检查sudo iptables -t filter -L -v
)。从那里 nginx 侦听所有接口的目的地为端口 80 的流量。找到一些与传入的 HTTP 请求相关的信息,然后您可以让 nginx 使用 proxy_pass 指令将此请求转发到 localhost:8080 (127.0.0.1:8080)。@MonomiDev 的帖子在这里为您提供了允许您执行此操作的实际 nginx 配置——然后如果您没有安装 nginx,Stack 和在线上有大量教程可以帮助您入门。
如果你这样做会怎样:
上次我使用这样的 DNAT 规则时,我还必须在 POSTROUTING 上放入 SNAT 规则才能使其正常工作。