我有一个带有真实 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
我做错了什么?:(
PS 在 '127.0.0.1:8080' 上绑定服务器会产生相同的结果,但这并不重要,因为在 '0.0.0.0:8080' 上运行的服务器将接受重定向到 '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)
答案1
我一直在尝试解决这个问题,虽然我最终决定不将我的服务器进程绑定到本地主机(我使用了 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 请求相关的内容,然后您可以使用 proxy_pass 指令让 nginx 将此请求转发到 localhost:8080 (127.0.0.1:8080)。
@MonomiDev 的帖子这里为您提供允许您执行此操作的实际 nginx 配置 - 如果您尚未安装 nginx,那么这里和网上都有大量教程可以帮助您入门。
答案2
只需用这个规则替换你的规则即可。
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
它应该可以工作。这会将 eth0 上的所有 80 端口流量重定向到运行 tomcat 的 localhost 的 8080 端口。
另一种不使用 iptables 的方法是使用 xinetd 服务(因为我甚至不确定是否可以使用 iptables)。要使用 xinetd 服务,请在您的机器上安装 xinetd(通常默认情况下已安装)。创建一个如下文件:
# 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
而且它将会发挥神奇的作用。
答案3
如果你这样做会怎么样:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j REDIRECT --to-port 80 --match comment --comment "Explain."
答案4
上次我使用这样的 DNAT 规则时,还必须在 POSTROUTING 上添加 SNAT 规则才能使其正常工作。