SNAT(Source Network Address Translation,源地址转换)是Linux防火墙的一种地址转换操作,也是iptables命令中的一种数据包控制类型,其作用是根据指定条件修改数据包的源IP地址。
1.1、SNAT策略概述
随着Internet网络在全世界范围内的快速发展,Ipv4协议支持的可用IP地址资源逐渐
变得山穷水尽,资源匮乏使得许多企业难以申请更多的公网IP地址,或者只能承受一个或者少数几个公网IP地址的费用。而与此同时,大部分企业都面临着将局域网内的主机接入Internet的需求。
通过在网关中应用SNAT策略,可以解决局域网共享上网的问题。下面以一个小型的企业网络为例,Linux网关服务器通过两块网卡eth0、eth1分别连接Internet和局域网,如图所示,分析局域网主机访问Internet的情况。
1、 只开启路由转发,未做地址转换的情况
正常情况下,作为网关的Linux服务器必须打开路由转发,才能沟通多个网络。未使用地址转换策略时,从局域网PC机访问Internet的数据包经过网关转发后其源IP地址保持不变,当Internet中的主机收到这样的请求数据包后,响应数据包将无法正确返回(私有地址不能再Internet中正常路由),从而导致访问失败。
2、开启路由转发,并设置SNAT转发的情况
如果在网关服务器中正确应用SNAT策略,数据包转发情况就不一样了,当局域网PC机访问Internet的数据包到达网关服务器时,会先进行路由选择,若发现该数据包需要从外网接口(如:eth0)向外网转发,则将其源IP地址(如:192.168.1.234)修改为网关外网接口地址(如:218.29.30.31),然后才发送给目标主机(如:58.63.236.45)。相当于从网关服务器的公网IP地址提交数据访问请求,目标主机也可以正确返回响应数据包,最终实现局域网PC机共享同一个公网IP地址接入Internet。
在上述SNAT转换地址的过程中,网关服务器会根据之前建立的SNAT映射,将响应数据包正确返回给局域网中的源主机。因此只要连接的第一个包被SNAT处理了,那么这个连接及对应数据流的其他包也会自动地被进行SNAT处理。另一方面,Internet中的服务器并不知道局域网PC机的实际IP地址,中间的转换完全由网关主机完成,一定程度上也起到了保护内部网络的作用。
1.2、SNAT策略的应用
SNAT的典型应用是为局域网共享上网提供接入策略,处理数据包的切入时机是在路由选择之后(POSTROUTING)进行。关键操作在于将局域网外发数据包的源IP地址(私有地址)修改为网关服务器的外网接口IP地址(公有地址)。
SNAT策略只能用在nat表的POSTROUTING链,使用iptables命令编写SNAT策略时,需要结合“—to-source ip地址”选项来制定修改后的源IP地址(例如:-j SNAT –to-source 218.29.30.31)。下面通过俩个实例来说明SNAT策略的具体用法。
1、 共享固定IP地址上网
案例环境如图所示,需求描述如下:
1) Linux网关服务器通过两块网卡eth0、eth1分别连接Internet和局域网,其中eth0的IP地址为218.29.30.31,eth1的IP地址为192.168.1.1。
2) 所有局域网PC机的默认网关为192.168.1.1,且已经设置了正确的DNS服务器。
3) 要求192.168.1.0/24网段的PC机能够通过共享方式正常访问Internet。
实验步骤:
(1)打开网关的路由转发
[root@localhost ~]# vi /etc/sysctl.conf net.ipv4.ip_forward = 0 //将此行配置中的0改为1 [root@localhost ~]# sysctl –p //读取修改后的配置 |
在测试过程中,若只希望临时开启路由转发,也可以执行以下操作。
[root@localhost ~]# echo 1 > /proc/sys/net/ipv4/ip_forward |
或者
[root@localhost ~]# sysctl -w net.ipv4.ip_forward=1 net.ipv4.ip_forward = 1 |
(2)正确设置SNAT策略。
通过分析得知,需要针对局域网PC机访问Internet的数据包采取SNAT策略,将源地址更改为网关的公网IP地址,参考一下操作在网关中设置防火墙规则。若要保持SNAT策略长期有效,应将相关命令写入到rc.local配置文件,以便开机后自动设置。
[root@localhost ~]# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 218.29.30.31 |
(3)测试SNAT共享接入结果。
上述操作完成以后,使用局域网中的PC机就可以正常访问Internet中的网站了。对于被访问的网站服务器来说,将会以为是网关主机218.29.30.31在访问(可观察Web日志获知),而并不知道实际上是企业内网的PC机在访问。
2、 共享动态IP地址上网
在某些情况下,网关的外网IP地址可能并不是固定的,例如使用ADSL宽带接入时。那么在这种网络环境下,应该如何设置SNAT策略呢?针对这种需求,iptables提供了一个名为MASQUERADE(伪装)的数据包控制类型,MASQUERADE相当于SNAT的一个特例,同样用来修改(伪装)数据包源IP地址,只不过它能够自动获取外网接口的IP地址,而无需使用“—to-source“指定固定的IP地址。
参照上一个SNAT案例,若要使用MASQUERADE伪装策略,只需去掉SNAT策略中的“—to-source IP地址“,然后改用“-j MASQUERADE”指定数据包控制类型。对于ADSL宽带连接来说,连接名称同城为ppp0、ppp1等。
[root@localhost ~]# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ppp0 -j MASQUERADE |
当然,如果网关使用固定的公网IP地址,最好还是选择SNAT策略而不是MASQUERADE策略,以减少不必要的系统开销。
MASQUERADE这个target和SNAT target的作用是一样的,区别就是它不需要指定--to-source 。MASQUERADE是被专门设计用于那些动态获取IP地址的连接的,比如,拨号上网、DHCP连接等。如果你有固定的IP地址,还是用SNAT target吧。
MASQUERADE和SNAT一样,只能用于nat表的 POSTROUTING链,而且它只有一个选项(不是必需的):
MASQUERADE target
Option --to-ports
Example iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 1024-31000
Explanation 在指定TCP或UDP的前提下,设置外出包能使用的端口,方式是单个端口,如--to-ports 1025,或者是端口范围,如--to- ports 1024-3000。注意,在指定范围时要使用连字号。这改变了SNAT中缺省的端口选择,详情请查看 SNAT target。
SNAT target
Option --to-source
Example iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to-source 194.236.50.155-194.236.50.160:1024-32000
Explanation 指定源地址和端口,有以下几种方式:
1、单独的地址。
2、一段连续的地址,用连字符分隔,如194.236.50.155-194.236.50.160,这样可以实现负载平衡。每个流会被随机分配一个IP,但对于同一个流使用的是同一个IP。
3、在指定-p tcp 或 -p udp的前提下,可以指定源端口的范围,如194.236.50.155:1024-32000,这样包的源端口就被限制在1024-32000了。
注意,如果可能,iptables总是想避免任何的端口变更,换句话说,它总是尽力使用建立连接时所用的端口。但是如果两台机子使用相同的源端口,iptables 将会把他们的其中之一映射到另外的一个端口。如果没有指定端口范围, 所有的在512以内的源端口会被映射到512以内的另一个端口,512和1023之间的将会被映射到 1024内,其他的将会被映射到大于或对于1024的端口,也就是说是同范围映射。还要注意,这种映射和目的端口无关。