iptables实现不连续地址的SNAT

想要从内网直接去访问外网的服务器肯定是不可能的,因为互联网中的机器都是公网通信,它看到内网来源后不知道该响应给谁,这就要用到源地址转换。源地址转换实质上就是把要出去的数据包中的源地址做了修改。

Linux 上基于 iptables 可实现源地址转换,即 SNAT。一般情况下一台主机配置一个公网 IP 就可以了,但是在有些场合因为业务需要,机器上要配置多个地址,这些地址可能是连续的,不连续的,一部分连续,一部分不连续,针对不同的情况,做 SNAT 也不同。

网卡上只有一个 IP 直接 SNAT 即可

1
2
# eth1 111.161.126.234
iptables -t nat -I POSTROUTING -o eth1 -s 192.168.0.0/16 -j SNAT --to 111.161.126.234

网卡上有在同一个子网的多个连续的 IP

1
2
3
4
5
eth0 111.161.74.179
eth0 111.161.74.180
eth0 111.161.74.181
eth0 111.161.74.182
eth0 111.161.74.183

这种情况可以选择其中一个 IP 做 SNAT,但是既然已经有这么多 IP 了就应该充分利用资源。使用 - 可以在 SNAT 的时候指定连续的 IP 范围,这样能够达到某种负载均衡的效果

1
iptables -t nat -I POSTROUTING -o eth0 -s 192.168.0.0/16 -j SNAT --to 111.161.74.179-111.161.74.183

网卡上的 IP 都在同一子网,但是都不连续

1
2
3
eth0 111.32.133.22
eth0 111.32.133.25
eth0 111.32.133.29

这种情况在 CentOS 5 上可以使用 SAME 和多个 --to 来达到上面的 SNAT 效果

1
iptables -t nat -I POSTROUTING -o eth0 -s 192.168.0.0/16 -j SAME --to 111.32.133.22 --to 111.32.133.25 --to 111.32.133.29

但是 CentOS 5 的系统已经很少使用了,并且高版本的系统也不支持这种写法了。要解决这个问题,可以使用 state 模块和 statistic 来根据连接状态做负载均衡。既然是 3 个不连续的地址,我们就可以视为 3 个要 SNAT 的对象,根据这个来匹配 NEW 状态的数据包,匹配到的数据包中每 3 个数据包作为一个循环体,其中第 1 个数据包 SNAT 到第 1 个 IP,第 2 个数据包 SNAT 到第 2 个 IP,以此类推,当前循环体操作完之后将操作下一个循环体的 3 个数据包。要注意一下,我们人所说的第 1 个,在计算机上是从 0 开始的。如果到最后还是没有被匹配到,就 SNAT 到其中任意一个 IP ,这个规则就相当于是默认的 SNAT 规则。

1
2
3
4
5
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/16 -m state --state NEW -m statistic --mode nth --every 3 --packet 0 -j SNAT --to 111.32.133.22
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/16 -m state --state NEW -m statistic --mode nth --every 3 --packet 1 -j SNAT --to 111.32.133.25
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/16 -m state --state NEW -m statistic --mode nth --every 3 --packet 2 -j SNAT --to 111.32.133.29
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/16 -j SNAT --to 111.32.133.22
# 默认 SNAT 规则

同一子网部分连续

1
2
3
eth1 42.81.58.226
eth1 42.81.58.227
eth1 42.81.58.230

这种情况我们可以把连续的 IP 当做一个 SNAT 对象,这样就是两个 SNAT 对象。同样还是按照上面的方法处理

1
2
3
4
iptables -t nat -A POSTROUTING -o eth1 -s 192.168.0.0/16  -m state --state NEW -m statistic --mode nth --every 2 --packet 0 -j SNAT --to 42.81.58.226-42.81.58.227
iptables -t nat -A POSTROUTING -o eth1 -s 192.168.0.0/16 -m state --state NEW -m statistic --mode nth --every 2 --packet 1 -j SNAT --to 42.81.58.230
iptables -t nat -A POSTROUTING -o eth1 -s 192.168.0.0/16 -j SNAT --to 42.81.58.226-42.81.58.227
# 默认 SNAT 规则

不同子网都是连续

1
2
3
4
5
6
7
8
9
10
11
eth2 220.181.122.74
eth2 220.181.122.75
eth2 220.181.122.76
eth2 220.181.122.77
eth2 220.181.122.78
# -------------------
eth2 111.202.106.82
eth2 111.202.106.83
eth2 111.202.106.84
eth2 111.202.106.85
eth2 111.202.106.86

还是一样,连续的 IP 当做一个 SNAT 对象

1
2
3
4
iptables -t nat -A POSTROUTING -o eth2 -s 192.168.0.0/16  -m state --state NEW -m statistic --mode nth --every 2 --packet 0 -j SNAT --to 220.181.122.74-220.181.122.78  
iptables -t nat -A POSTROUTING -o eth2 -s 192.168.0.0/16 -m state --state NEW -m statistic --mode nth --every 2 --packet 1 -j SNAT --to 111.202.106.82-111.202.106.86
iptables -t nat -A POSTROUTING -o eth2 -s 192.168.0.0/16 -j SNAT --to 220.181.122.74-220.181.122.78
# 默认 SNAT 规则
有钱任性,请我吃包辣条
0%