linux配置nat需同时满足三条件:启用ip转发(修改sysctl.conf并加载systemd-sysctl)、正确选用masquerade或snat规则并限制源地址、确保nftables中hook与priority匹配且连接跟踪模块(nf_conntrack/nf_nat)已加载。

Linux 上配 NAT 不是“加一条规则就完事”,关键在三件事:IP 转发必须开、连接跟踪必须稳、规则链位置不能错。缺一不可,否则流量进得去出不来,或者回包直接丢弃。
ip_forward 必须显式启用,且要持久化
内核默认关闭 IPv4 转发,sysctl -w net.ipv4.ip_forward=1 只是临时生效。重启后失效是常见故障源头。
- 检查当前状态:
cat /proc/sys/net/ipv4/ip_forward—— 返回0就没开 - 立即启用:
echo 1 > /proc/sys/net/ipv4/ip_forward - 永久生效:编辑
/etc/sysctl.conf,确保有这一行:net.ipv4.ip_forward = 1,然后运行sysctl -p - 注意:某些发行版(如 RHEL/CentOS 8+)还依赖
systemd-sysctl.service,改完需确认该服务已启用并运行
iptables 的 SNAT 和 MASQUERADE 别混用
MASQUERADE 是动态 SNAT,适合出口 IP 不固定(比如 DHCP 获取的公网接口);SNAT --to-source 是静态映射,要求出口 IP 明确且稳定。选错会导致规则不生效或连接中断。
- 用
MASQUERADE(推荐新手):iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 -j MASQUERADE - 用
SNAT(适合固定 IP):iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 -j SNAT --to-source 203.0.113.5 - 别写成
-j MASQUERADE --to-source ...——MASQUERADE不接受--to-source参数,会报错Unknown arg `--to-source' - 务必限制源地址范围(如
-s 192.168.1.0/24),否则可能把本机管理流量也做了 NAT,导致 SSH 断连
nftables 配置里 hook 和 priority 必须匹配 nat 类型
nftables 的 srcnat 链不是随便起名的,它对应 Netfilter 的 POSTROUTING + snat 优先级。写成 postrouting 或漏掉 priority srcnat,规则就挂不上。
- 正确写法(必须):
type nat hook postrouting priority srcnat; - 错误写法示例:
type nat hook postrouting priority 100;—— 这个 priority 值不触发 SNAT 流程,规则无效 - 验证是否加载:
nft list table ip nat,看到 chain 名、hook、priority 三项都对才可信 - 如果用了
masquerade关键字(nftables 0.9.4+),可省略to地址:masquerade自动取出口接口主 IP
连接跟踪模块未加载会导致 SNAT 规则静默失败
SNAT 依赖 nf_conntrack 和 nf_nat 模块做状态维护。模块没加载时,iptables 命令能执行成功,但规则完全不生效,且无任何错误提示。
- 检查模块是否在位:
lsmod | grep -E 'nf_conntrack|nf_nat' - 常见缺失模块:
nf_conntrack_ipv4(IPv4)、nf_nat_masquerade_ipv4(MASQUERADE 支持) - 手动加载:
modprobe nf_conntrack、modprobe nf_nat、modprobe nf_nat_masquerade_ipv4 - 持久化加载:把模块名写入
/etc/modules-load.d/nat.conf,避免重启后丢失
最易被忽略的是连接跟踪模块的完整性 —— 它不像 iptables 命令那样报错,而是让整个 NAT 表面正常、实则空转。配完规则务必用 tcpdump -i eth1 host 8.8.8.8 抓包看源 IP 是否真被替换了,别只信 iptables -t nat -L -v 的计数器。










