如何用iptables模拟NAT反射(Hairpinning)失效场景
如何用iptables模拟NAT反射(Hairpinning)失效场景
先确认下你的场景:你的工作站LAN IP是192.168.0.101,路由器把WAN口80端口转发到你工作站的8080,现在NAT反射正常——你自己用WAN IP 12.34.56.78:80能连到本地的8080服务,外网也能正常访问。现在想要模拟Hairpin失效:自己用WAN IP连不上,但外网访问不受影响,用iptables就能做到,具体步骤如下:
核心思路
咱们要做的是:在工作站的iptables里,拦截从本机发起的、目标是自身WAN IP的流量,但放行从外网过来的、目标是自身LAN IP的转发流量(因为外网流量经路由器端口转发后,到达你工作站时的目标IP是LAN IP而非WAN IP)。
具体iptables规则
直接在你的工作站(192.168.0.101)上执行以下规则:
- 拦截本机发起的、目标为WAN IP的出站流量(核心规则):
iptables -A OUTPUT -d 12.34.56.78 -p tcp --dport 80 -j DROP
这条规则会直接丢弃你工作站自己发起的、目标为12.34.56.78:80的TCP数据包。此时你再执行echo 'Hello World' | nc 12.34.56.78 80就会连接失败,完美模拟Hairpin失效的场景。
- (可选但更严谨)明确放行外网转发的流量:
因为外网流量经路由器端口转发后,到达你工作站时的目标IP是192.168.0.101:8080,默认不会被上面的规则拦截,但可以加一条规则明确放行,避免其他潜在规则影响:
iptables -A INPUT -d 192.168.0.101 -p tcp --dport 8080 -j ACCEPT
验证效果
- 本机测试:执行
echo 'Hello World' | nc 12.34.56.78 80,会出现连接超时或被拒绝的情况,符合Hairpin失效的要求。 - 外网测试:从外部网络执行
echo 'Hello World' | nc 12.34.56.78 80,依然能正常连接到你工作站的8080服务,完全不受影响。
恢复规则
如果之后需要取消模拟,直接删除刚才添加的规则即可:
# 删除核心拦截规则 iptables -D OUTPUT -d 12.34.56.78 -p tcp --dport 80 -j DROP # 如果添加了可选的放行规则,也一起删除 iptables -D INPUT -d 192.168.0.101 -p tcp --dport 8080 -j ACCEPT
补充说明
- 为什么这个规则能精准模拟Hairpin失效?因为Hairpin失效的本质是:本机发起的目标为自身WAN IP的流量,无法通过路由器的NAT反射回到本机。咱们通过拦截本机出站的这类流量,达到了和真实Hairpin失效完全一致的效果——本机用WAN IP连不上,但外网访问不受影响。
- 如果你需要针对所有端口而非仅仅80端口模拟,只需要去掉
--dport 80参数即可,但根据你的场景,只针对80端口就足够了。
备注:内容来源于stack exchange,提问作者root-aj
相关产品推荐
相关产品推荐

