iptables实现nat的本质是在netfilter框架中通过prerouting和postrouting链重写ip地址与端口,并依赖conntrack表保障双向通信;snat在postrouting链修改源ip以实现内网共用公网出口,dnat在prerouting链修改目的ip以将公网请求转发至内网服务。

iptables 实现 NAT 的本质,是在 Linux 内核 netfilter 框架中,通过特定链(prerouting、postrouting)对进出数据包的 IP 地址和端口进行重写,并维护一张动态映射表来保障双向通信的连贯性。
SNAT:让内网设备“共用”一个公网出口
SNAT(源地址转换)用于内网主机访问外网时隐藏真实 IP。它发生在数据包即将离开本机前的 postrouting 链上,此时路由已确定,系统知道该往哪发,才开始改源地址。
- 典型命令:
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 203.0.113.1 - 更常用的是 MASQUERADE(适合拨号或动态公网 IP):
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ppp0 -j MASQUERADE - 关键点:必须开启内核 IP 转发(
echo 1 > /proc/sys/net/ipv4/ip_forward),否则包不会被转发
DNAT:把公网请求“转给”内网服务
DNAT(目标地址转换)用于将外部访问某个公网 IP+端口的请求,定向到内网某台服务器。它发生在数据包刚进入本机的 prerouting 链上,确保在路由决策前就完成目标地址替换。
- 例如把公网 203.0.113.1:80 的请求转给 192.168.1.100:80:
iptables -t nat -A PREROUTING -d 203.0.113.1 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80 - 若需同时支持内网用户也用同一公网地址访问该服务,还需补充一条回流规则(避免响应包绕过 DNAT)
- 注意:DNAT 后,返回包的源地址是内网服务器地址,所以通常需配合 SNAT 或路由调整,否则可能不通
NAT 表如何工作:映射靠状态,转发靠规则
iptables 的 nat 表不直接决定“是否放行”,而是修改地址并建立连接跟踪(conntrack)记录。实际转发由 filter 表的 FORWARD 链控制,因此配置 NAT 后常要同步放行相关连接:
- conntrack 模块自动维护会话:记录
192.168.1.50:42321 → 203.0.113.1:80这样的映射,返回包到来时自动反向还原 - 必须允许已建立连接的返回流量:
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT - 若启用 DNAT,还要显式放行新连接到内网服务器的 FORWARD 规则,否则包会被 drop
常见误区与实操要点
很多配置失败不是规则写错,而是忽略了底层依赖或链执行顺序:
- 别在 INPUT 链做 DNAT —— 它只处理发给本机的包,而 DNAT 是为转发设计的;正确位置是 PREROUTING
- 别忘记开启 IP 转发,且确认网卡角色:内网接口标记为
ip nat inside(逻辑概念,iptables 中靠 -i/-o 区分) - MASQUERADE 自动适配出口 IP 变化,但性能略低于固定 SNAT;生产环境建议优先用 SNAT + 固定公网 IP
- 测试时可用
conntrack -L查看实时 NAT 映射条目,验证规则是否生效










