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

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

我有一个带有真实 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 规则才能使其正常工作。

相关内容