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 端口。

iptables端口映射删除 iptables端口转发步骤_源地址

1.237 机器上连接 1.242 的 7777 端口,虽然 1.242 的 7777 端口并未被侦听,但是被转发给了处于侦听状态的 6666 端口。

 

iptables端口映射删除 iptables端口转发步骤_源地址_02

 1.237 上查看连接信息

iptables端口映射删除 iptables端口转发步骤_抓包_03

1.242 上查看连接信息

iptables端口映射删除 iptables端口转发步骤_端口转发_04

 注意 1.242 查查看到的连接信息中,端口是转发之后的端口 6666,而不是 7777.

删除该端口转发:

查看当前iptables 的 nat 表的所有规则:(不用 -t 指定表名默认的是指 filter 表)

iptables -t nat -nL --line

iptables端口映射删除 iptables端口转发步骤_iptables端口映射删除_05

删除指定表的指定链上的规则, -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 上设置:


 


  1. sysctl -w net.ipv4.ip_forward=1
  2. iptables -t nat -A PREROUTING -p tcp --dport 6666 -j DNAT --to-destination 192.168.1.8:7777
  3. iptables -t nat -A POSTROUTING -p tcp -d 192.168.1.8 --dport 7777 -j SNAT --to-source 192.168.1.168

iptables端口映射删除 iptables端口转发步骤_抓包_06

 3138 端口从后边的抓包结果中获取。

 分别在 1.168 上抓包和 1.8 上抓包:tcpdump -i virbr0 port 6666 or 7777 -w result.cap.

-i 选项指定网卡,-w 选项保存结果到文件当中。抓包的结果使用 Wireshark 查看如下。

1.168 的抓包结果:

iptables端口映射删除 iptables端口转发步骤_源地址_07

可以看到 168 收到的包被转发。因为转发发生在内核,在 1.168 转发机上,使用 ss 看不到任何与 1.6 即 1.8 的连接。

iptables端口映射删除 iptables端口转发步骤_端口转发_08

 1.8 机器上,看到的就是正常的和 1.168 建立连接并传送数据,1.8 并不知道 1.168 仅仅是转发而已。

3、将一台公网 ip 主机的端口转发到另一台公网 ip 主机

 我有两台AWS主机,一台位于伦敦,一台位于俄勒冈。红色为对应主机的公网 ip. 黑色为私网ip. 将 London 主机的 8016 端口转发到 Oregon 的 8017 端口。

iptables端口映射删除 iptables端口转发步骤_抓包_09

在 London 主机上操作:


 


  1. iptables -t nat -A PREROUTING -p tcp --dport 8016 -j DNAT --to-destination 18.222.236.211:8017
  2. iptables -t nat -A POSTROUTING -p tcp -d 18.222.236.211 --dport 8017 -j SNAT --to-source 10.53.1.49

 在 London 主机上抓包:

iptables端口映射删除 iptables端口转发步骤_iptables端口映射删除_10

注意:这里关键的地方在于 SNAT 之后的 source 地址只能是内网地址,不能 London 主机的公网地址

如果配成了 London 主机的公网地址,抓包结果如下,转发不会成功。

iptables端口映射删除 iptables端口转发步骤_抓包_11

虽然通过公网 ip 连接主机,但实际上在主机上抓包显示,数据包的目的地址都是主机的私网地址。DNAT 修改了数据包的目的地址,SNAT修改了数据包的源地址,一旦源地址被修改为本机的公网地址,该数据包将会被丢弃。