Linux网络的SNAT和DNAT
作者:杨冬 欢迎转载,也请保留这段声明。谢谢!
出处:https://andyyoung01.github.io/ 或 http://andyyoung01.16mb.com/
NAT全名是Network Address Translation,字面上的意思是网络地址转换,它还可以分为SNAT(Source Network Address Translation,源地址转换)和DNAT(Destination Network Address Translation,目的地址转换)。SNAT主要是用来做默认网关的,而DNAT主要是用来做端口映射的。
本篇就来简单看看在Linux系统上的SNAT和DNAT的配置。
背景知识
Linux的NAT可以通过iptables配置实现。下图是一个简化的网络数据包在Linux主机中iptables各个表中处理的过程。为了简单,在该图中只标出了iptables中表filter和nat的链:
在任何一个IP数据包中,都会有Source IP Address与Destination IP Address这两个字段,数据包所经过的Linux路由器主机也是根据这两个字段是判定数据包是由什么地方发过来的,它要将数据包发到什么地方去。而iptables的DNAT与SNAT就是根据这个原理,对Source IP Address与Destination IP Address进行修改。
SNAT主要是用来给内网的主机提供连接到Internet的默认网关,借用鸟哥的图:
如上图,SNAT操作的是iptables中NAT表的Postrouting链,将ip包的源地址替换为网关的公网地址。
DNAT可以将内网机器的端口映射到外网上面,仍然借用鸟哥的图:
如上图,DNAT操作的是iptables中NAT表的Prerouting链,将ip包的目的地址替换为内网要映射端口的主机地址。
所以,NAT服务器一定是路由器,因为NAT服务器一定进行了数据包的转发。
配置
开启内核数据包转发
从上面的背景知识可知,要配置NAT,必须开启Linux内核的转发功能:
echo 1 > /proc/sys/net/ipv4/ip_forward #临时生效,重启失效
要永久生效,需要:
vi /etc/sysctl.conf
修改其中的net.ipv4.ip_forward = 1
。
然后执行:
syscty -p
立刻生效。
加入NAT相关模块
由于NAT是通过内核的nat模块提供的,而内核的iptable_nat模块默认是没有加载的,通过如下命令手动加载该模块:
modprobe iptable_nat
不过,后面在进行iptables操作时,-j SNAT或-j MASQUERSDE及-j DNAT会自动加载iptable_nat内核模块。这里如果没有手动加载,后面的操作也会将该模块自动加载上。
检查iptables是否允许转发
从第一张图可以知道,如果数据包需要进行转发,还要通过iptables中filter表的FORWARD链。所以需要确保iptables规则中FORWARD链可以转发相应的数据包。可以通过如下命令确认:
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
从上面命令的输出可以看出,FORWARD链默认规则是ACCEPT,而且它没有设置其它规则,所以数据包是可以通过FORWARD链的。如果FORWARD链的默认规则为DROP或REJECT,需要在FORWARD链中再添加相关规则以允许相应的数据包通过。
配置SNAT
假如在NAT机器上,想要将192.168.1.0/24网段的数据包的源地址修改为公网的ip58.20.51.66,通过端口eth送出,可以:
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 -j SNAT --to-source 58.20.51.66
另外一种方法:
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 -j MASQUERADE
配置DNAT
假如需要将对外网ip202.103.96.112网口eth1的访问,映射到对内网ip192.168.0.112的访问;
iptables -t nat -A PREROUTING -i eth1 -p tcp -d 202.103.96.112 --dport 80 -j DNAT --to-destination 192.168.0.112:80