设想
ClientA和ClientB都通过VPN连接到ServerA
目标
ClientA 通过 ServerA 进入 Internet 的所有流量都应使用公网 IP 192.0.2.1
,ClientB 也应使用公网 IP192.0.2.2
设置
我的配置是一台服务器和四个客户端,我想通过 ServerA 路由所有流量。
VPN IP | |
---|---|
服务器A | 10.0.0.1(192.0.2.1 和 192.0.2.2(公共 IP)) |
客户A | 10.0.0.2 |
客户端B | 10.0.0.3 |
规则
我通过以下方式添加了这些规则iptables
:
iptables -t nat -A POSTROUTING -s 10.0.0.2/22 -o eth0 -j SNAT --to 192.0.2.1
iptables -t nat -A POSTROUTING -s 10.0.0.3/22 -o eth0 -j SNAT --to 192.0.2.2
配置工作正常,但所有流量都会转换192.0.2.1
为两个客户端的 IP,即使我指定每个客户端通过某个公共 IP 出去。
说实话,我不知道我想要的是否有可能实现,但如果可以实现,会是什么样子。
在防火墙地址匹配的上下文中,
-s 10.0.0.2/22
和 的-s 10.0.0.3/22
工作方式类似于-s 10.0.0.0/22
,即掩码显示要分析的位数,并且.2
此处.3
不分析和 。这些未使用的部分实际上在添加到防火墙之前被剥离:请注意如何
.2
默默地转换为.0
.使用 运行这些命令后检查您的规则iptables-save
,您会发现您创建了两个具有完全相同匹配的规则,因此只有第一个有机会触发!如果您想要匹配这些地址而不是整个子网,则不需要指定掩码(即使用掩码
/32
):更新:防火墙规则按顺序处理。第一个匹配的规则终止链处理。因此,如果您想要有一个“默认”NAT 设置并为有限数量的客户端“覆盖”它,请首先放置“覆盖”规则,然后将“默认”规则放在最后,并进行足够广泛的匹配:
这将
192.0.2.1
作为匹配所有客户端的“默认”设置。大多数没有.22
或.44
不会被前两条规则匹配的客户,将被第三条规则翻译。特殊客户端.22
和.44
也会与最后一条规则匹配,但有专门针对它们的规则,这些规则发生在链的早期192.0.2.2
并将它们转换为,因此处理不会到达最后一条规则。您可以使用
-I
操作将规则插入到填充链中的任意位置(而-A
始终附加到链的末尾)。例如,您可以在前面的所有最后一条规则之上添加另一个覆盖:这会将新规则置于第三位,将全能规则移至第四位。通常,由于覆盖之间的顺序并不重要,因此您总是将它们放在第一位;这里唯一的要求是将新规则置于广泛匹配的“默认”规则之上。
为了完整起见,我将解释如何在防火墙中正确使用掩码。
如果您可以控制客户端 IP 地址分配,则可以将应以类似方式映射的客户端分组到块中。然后使用掩码来匹配块。以下将把 IP 地址
10.0.0.32÷.63
(含)转换为192.0.2.1
和:10.0.0.64÷.95
192.0.2.2
上面的示例将客户端分配到 32 个地址的块中,对应于 mask
/27
=255.255.255.224
。请注意,这些掩码与为客户端本身分配地址时使用的网络掩码无关;这些发挥着不同的作用。此外,块的“第一个和最后一个”地址可以在客户端系统上使用,因为这些块不用作子网,而仅用于防火墙匹配,因为您的子网是诸如等地址不发挥任何特殊作用的10.0.0.0/22
地方。.32
.63
如果你不能将客户端分组到这样的块中,你可以使用
ipset
和相应的匹配来静态分配客户端。首先为每个传出 IP 创建一个专用的 IP 集:添加与相应集匹配的 NAT 规则,而不是上面的规则:
现在,您将客户端添加到相应的集合中,它们将被 NAT 到相应的 IP:
地址块也可以用作集合的成员,因此这是最通用的方法。阅读手册页以了解如何使用它们。