我希望每个源 IP(我有很多)都始终具有相同的 SNAT(我有两个。对我来说,第一次可以随机分配)。
例如:
10.0.0.1 > 8.0.0.1
10.0.0.2 > 8.0.0.2
10.0.0.3 > 8.0.0.1
10.0.0.4 > 8.0.0.2
10.0.0.1 > 8.0.0.1
10.0.0.2 > 8.0.0.2
等等。
有可能的?
答案1
显然-j SNAT --persistent
仅适用于源/目标对,因此当连接到不同的目的地时,不能保证将使用相同的源。
相反,来自man iptables-extensions
:
u32
U32 测试从数据包中提取的最多 4 个字节的数量是否具有指定值。提取内容的规范足够通用,可以从 tcp 标头或有效负载中找到给定偏移量的数据。
只要您想要转换后正好有 2^n 个 IP(这里您想要 2 个,所以没问题),那么只需检查原始 IP 模 2^n 的末尾并从结果中执行选择性 SNAT,就可以轻松仅使用 2^n(这里是 2)规则。解决方案如下:
iptables -t nat -I POSTROUTING -s 10.0.0.0/16 ! -d 10.0.0.0/16 -m u32 --u32 '12 & 0x1 = 0x1' -j SNAT --to-source 8.0.0.1
iptables -t nat -I POSTROUTING -s 10.0.0.0/16 ! -d 10.0.0.0/16 -m u32 --u32 '12 & 0x1 = 0x0' -j SNAT --to-source 8.0.0.2
12 是数据包中源 IP 地址的位置
如果需要,请将 -I 替换为 -A,并将所有 /16(您说的很多!)替换为任何其他大小。
如果您事先不知道目标 IP(8.0.0.1 和 8.0.0.2),那么您当然必须在脚本中使用一些变量来替换这些值(8.0.0.1 和 8.0.0.2)
如果您有 4 个可用的公共 IP,则可以将掩码更改& 0x1
为& 0x3
,并使用总共 4 个 SNAT,每个 SNAT 对应 4 个可能的结果 1 2 3 0 。 依此类推...
由于没有等效的目标扩展规则,因此使用 iptables 对目标 IP 进行“通用”转换以便在唯一规则中直接使用测试结果似乎是不可能的。
答案2
我让bpf匹配取模操作用于划分任意数量的外部 IP
像这样ip % 3 == 2
这个 bash 代码
#!/bin/bash
mod=7
src_ip_mod (){
eq=$1
echo "15,48 0 0 0,84 0 0 240,21 0 11 64,32 0 0 12,2 0 0 1,52 0 0 ${mod},7 0 0 5,0 0 0 ${mod},44 0 0 0,7 0 0 5,96 0 0 1,28 0 0 0,21 0 1 ${eq},6 0 0 65535,6 0 0 0"
}
mod=3
iptables -t nat -A POSTROUTING -m bpf --bytecode "`src_ip_mod 0`" -j SNAT --to-source 8.0.0.1
iptables -t nat -A POSTROUTING -m bpf --bytecode "`src_ip_mod 1`" -j SNAT --to-source 8.0.0.2
iptables -t nat -A POSTROUTING -m bpf --bytecode "`src_ip_mod 2`" -j SNAT --to-source 8.0.0.3