iptables 端口转发
ssh 也能实现本机的端口转发,只不过原来的 1 条连接会变成 3 条。详情见前一篇 ssh 端口转发博文。而 iptables 的端口转发则是在内核进行。
1、将本地的端口转发到本机端口
将本机的 7777 端口转发到 6666 端口。
iptables -t nat -A PREROUTING -p tcp --dport 7777 -j REDIRECT --to-port 6666
1.242 机器上将 7777 端口转发到 6666,并侦听 6666 端口。
1.237 机器上连接 1.242 的 7777 端口,虽然 1.242 的 7777 端口并未被侦听,但是被转发给了处于侦听状态的 6666 端口。
1.237 上查看连接信息
1.242 上查看连接信息
注意 1.242 查查看到的连接信息中,端口是转发之后的端口 6666,而不是 7777.
删除该端口转发:
查看当前iptables 的 nat 表的所有规则:(不用 -t 指定表名默认的是指 filter 表)
iptables -t nat -nL --line
删除指定表的指定链上的规则, -D 并指定序号即可。
iptables -t nat -D PREROUTING 1
*说明:PREROUTING链修改的是从外部连接过来时的转发,如果本机连接到本机的转发,需要修改 OUTPUT链。
iptables -t nat -A OUTPUT -p tcp --dport 7777 -j REDIRECT --to-port 6666
2、将本机的端口转发到其他机器
通过 1.168 的 6666 端口访问 1.8 的 7777 端口,在 1.168 上设置:
-
sysctl -w net.ipv4.ip_forward=1
-
iptables -t nat -A PREROUTING -p tcp --dport 6666 -j DNAT --to-destination 192.168.1.8:7777
-
iptables -t nat -A POSTROUTING -p tcp -d 192.168.1.8 --dport 7777 -j SNAT --to-source 192.168.1.168
3138 端口从后边的抓包结果中获取。
分别在 1.168 上抓包和 1.8 上抓包:tcpdump -i virbr0 port 6666 or 7777 -w result.cap.
-i 选项指定网卡,-w 选项保存结果到文件当中。抓包的结果使用 Wireshark 查看如下。
1.168 的抓包结果:
可以看到 168 收到的包被转发。因为转发发生在内核,在 1.168 转发机上,使用 ss 看不到任何与 1.6 即 1.8 的连接。
1.8 机器上,看到的就是正常的和 1.168 建立连接并传送数据,1.8 并不知道 1.168 仅仅是转发而已。
3、将一台公网 ip 主机的端口转发到另一台公网 ip 主机
我有两台AWS主机,一台位于伦敦,一台位于俄勒冈。红色为对应主机的公网 ip. 黑色为私网ip. 将 London 主机的 8016 端口转发到 Oregon 的 8017 端口。
在 London 主机上操作:
-
iptables -t nat -A PREROUTING -p tcp --dport 8016 -j DNAT --to-destination 18.222.236.211:8017
-
iptables -t nat -A POSTROUTING -p tcp -d 18.222.236.211 --dport 8017 -j SNAT --to-source 10.53.1.49
在 London 主机上抓包:
注意:这里关键的地方在于 SNAT 之后的 source 地址只能是内网地址,不能 London 主机的公网地址。
如果配成了 London 主机的公网地址,抓包结果如下,转发不会成功。
虽然通过公网 ip 连接主机,但实际上在主机上抓包显示,数据包的目的地址都是主机的私网地址。DNAT 修改了数据包的目的地址,SNAT修改了数据包的源地址,一旦源地址被修改为本机的公网地址,该数据包将会被丢弃。
转载至https://blog.****.net/zhouguoqionghai/article/details/81947603