问题背景
一个四十人左右的研发团队,办公室拉了一条企业宽带,入口是一台企业级路由器。内网有一台 NAS,上面跑 GitLab 和文件服务,路由器把 WAN 的 443 端口映射到 NAS 的 443,公网侧用 DDNS 域名 files.example.com 访问。外网访问一直正常,办公室里用同一个域名访问也一直正常。
上个月这台路由器老化,频繁重启,于是换了一台新的。配置是照着旧设备抄的:WAN 拨号、443 端口映射、DDNS 账号,三项填完,用手机流量访问域名验证通过,就把旧设备下架了。当时默认“外网能打开就说明配置没问题”,没有在内网再试一次。
第二天开始,陆续有人反馈:在办公室打开 files.example.com 一直转圈,但直接输 NAS 的内网 IP 又是好的。
故障现象
- 办公室内浏览器访问
https://files.example.com长时间无响应,最终超时;偶尔报ERR_CONNECTION_RESET。 - 同一台电脑访问
https://192.168.10.20完全正常,GitLab 页面和文件下载都没问题。 - 用手机 4G/5G 访问同一个域名正常,说明端口映射、证书、NAS 服务都没坏。
- 域名解析正常,
nslookup得到的是公网 IP;内网 ping 这个公网 IP 也能通。 - 有线、无线终端表现一致,换浏览器、清缓存都无效。
- 把旧路由器临时接回去,内网访问立刻恢复。
排查过程
第一步做分层排除。DNS 解析到公网 IP,正确;外网访问正常,说明端口映射和运营商没有封 443;内网用私有 IP 访问正常,说明 NAS 服务本身没问题。问题被压缩到一条很窄的路径上:内网终端访问自己的公网 IP。
第二步抓包。在内网终端上抓,看到 SYN 反复发往公网 IP,一直没有收到合法的响应;在 NAS 上抓,SYN 确实到了,NAS 也回了 SYN-ACK,但这条 SYN-ACK 的源地址是 NAS 的内网 IP,不是客户端期望的公网 IP。客户端内核认为这个包和发出的连接对不上,直接丢弃,三次握手永远完不成。
第三步解释这个现象。路由器做端口映射时只执行了 DNAT:把目的地址从公网 IP 改成 NAS 的内网 IP,源地址仍然是客户端的内网 IP。NAS 收到请求后回包,发现目的地址和自己同一网段,于是直接二层转发给客户端,根本不经过路由器。客户端发出去时目标是公网 IP,收到的却是内网 IP 的响应,连接自然建立不起来。这条路径是单向的——去程经过路由器,回程绕过了它。
第四步确认设备能力。查新路由器的文档,它支持 NAT 回环(不同厂商叫 NAT Loopback、NAT Reflection 或 Hairpin NAT),但该选项默认关闭,藏在防火墙的高级设置里。旧路由器恰好默认开启,所以这些年大家一直没意识到存在这样一个隐式依赖。
第五步验证。打开 NAT 回环后,内网访问域名立即恢复;再次抓包,可以看到路由器把源地址 SNAT 成了自己的内网接口地址,NAS 的回包先回到路由器,再由路由器转给客户端,往返路径对称,握手正常完成。
解决方案
- 首选开启 NAT 回环:在路由器的 NAT 或防火墙高级设置里启用 NAT Loopback / NAT Reflection / Hairpin NAT。开启后内网访问公网 IP 时,路由器会同时做 DNAT 和 SNAT,把回程拉回自己。
- 不支持时改用 DNS 分离解析:内部 DNS 把
files.example.com解析成 NAS 的内网 IP,公网 DNS 仍返回公网 IP。TLS 证书按域名签发,内网访问同样受信,而且流量直接走内网,不经过路由器的 NAT 转发,性能和延迟都更好。 - 服务较少时可用内网反向代理:在路由器或一台内网服务器上做反向代理,把域名指向内网服务。缺点是引入单点和额外维护成本,不适合作为默认方案。
- 不建议逐台改 hosts:终端数量一多就无法维护,手机、平板等移动设备也改不了,出差场景还会留下错误解析。
- 改完双向验证:内网访问域名、外网访问域名各测一次,并检查证书链和重定向是否正常。
根因分析
直接根因是 路由器缺少(或未启用)NAT 回环:端口映射只做了 DNAT,没有配套的 SNAT,内网访问公网 IP 时回程流量绕过路由器,形成非对称路径,TCP 握手无法完成。
更深一层,问题出在配置迁移和验收方式上。换机时我们迁移的都是“填在页面里的显式配置”——拨号账号、端口映射、DDNS;而 NAT 回环是旧设备默认开启的隐式能力,从来没被写进文档,也没人知道它的存在。验收又只测了外网,没有测内网访问同一域名的路径,于是这个缺口被完整地带到了新设备上。
预防措施
- 设备更换或配置迁移时建立“访问路径矩阵”:内网访问内网 IP、内网访问公网域名、外网访问公网域名,逐条验收,缺一不可。
- 路由器选型把 NAT 回环列为必检项;不支持或默认关闭时,统一采用内网 DNS 分离解析作为标准方案。
- 文档记录隐式依赖,例如 NAT 回环、UPnP、DDNS 更新方式、端口映射清单,避免下次换机再踩同一个坑。
- 对内网域名访问做可用性监控,配置变更后能第一时间发现回归。
总结
“外网能打开”不等于“哪里都能打开”。NAT 回环是一个不会出现在端口映射页面上的隐式能力:它靠额外一条 SNAT 把回程流量拉回路由器,少了这一步,连接就是单向的。换设备时真正容易丢的,往往不是那些填在表单里的配置,而是那些一直默默生效、却从没被写进文档的能力。验收要按访问路径走,而不是按配置页面走。