绝大多数家用或动态IP场景下必须用MASQUERADE;SNAT仅适用于固定IP且维护成本高。需永久开启IPv4转发、将MASQUERADE规则插入POSTROUTING链首行、确保内网设备网关指向NAT主机,并显式放行FORWARD链流量。

iptables 的 POSTROUTING 链必须用 -j MASQUERADE 还是 SNAT?
绝大多数家用或动态 IP 场景下,MASQUERADE 是唯一安全的选择;硬写 SNAT 会导致外网流量发不出去。
-
MASQUERADE自动感知出口网卡的实时 IP(比如 DHCP 分配的公网 IP),适合拨号、4G、云主机弹性 IP 等场景 -
SNAT要求你手动写死源地址,一旦网卡 IP 变更(比如重启网络服务),NAT 规则立刻失效,且不会报错,只表现为“能 ping 通网关但上不了网” - 如果你确定出口 IP 固定(如 IDC 服务器),
SNAT性能略好(少一次查表),但维护成本高,不推荐新手碰
开启 IPv4 转发只是第一步,/proc/sys/net/ipv4/ip_forward 会被重置
临时开转发只是治标:echo 1 > /proc/sys/net/ipv4/ip_forward 下次 reboot 就回 0。
- 永久生效必须改配置文件:
/etc/sysctl.conf里加一行net.ipv4.ip_forward = 1,再执行sysctl -p - 某些发行版(如 Ubuntu 22.04+)默认启用
systemd-sysctl,但若你手动改过/etc/sysctl.d/*.conf,优先级可能冲突,建议统一用/etc/sysctl.conf - 验证是否真生效:运行
sysctl net.ipv4.ip_forward,输出必须是net.ipv4.ip_forward = 1,不能只看文件里有没有那行
iptables 规则顺序错了,NAT 就完全不工作
NAT 规则必须插在 POSTROUTING 链最前面,否则被前面的 ACCEPT 或 DROP 拦截掉,包根本到不了 NAT 层。
- 别用
iptables -A POSTROUTING ...(追加到末尾),要用iptables -t nat -I POSTROUTING 1 ...(插入第 1 行) - 典型错误:先写了
-A FORWARD -i eth0 -o eth1 -j ACCEPT,再写 NAT,结果流量在 FORWARD 链就放行了,压根不进 POSTROUTING - 检查顺序:用
iptables -t nat -L -n --line-numbers,确认MASQUERADE规则在第 1 行,且目标接口(-o)是你真正的出口网卡(比如eth0或ens3),不是内网桥接口
内网设备默认网关没指向 Linux 主机,NAT 就是摆设
Linux 做 NAT 不是“装完规则就自动接管”,内网机器必须把它的默认路由设成这台 Linux 的内网 IP。
- 比如 Linux 内网口 IP 是
192.168.100.1,那么 Windows 或手机的网关就得设成这个地址,不能是光猫或路由器的 IP - 如果内网是另一个路由器(比如 OpenWrt),得关掉它的 DHCP,或者把它设为纯交换模式,否则内网设备会从它那里拿到错误网关
- 验证方法:在内网机器上执行
ip route show default(Linux)或route print(Windows),确认默认网关确实是你的 NAT 主机内网 IP
最容易被忽略的是:NAT 规则本身没问题,但 FORWARD 链默认是 DROP,必须显式放行内网→外网的流量。很多人只加了 MASQUERADE,忘了加 iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT(假设 eth1 是内网口)。没有这条,包连转发都进不去,更别说做地址转换了。

















