我有一个提供服务的节点服务器localhost:90
,我们需要将机器内部的所有 curl 调用直接引导168.92.168.92
到localhost:90
。
如何实现?这会使用 iptables 吗?
我尝试了 OUTPUT 和 PREROUTING,但请求连接失败。
Chain PREROUTING (policy ACCEPT 3339 packets, 200K bytes)
num pkts bytes target prot opt in out source destination
1 0 0 DNAT tcp -- 168.92.168.92 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:127.0.0.1:90
Chain INPUT (policy ACCEPT 3339 packets, 200K bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 6220 packets, 652K bytes)
num pkts bytes target prot opt in out source destination
1 0 0 DOCKER all -- * * 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
2 0 0 DNAT tcp -- * * 168.92.168.92 0.0.0.0/0 tcp dpt:80 to:127.0.0.1:90
输出:
# curl -v http://168.92.168.92/hello
* About to connect() to 168.92.168.92 80 (#0)
* Trying 168.92.168.92... Connection refused
* couldn't connect to host
* Closing connection #0
curl: (7) couldn't connect to host
Curl directly to the server on localhost:90 works, but curl on 168.92.168.92 does not.
我错过了什么?
编辑:
iptables-save
:
# Generated by iptables-save v1.4.7 on Fri Aug 16 17:21:40 2019
*nat
:PREROUTING ACCEPT [51:3060]
:INPUT ACCEPT [51:3060]
:OUTPUT ACCEPT [99:10310]
:POSTROUTING ACCEPT [100:10370]
[0:0] -A PREROUTING -i 168.92.168.92.168 -p tcp -m tcp --dport 80 -j DNAT --to-destination 127.0.0.1:90
[1:60] -A OUTPUT -d 168.92.168.92.168/32 -j DNAT --to-destination 127.0.0.1
COMMIT
# Completed on Fri Aug 16 17:21:40 2019
# Generated by iptables-save v1.4.7 on Fri Aug 16 17:21:40 2019
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [2280:3167420]
:DOCKER - [0:0]
:DOCKER-ISOLATION - [0:0]
[1165:209934] -A INPUT -p udp -j ACCEPT
[12303:3865350] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
[0:0] -A INPUT -p icmp -j ACCEPT
[24:1440] -A INPUT -i lo -j ACCEPT
[653:39180] -A INPUT -p tcp -m state --state NEW -m tcp --dport 1:65535 -j ACCEPT
[0:0] -A INPUT -p udp -m udp --dport 15050 -j ACCEPT
[0:0] -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
[1:40] -A INPUT -j DROP
[0:0] -A FORWARD -d 127.0.0.1/32 -p tcp -m tcp --dport 90 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
COMMIT
# Completed on Fri Aug 16 17:21:40 2019
答案1
需要使用iptables
nat表REDIRECT
操作:
iptables -t nat -A PREROUTING --proto tcp --dport 80 -j REDIRECT --to-ports 90
这会将任何传入数据包(从另一个系统的网络接口传入)重定向到 tcp 端口 80 到本地主机端口 90。
对于传入的数据包来说这没问题,但对于本地生成的数据包(在同一系统上),我认为不可能将它们重定向到端口 90。
答案2
检查filter/INPUT
链。最好使用iptables-save -c
命令列出完整规则集。tcp://127.0.0.1:90
应该接受数据包。
然后检查规则的计数器DNAT
。运行 curl 时,它应该会增加。
到DNAT
localhost( 127.0.0.1
) 需要启用route_localnet
sysctl 变量。编辑该/etc/sysctl.conf
文件,然后执行sysctl -p
命令。
net.ipv4.conf.all.route_localnet = 1
更新
从问题的更新中,你可以看到 DNAT 规则正在起作用,nat/OUTPUT
因为计数器不为零。最好让这个规则更具体一些。例如
iptables -t nat -I OUTPUT -d 168.92.168.92 -p tcp --dport 80 -j DNAT --to 127.0.0.1:90
然后检查实际的路线决策
ip route get 127.0.0.1 from <src>
还可以用命令检查路由规则ip rule list
。
下一步是添加规则以记录来自防火墙的数据包:
iptables -I INPUT 1 -d 127.0.0.1 -p tcp --dport 90 -j NFLOG --nflog-group 10
iptables -I INPUT 2 -d 127.0.0.1 -p tcp --dport 90 -j ACCEPT
并运行tcpdump -ni nflog:10
命令来捕获这些数据包。
使用新信息更新问题,完成这些步骤后您将得到什么。