关键是要确保IP转发开启、NAT规则匹配方向正确、连通性验证闭环,其中MASQUERADE或SNAT必须置于POSTROUTING链,且FORWARD链需放行内网→外网及返回流量,同时确认内网主机网关指向正确。

要解决跨子网单向通信故障(比如内网主机能 ping 通网关,但无法访问外网;或外网能收到请求却无法回包),关键不是单纯加一条规则,而是确保 IP 转发开启 + NAT 规则匹配方向 + 连通性验证闭环 同时成立。IP 伪装(MASQUERADE 或 SNAT)只是其中一环,且必须用在正确链和表中。
确认并开启内核 IP 转发
这是前提,没有它,数据包根本不会被转发,NAT 规则形同虚设:
- 临时启用:
echo 1 > /proc/sys/net/ipv4/ip_forward - 永久生效:在
/etc/sysctl.conf中添加net.ipv4.ip_forward = 1,再执行sysctl -p - 验证是否生效:
sysctl net.ipv4.ip_forward输出应为1
选择正确的 NAT 类型与链位置
NAT 表中的规则必须放在 POSTROUTING 链(路由决策之后、发出前),用于修改源地址。选 MASQUERADE 还是 SNAT,取决于出口 IP 是否固定:
-
MASQUERADE:适用于动态公网 IP(如 PPPoE 拨号、DHCP 获取的云服务器外网口)。自动取出口网卡当前 IP。
例:iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -o eth1 -j MASQUERADE -
SNAT:适用于静态公网 IP。显式指定转换后的源地址,性能略优、映射更稳定。
例:iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -o eth1 -j SNAT --to-source 203.0.113.50
⚠️ 注意:-s 指定的是“需要被伪装”的内网源网段;-o 必须是通往外网的出口网卡(如 eth1、ppp0),不能写错。
检查 FORWARD 链是否放行
NAT 只改地址,不控制是否允许转发。若 filter 表的 FORWARD 链默认拒绝,即使伪装成功,包也会被 DROP:
- 允许内网→外网转发:
iptables -A FORWARD -i eth0 -o eth1 -s 192.168.10.0/24 -j ACCEPT - 允许响应包返回(状态跟踪):
iptables -A FORWARD -i eth1 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT - 可选:设置 FORWARD 默认策略为 DROP,再明确放行,更安全
验证与排错要点
单向通信失败,常卡在以下环节:
- 从内网主机 traceroute 到外网地址,看是否卡在网关(说明转发未生效或 FORWARD 拦截)
- 在网关上抓包:
tcpdump -i eth0 src 192.168.10.100(确认内网包进来)tcpdump -i eth1 src 203.0.113.50(确认伪装后包发出) - 检查 iptables 规则顺序:
iptables -t nat -L -n -v和iptables -L FORWARD -n -v,看命中计数是否增长 - 确认内网主机网关已指向该 Linux 网关的内网 IP(如 192.168.10.1)

















