我正在使用 Red Hat,并尝试设置 Web 服务。我已经实现了从 80 到 8080 的端口转发以访问 tomcat8 服务。
firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080
服务器从外部接收 HTTP 请求(由于端口转发,该请求运行良好),根据请求,它将向 nodejs 发送请求,然后 nodejs 会进行响应。问题是,当 nodejs 尝试响应来自 tomcat8 的请求时,连接被拒绝:
problem with request: connect ECONNREFUSED <my_ip_adress>:80
我尝试接受端口 80 上的每个 TCP 连接,但它没有任何反应。
iptables -I INPUT -p UDP --port 80 -j ACCEPT
我还尝试修改防火墙以接受public
和internal
区域上的端口 80 上的每个 TCP 连接。
firewall-cmd --zone=public --add-port=80/tcp
firewall-cmd --zone=internal --add-port=80/tcp
并在防火墙的内部区域添加80到8080的特定端口转发。
firewall-cmd --zone=internal --add-forward-port=port=80:proto=tcp:toport=8080
另外,当我尝试连接到端口 80 上的本地主机时,连接被拒绝。
telnet localhost 80
我得出的结论是端口转发不是内部进行的。有人知道如何授权这种内部通信吗?
更新 1
也许它可以有所帮助,当我telnet hostname 80
在网络中的另一台机器上执行时,它可以连接。当我telnet hostname 8080
在相关机器上执行时,它也能正确连接(正如端口转发和路由表所期望的那样)。但是,当我执行时telnet hostname 80
,连接被拒绝。
我认为这个问题与“重复”的问题不同,因为这里的问题是无论出于何种原因都没有内部端口转发。
** 更新 2** 输出iptables -t nat -nvL
(我已截断空链):
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
7 424 PREROUTING_direct all -- * * 0.0.0.0/0 0.0.0.0/0
7 424 PREROUTING_ZONES_SOURCE all -- * * 0.0.0.0/0 0.0.0.0/0
7 424 PREROUTING_ZONES all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 REDIRECT tcp -- lo * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 redir ports 8080
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
3 185 OUTPUT_direct all -- * * 0.0.0.0/0 0.0.0.0/0
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
3 185 POSTROUTING_direct all -- * * 0.0.0.0/0 0.0.0.0/0
3 185 POSTROUTING_ZONES_SOURCE all -- * * 0.0.0.0/0 0.0.0.0/0
3 185 POSTROUTING_ZONES all -- * * 0.0.0.0/0 0.0.0.0/0
Chain POSTROUTING_ZONES (1 references)
pkts bytes target prot opt in out source destination
2 133 POST_public all -- * ens192 0.0.0.0/0 0.0.0.0/0 [goto]
1 52 POST_public all -- * + 0.0.0.0/0 0.0.0.0/0 [goto]
Chain POST_public (2 references)
pkts bytes target prot opt in out source destination
3 185 POST_public_log all -- * * 0.0.0.0/0 0.0.0.0/0
3 185 POST_public_deny all -- * * 0.0.0.0/0 0.0.0.0/0
3 185 POST_public_allow all -- * * 0.0.0.0/0 0.0.0.0/0
Chain PREROUTING_ZONES (1 references)
pkts bytes target prot opt in out source destination
7 424 PRE_public all -- ens192 * 0.0.0.0/0 0.0.0.0/0 [goto]
0 0 PRE_public all -- + * 0.0.0.0/0 0.0.0.0/0 [goto]
Chain PRE_public (2 references)
pkts bytes target prot opt in out source destination
7 424 PRE_public_log all -- * * 0.0.0.0/0 0.0.0.0/0
7 424 PRE_public_deny all -- * * 0.0.0.0/0 0.0.0.0/0
7 424 PRE_public_allow all -- * * 0.0.0.0/0 0.0.0.0/0
Chain PRE_public_allow (1 references)
pkts bytes target prot opt in out source destination
7 424 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x64 to::8080
输出iptables -nvL
(我已截断空链):
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
630 150K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
3 156 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
16 1069 INPUT_direct all -- * * 0.0.0.0/0 0.0.0.0/0
16 1069 INPUT_ZONES_SOURCE all -- * * 0.0.0.0/0 0.0.0.0/0
16 1069 INPUT_ZONES all -- * * 0.0.0.0/0 0.0.0.0/0
8 416 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
1 229 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
0 0 FORWARD_direct all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 FORWARD_IN_ZONES_SOURCE all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 FORWARD_IN_ZONES all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 FORWARD_OUT_ZONES_SOURCE all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 FORWARD_OUT_ZONES all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT 570 packets, 132K bytes)
pkts bytes target prot opt in out source destination
635 141K OUTPUT_direct all -- * * 0.0.0.0/0 0.0.0.0/0
Chain FORWARD_IN_ZONES (1 references)
pkts bytes target prot opt in out source destination
0 0 FWDI_public all -- ens192 * 0.0.0.0/0 0.0.0.0/0 [goto]
0 0 FWDI_public all -- + * 0.0.0.0/0 0.0.0.0/0 [goto]
Chain FORWARD_OUT_ZONES (1 references)
pkts bytes target prot opt in out source destination
0 0 FWDO_public all -- * ens192 0.0.0.0/0 0.0.0.0/0 [goto]
0 0 FWDO_public all -- * + 0.0.0.0/0 0.0.0.0/0 [goto]
Chain FWDI_public (2 references)
pkts bytes target prot opt in out source destination
0 0 FWDI_public_log all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 FWDI_public_deny all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 FWDI_public_allow all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
Chain FWDO_public (2 references)
pkts bytes target prot opt in out source destination
0 0 FWDO_public_log all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 FWDO_public_deny all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 FWDO_public_allow all -- * * 0.0.0.0/0 0.0.0.0/0
Chain INPUT_ZONES (1 references)
pkts bytes target prot opt in out source destination
16 1069 IN_public all -- ens192 * 0.0.0.0/0 0.0.0.0/0 [goto]
0 0 IN_public all -- + * 0.0.0.0/0 0.0.0.0/0 [goto]
Chain IN_public (2 references)
pkts bytes target prot opt in out source destination
16 1069 IN_public_log all -- * * 0.0.0.0/0 0.0.0.0/0
16 1069 IN_public_deny all -- * * 0.0.0.0/0 0.0.0.0/0
16 1069 IN_public_allow all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
Chain IN_public_allow (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 ctstate NEW
7 424 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate NEW mark match 0x64
答案1
通过 Linux 机器的流量可以通过以下三个钩子之一进行控制:
- 输入
- 向前
- 输出
如果进行了某种转换(如端口转发),则需要使用额外的钩子:
- 路由后
- 预路由
端口转发发生在 PREROUTING 钩子中(在 nat 表中),顾名思义它发生在路由之前。因此,从外部到本地进程的流量通过 PREROUTING,进行端口转发(目标端口从 80 更改为 8080),然后通过 INPUT 链。
然后,本地 Tomcat 通过环回接口连接到本地 nodejs,并且由于环回接口上没有端口转发规则,因此 nodejs 接收来自 Tomcat 的流量来自 8080 端口而不是 80。
底线是,本地进程使用环回接口相互通信,除非你在此接口上添加端口转发,否则连接到 localhost:80 是无法连接到任何地方的,因为 localhost:80 上没有进程在监听
答案2
我本来想把这个作为评论,但我的个人资料太新了。
这很可能是 sysctl 内核问题,而不是 iptables 问题。
尝试运行:
/sbin/sysctl net.ipv4.ip_forward
检查它是否设置为 1。
如果将其设置为零,则需要启用它运行:
sysctl -w net.ipv4.ip_forward=1
并确保您/etc/sysctl.conf
也将其设置好,以便它在重启后仍然有效。