查看linux中nat实际工作状态的关键是检查conntrack表是否建立正确的双向映射关系:一、用sudo conntrack -l -p tcp | head -5确认目标流量是否被跟踪;二、查iptables -t raw -l prerouting排除notrack干扰;三、通过grep筛选验证snat/dnat四元组是否完整;四、依据[assured]标记判断映射是否稳固;五、结合nf_conntrack_count/max及dmesg日志排查表满或异常状态堆积。

要查看 Linux 中 NAT 的实际工作状态,关键不是查 iptables 规则本身,而是看 conntrack 表里是否已建立正确的双向映射关系。NAT 依赖 conntrack 运行,没有表项,转换就无法反向还原——哪怕规则写对了,连接也会失败。
确认 NAT 流量是否已被跟踪
先验证内核是否在对相关流量做连接跟踪:
- 运行 sudo conntrack -L -p tcp | head -5,观察输出中是否有包含你预期的源/目的 IP 和端口的条目
- 若完全无输出,检查是否误用了 NOTRACK 规则:执行 sudo iptables -t raw -L PREROUTING,确认没有跳过跟踪的规则覆盖了你的流量
- 对 UDP 或 ICMP 流量,同样用 -p udp 或 -p icmp 查看,注意 UDP 条目可能带 [UNREPLIED] 标记(表示只收到请求、未见响应)
识别 NAT 映射关系是否完整
一条成功的 SNAT 或 DNAT 连接,在 conntrack 表中会显示原始方向和回复方向两组地址端口,且第二组体现转换结果:
- 例如内网 192.168.1.100:54321 → 114.114.114.114:80 经 SNAT 后变为 203.0.113.5:54321 → 114.114.114.114:80,表中应同时出现这两组四元组
- 查找特定转换:sudo conntrack -L | grep "192.168.1.100" | grep "114.114.114.114"
- 若只看到原始方向、没看到转换后的回复方向,说明 NAT 规则未命中,或报文未经过 netfilter 链(如走 bypass 路径)
区分 SNAT 与 DNAT 的表项特征
SNAT(源地址转换)和 DNAT(目的地址转换)在 conntrack 条目中表现不同:
- SNAT 表项:原始方向 src 是内网 IP,回复方向 dst 是路由器 WAN 口 IP(即转换后的源 IP)
- DNAT 表项:原始方向 dst 是路由器公网 IP + 端口,回复方向 src 是后端真实服务器 IP + 端口
- 两者共有的关键标记是 [ASSURED]——表示双向报文均已收到,映射已稳固;若长期停留在 [UNREPLIED],说明响应丢失或被拦截
排查 NAT 失效的典型 conntrack 线索
当用户能发包但收不到回包时,conntrack 往往暴露真正瓶颈:
- 执行 sudo cat /proc/sys/net/netfilter/nf_conntrack_count 和 cat /proc/sys/net/netfilter/nf_conntrack_max,确认是否达到上限(常见于大量短连接)
- 搜索丢包日志:dmesg | grep "nf_conntrack: table full",命中即说明新连接被直接丢弃
- 检查异常状态堆积:sudo conntrack -L | awk '$4 ~ /SYN_SENT|TIME_WAIT/ {print $0}' | head -10,过多 SYN_SENT 可能指向目标不可达,过多 TIME_WAIT 则需调优超时











