Iptables physdev模块在NAT表POSTROUTING链的配置问题(桥接环境下SNAT需求)
Iptables physdev模块在NAT表POSTROUTING链的配置问题(桥接环境下SNAT需求)
我来帮你搞定这个桥接环境下的SNAT配置问题,先理清楚你的场景和需求:
你的现有环境梳理
- 网络拓扑:
PC1 (192.168.100.1/24) - (enp6s0f0) 桥设备br0 (enp6s0f1) - PC2 (192.168.100.2/24) - 桥配置已经正确完成,br0设置为
169.254.100.1/32,PC1和PC2能正常互通,且默认不会和桥设备直接通信 - 核心需求:让PC1看到桥设备的IP是
192.168.100.100,PC2看到桥设备的IP是192.168.100.200
关键前提:开启桥接流量的iptables处理
桥接环境下,二层流量默认不会经过iptables的三层处理链(比如NAT表),所以首先要开启内核参数让iptables能接管桥接的三层流量:
echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
如果要让这个配置重启后生效,把下面的内容加到/etc/sysctl.conf里,再执行sysctl -p:
net.bridge.bridge-nf-call-iptables = 1
POSTROUTING链的SNAT规则配置
利用physdev模块匹配流量实际的物理输出接口,针对不同接口设置不同的SNAT源IP:
- 针对去往PC1的流量(从enp6s0f0接口发出),将桥的源IP替换为
192.168.100.100:
iptables -t nat -A POSTROUTING -o br0 -m physdev --physdev-out enp6s0f0 -j SNAT --to-source 192.168.100.100
- 针对去往PC2的流量(从enp6s0f1接口发出),将桥的源IP替换为
192.168.100.200:
iptables -t nat -A POSTROUTING -o br0 -m physdev --physdev-out enp6s0f1 -j SNAT --to-source 192.168.100.200
规则说明:
-o br0:指定流量从桥接口br0输出(桥设备的流量都会走这个接口,再转发到物理网卡)--physdev-out enp6s0f0:用physdev模块精准匹配实际的物理输出网卡,这样就能区分是发往PC1还是PC2的流量- SNAT动作会把桥发出的数据包源IP替换成指定地址,这样PC1/PC2收到的数据包就会显示来自你想要的IP
补充:PC主动访问桥的DNAT规则
如果需要PC1能主动访问192.168.100.100(桥的虚拟IP)、PC2能主动访问192.168.100.200,还需要添加PREROUTING链的DNAT规则:
- 处理PC1发来的访问
192.168.100.100的流量,转发到桥的实际IP:
iptables -t nat -A PREROUTING -i br0 -m physdev --physdev-in enp6s0f0 -d 192.168.100.100 -j DNAT --to-destination 169.254.100.1
- 处理PC2发来的访问
192.168.100.200的流量,转发到桥的实际IP:
iptables -t nat -A PREROUTING -i br0 -m physdev --physdev-in enp6s0f1 -d 192.168.100.200 -j DNAT --to-destination 169.254.100.1
测试验证
- 从桥设备ping PC1,在PC1上用
tcpdump抓包,应该看到源IP是192.168.100.100 - 从桥设备ping PC2,在PC2上抓包,应该看到源IP是
192.168.100.200 - 从PC1 ping
192.168.100.100,应该能正常连通桥设备
规则持久化
如果要让iptables规则重启后不丢失,可以用以下命令保存:
iptables-save > /etc/iptables/rules.v4
或者安装iptables-persistent工具来管理规则的持久化。
备注:内容来源于stack exchange,提问作者Ivashka
相关产品推荐
相关产品推荐

