使用iptables配置NAT

1,092 阅读4分钟

一、SNAT 和 DNAT是什么

本文使用的是操作系统是Linux,配置工具是iptables。

相关概念的描述

1. Source NAT (SNAT)

源地址转换,改写数据包的源地址, 目的地址保持不变。常使用的场景有:

  • 多台内网机器使用同一个公网IP上网的
  • 将服务器的源IP隐藏,改成公开的IP

配置的命令:iptables -t nat -A POSTROUTING -p tcp --dport 1233 -j SNAT --to 192.168.0.1

命令详解如下:

-t nat : 配置的是nat表,-t指定了nat表
-A POSTROUTING:A代表的是append,增加一个POSTROUTING的chain
-p tcp --dport 1233 代表的是匹配到的数据包的特征,使用tcp协议,目的端口号是1233号
-j 表示的是action,该action就是进行源地址转换
--to 192.168.0.1转换成192.168.0.1的源地址,源端口号不变

2. Destination NAT (DNAT) 目的地址转化,对数据包的目的地址进行修改,其源地址保持不变。常使用的场景:

  • 端口映射,对数据包进行转发到指定的地址
  • 隐藏后端服务的真实地址,用户访问公开的地址,由NAT服务进行转发
    配置的命令:iptables -t nat -A PREROUTING -p tcp --dport 1233 -j DNAT --to-destination 127.0.0.1:6543
    命令详解如下:

-t nat : 配置的是nat表,
-t指定了nat表
-A PREROUTING:A代表的是append,添加一个PREROUTING的chain
-p tcp --dport 1233 代表的是匹配到的数据包的特征,使用tcp协议,目的端口号是1233号
-j 表示的是action,DNAT就是进行目的地址转换
--to-destination 127.0.0.1:6543: IP地址改成127.0.0.1,端口号改成6543

补充: SNAT 要在POSTROUTING链添加, DNAT需要再PREROUTING链添加。关于POSTROUTING和PREROUTING的区别,以及iptables的相关原理会在后面文章中详述。

二、 实际应用场景

​ 上面对SNAT和DNAT的原理以及命令配置做了简单的描述,各位可能还不知道NAT的在工作中可以应用的场景。以下列举实际工作中会遇到的场景。

​ 场景: Server A 运行着一个服务s1,只开放的本地地址连接,开放的端口号是6543。即Server A的服务s1监听的端口是127.0.0.1:6543。本地客户端Client想连接到服务s1去,这时可以修改s1的配置文件,让其监听所有的地址。也可以使用iptables配置NAT,使得可以访问6543的端口。

​ 解决方案1:在Server A中执行iptables -t nat -A PREROUTING -p tcp --dport 1233 -j DNAT --to-destination 127.0.0.1:6543,让连接到Server A的1233的端口转发到本地的6543端口上去,完成了NAT的映射。

​ 模拟操作步骤:

  1. step1: Server A执行 nc -l -p 6543 监听本地的6543端口
  2. step2: Server A执行 iptables -t nat -A PREROUTING -p tcp --dport 1233 -j DNAT --to-destination 127.0.0.1:6543 进行地址映射
  3. step3: 在Clinet 所在的机器访问Server A的1233端口,假设Server A的公网IP是22.23.34.1,nc 22.23.34.1 1233
  4. step4: 在Client建立连接后,输入几个字符,在Server A监听的6543端口上有显示即可。

​ 解决方案2:

  1. iptables -t nat -A PREROUTING -p tcp --dport 5000 -j REDIRECT --to-ports 6543

使用REDIRECT的action,直接将Server A的5000端口数据转发到本地的6543端口中去。

上述提到的两个解决方案,在本地验证是通过不了的。即Server A和Client 都是同一台机器,因为使用lo网卡的时候,是没有PREROUTING这个阶段的,如果一定要在本地进行NAT的验证。可以使用此命令:iptables -t nat -I OUTPUT -p tcp -o lo --dport 1232 -j REDIRECT --to-ports 6543 。此命令是设置了,lo网卡的数据包的目的端口是1232的时候,转发到6543端口去。使用的是OUTPUT,因此从外部访问Server A的1232端口的话,不会转发的6543端口去,一定要是本地访问本地的时候才行。

##三、 后记

  1. 使用上述的NAT功能前,一定要先开启linux nat转发的功能:echo 1 > /proc/sys/net/ipv4/ip_forward ,重启后失效,如果需要重启后还开启,需要写到/etc/rc.local中去
  2. 上述提到的场景,可扩展为Server A的1233端口,转发到Server B(假设地址是8.8.8.8)的6543端口中去,Server A的角色是一个跳板,只要修改一下命令:把iptables -t nat -A PREROUTING -p tcp --dport 1233 -j DNAT --to-destination 127.0.0.1:6543 改成 iptables -t nat -A PREROUTING -p tcp --dport 1233 -j DNAT --to-destination 8.8.8.8:6543