家里上网为什么能共享一个公网 IP?NAT 会话表拆解
专栏《计算机网络基础》对应总览第四篇 网络层让包跨越「很多个网络」本篇角色NAT 专章——公私网地址如何转换、会话表长什么样承接《路由基础》——包已经知道「下一跳去网关」本篇看网关出口如何「换皮」读完你能说清 SNAT/DNAT画出一张五元组映射解释为何外网不能随便连进你家区分 NAT 与云安全组导读路由送到门口谁负责「出门换马甲」上一章路由表解决的是包该扔给谁。家里十几台手机、电脑地址却都是192.168.x.x这种私网地址——公网上并不路由它们。运营商通常只给你家或整栋楼的某个出口有限的公网 IPv4。于是家用路由器在 WAN 口做了一件天天发生、却很少被看穿的事把「很多个内网五元组」临时映射成「少量公网 IP 端口」让回复还能找回家。这就是NATNetwork Address Translation网络地址转换。本篇不背考试名词表重点拆会话表没有这张表共享公网 IP 根本玩不转。手机 192.168.1.8:50123 ──► 路由器 NAT ──► 公网 203.0.113.9:40001 ──► 网站 网站回包到 203.0.113.9:40001 ──► 查会话表 ──► 改回 192.168.1.8:50123一、概念NAT 在解决什么痛点1.1 一句话NAT在转发时改写 IP 包常常还改端口使私网主机能借用公网地址通信并尽量让回程包回到正确主机。常见动机现实混在一起动机说明IPv4 不够用私网地址可在每个家庭重复使用拓扑隐藏外网默认看不到你家每台设备的真实地址出口收敛公司/机房多台机器共用出口地址NAT不是防火墙的完整替代品虽然「默认不映射就不进得来」看起来有点像防护——后面会单独掰扯。1.2 SNAT / Masquerade出门换源地址SNATSource NAT改源地址常连带源端口。家用场景里Linux 上常叫Masquerade伪装出口地址跟着 WAN 口当前 IP 变DHCP 换号也不用写死。出门前源192.168.1.8:50123 目的93.184.216.34:443 出门后源203.0.113.9:40001 目的93.184.216.34:443 ← 源被换成公网回程时路由器必须记得公网:40001此刻「代表」谁。没有这张记忆回程包即使到了你家公网口也不知道该交给哪台手机。1.3 DNAT / 端口转发进门改目的地址DNATDestination NAT改目的地址常连带目的端口。家用「端口转发 / 虚拟服务器」就是它外网访问目的203.0.113.9:8080 转发后 目的192.168.1.20:80 ← 打到家里 NAS/树莓派没有 DNAT或 UPnP/PCP 自动开的映射外网主动连你家私网主机——路由器通常不知道交给谁包就被丢了。1.4 和「路由」的边界路由决定从哪出去、下一跳是谁 NAT在出入过程中改写地址/端口并维护会话好让回程还能归位两者常在同一台家用路由上先后发生先按路由选 WAN再做 SNAT 出站。云上的「NAT 网关」产品本质仍是私网出公网时做源地址转换别被产品名吓到。1.5 NAT 改的是「边界上的身份」不是改应用协议本身对浏览器来说它仍然以为自己在用192.168.1.8访问网站对网站来说它只看见出口公网 IP。中间那层「翻译」对应用常常透明——直到应用把内网地址写进载荷某些 FTP/SIP/自定义协议翻译层又看不懂或帮倒忙问题才浮出水面。所以学 NAT 时要同时记住两层真实包头地址经常被改这是 NAT 的本职 载荷里的地址默认没人改除非 ALG/应用自己处理这也解释了为什么现代协议更爱「在载荷里避免硬编码地址」或干脆假设有中继TURN可用。二、原理会话表才是 NAT 的灵魂2.1 五元组映射先建立这张表传输层连接/数据报常被概括为五元组协议 源IP 源端口 目的IP 目的端口NAT 设备为「正在发生的通信」建一条或一组映射人话版可以画成会话表示意 ───────────────────────────────────────────────────────────── 内网侧 公网侧WAN UDP/TCP 192.168.1.8:50123 203.0.113.9:40001 ↔ 93.184.216.34:443 ↔ 93.184.216.34:443 超时剩余 30sUDP 往往更短 / TCP 可能更长 ─────────────────────────────────────────────────────────────要点出站时创建或刷新映射你先访问网站表项才出现。入站回程必须能命中已有映射才会改回内网地址。超时一段时间没流量表项删除——UDP 应用对此特别敏感传输层篇章提过。排障时还要问清你看的是内网抓包还是公网侧抓包。同一条连接两边看到的源 IP/端口本来就不一样。2.2 「全锥 / 对称」只做直觉不考试背诵文献里有全锥、受限锥、端口受限锥、对称 NAT 等分类用来描述没做过映射的外部主机能不能打进映射端口换了外部地址后还认不认。直觉版够用宽松一旦你出站过某些环境下外部更容易打回你的映射端口 严格常被说成「对称」味道换一个外部目标映射端口也可能变 → P2P / 打洞更难常要 TURN 中继家庭宽带、运营商 CGNAT、公司防火墙宽松程度天差地别。做业务时别假设「能出站就一定能被任意人连回来」。家用路由行为各异也不要假设和实验室分类表一一对应。2.3 为什么外网不能主动连内网不是私网地址「魔法隐身」而是默认情况下1) 公网路由不到 192.168.x.x / 10.x 等私网 2) 家用路由 WAN 上若没有 DNAT/UPnP 映射入站包没有会话可归位 → 丢弃 3) 即便有公网 IP没有转发规则也不会进到你指定的那台电脑所以「能上网」≠「别人能连进我这台机器」。出站 SNAT 会话默认只服务「你发起、对方回包」这条对话。想让外网访问家里服务端口转发、内网穿透、或后面要讲的 VPN而不是指望私网地址自己暴露出去。2.4 映射耗尽端口也是资源一个公网 IPv4 的传输端口大约六万多个可用。出口上成千上万设备、或短生命周期连接狂飙时可能出现新建连接失败、偶发超时日志里出现 NAT pool exhausted / port allocation failed 一类信息设备而异「有时上不了网重启路由就好」——有可能是会话表/连接跟踪打满后的粗暴自愈云上的 NAT 网关、运营商 CGNAT都把「端口库存」当容量规划的一部分。2.5 ALG聪明反被聪明误ALGApplication Layer Gateway会「看懂」应用载荷里的地址端口经典如部分 FTP、SIP并帮忙改写。理想很丰满现实常翻车加密流量看不懂ALG 帮不上帮错了改坏载荷、和现代协议打架排障时多了一个「看不见的改包者」直觉遇到诡异的「只有某个老协议不行」想想有没有 ALG/助手功能在掺和能关的测试环境不妨对比开关。2.6 Hairpin NAT回环 / NAT 环回同一内网里的 A用公网 IP 转发端口去访问家里的 BA内网──► 访问 公网IP:8080 ──► 路由器 ──?──► B内网有的路由支持hairpin把这种「出门又进门」的流量拧回内网。不支持时会出现经典怪症外网能访问家里 NAS 家里 Wi‑Fi 用公网域名/公网 IP 反而访问不了 内网直连 NAS 私网 IP 却正常排障时先分清客户端是否在「同一 NAT 内侧」。很多「域名解析没问题、外网朋友说能开」的工单最后落在 hairpin。2.7 运营商 CGNAT你「可能」没有独立公网 IPv4很多宽带给的是运营商大网里的私网/共享地址你家路由再套一层 NAT——双重 NAT。后果直觉家端口转发更难甚至无效开游戏主机、远程桌面、P2P 更痛这不是你路由设置「手残」是上游地址形态变了用curl -4 ifconfig.me一类服务看到的「公网 IP」和光猫 WAN 口地址不一致时要怀疑中间还有一层。2.8 端口会不会变为什么有时「源端口对不上」很多家用 NAT 会做NAPT带端口转换的地址转换不只改 IP还可能改源端口以避免两台内网机器碰巧用了同一个源端口时冲突。内网 A192.168.1.8:50123 → 映射成 公网:40001 内网 B192.168.1.9:50123 → 映射成 公网:40002于是你在服务器日志里看到的源端口未必等于客户端ss里看到的本地端口。排障时如果强行「按端口一一对上」会对不上号——要以会话表或两端抓包为准。TCP 与 UDP 在映射刷新上也不一样TCP 有连接状态映射往往跟连接生命周期更齐UDP 更像「一段时间内的对话」静默太久就可能被忘掉。游戏、VoIP、部分 DNS 长流程都在这条差异上栽过跟头。2.9 「看起来像防火墙」时NAT 到底提供了什么默认丢弃「没有会话可归位」的入站包客观上减少了暴露面。但它不是完整安全方案NAT 不做的事举例 - 细粒度「只允许某用户访问某服务」 - 应用层审计与入侵检测 - 替代补丁与强密码把 NAT 当成唯一防护会高估安全性完全忽略它带来的「默认不进得来」又会低估家用拓扑的实际形态。更干净的心智模型是NAT 负责翻译与会话放行/拒绝交给防火墙或安全组。三、应用家里、公司、云上怎么碰到 NAT3.1 家用路由器默认的 SNAT 可选端口转发手机/电脑 → 默认路由到 192.168.1.1 → WAN 口 Masquerade → 运营商可能还有一层 CGNAT管理页里的「端口映射 / 虚拟服务器 / UPnP」 给入站开 DNATUPnP 是自动开映射的机制便利也有安全争议。3.2 公司出口地址池与会话规模公司防火墙后面可能是成千上万私网用户共享一小撮出口地址。这时运维关心的不只是「能不能上网」还有会话表容量、每用户连接数、是否要对某些业务做固定 SNAT方便对端加白名单。3.3 云上别把「安全组」和「NAT」混成一个词NAT / NAT 网关安全组 / 防火墙规则主要动作改地址/端口维护会话允许或拒绝某些流量典型目的私网出公网、隐藏内网地址最小暴露面、访问控制失败体感出不去、映射满、回程错乱明确被拒或超时视实现常见云拓扑私有子网里的主机 → 路由指向 NAT 网关 → 共用出口 EIP 访问互联网 公网回连业务 → 通常走负载均衡 / 公网 IP 绑定而不是「指望 NAT 会话反向打开」安全组放行了 443但子网路由没指到 NAT 网关——仍然出不了公网。这是上一章路由 本章 NAT 的联合题。表象很像时怎么分线索更像云控制台显式 Deny 日志安全组/ACL私网主机根本没有出网路由路由问题出网地址池告警 / 新建失败NAT 容量入站从未配置转发却指望别人连进来对 NAT 模型预期错了3.4 容器与节点又一叠转换Kubernetes NodePort、docker 端口映射等场景里常常还有节点侧 NAT。排障时要问我看到的源 IP是客户端真实地址还是被哪一层 SNAT 过日志里「全是节点 IP」时经常不是应用写错而是链路中途被改写了。四、问题定位NAT 翻车现场4.1 「单向不通」优先怀疑映射与回程出站正常、入站不行 → 正常无 DNAT或安全策略拦入站 A 能连 BB 不能连 A → 两端 NAT/防火墙不对称或只有一边建了会话 「刚才还行过一会不行」 → UDP 映射超时移动网络切换导致公网侧五元组变了 外网 OK、内网用公网域名不行 → hairpin 缺失 偶发新建失败 → 端口耗尽、连接跟踪表满 某个老协议独惨 → ALG / 载荷内嵌地址 家端口转发怎么都不生效 → 先怀疑 CGNAT / 上游还有 NAT4.2 决策树4.3 实操命令与观察点思路不必在家路由器里瞎改生产规则# 本机私网地址 ip -br addr # 外网看见的地址若可达 curl -4 ifconfig.me # 看自己到外网的连接本机五元组 ss -tnp | head ss -tn dst :443ipconfig # 查建立中的 TCP示意 Get-NetTCPConnection -State Established | Select-Object -First 10在路由管理页查看端口转发列表、连接数/会话数不同品牌菜单名不同。有 OpenWrt / 实验路由时还可以对照 LAN/WAN 两侧抓包亲眼看源地址被改写的那一刻。4.4 单向不通的「最小复述」同事说「服务器收得到请求回不去」时你可以按这个顺序复述现场1) 请求方向客户端 → NAT → 服务器源已被换成出口 IP 2) 响应方向服务器 → 出口 IP:映射端口必须能回到同一台 NAT 3) NAT 查表映射还在吗超时了吗被灌满后淘汰了吗 4) 回去内网DNAT/会话改写后内网主机防火墙是否又拦了回程很多「单向」其实是回程在第 2/3 步丢的对端只放行了入站业务端口却没有正确的回程路由或你的出口有多条请求从 A 出、响应却想从 B 回会话对不上。云上多网卡、双出口公司网尤其常见。4.5 和上一章路由的联合作答出不了公网 先看有没有指向 NAT 网关/默认网关的路由 再看 NAT 是否健康地址、会话表、配额 最后才看安全组有没有放行出站有的云默认很宽有的很紧 外网进不来 先问业务是否根本不该直接进该走 LB / VPN 再查 DNAT/端口转发/公网 IP 绑定 同时查安全组入站与操作系统防火墙把「翻译」和「选路」分开问工单会短很多。五、动手用「想象会话表」 ss / tcpdump 建立直觉家用路由的会话表界面各厂不同有的叫「连接跟踪 / ContTrack / 会话列表」。下面用纸上推演 主机侧命令练肌肉不要求你刷第三方固件。实验 A画出你一次 HTTPS 访问的映射访问任意网站在电脑上查看本机五元组# Linux ss -tnp | head ss -tn dst :443Get-NetTCPConnection -State Established | Where-Object RemotePort -eq 443 | Select-Object -First 5在纸上填数字用你看到的内网 我的IP:______ 源端口:______ → 网站IP:______ :443 公网 家宽公网或 CGNAT 地址:______ → 同一网站:443想清楚网站看到的源 IP是哪一个回程目的端口是哪一个实验 B两台设备对比「外网看见的地址」若你有手机 电脑同连一家路由各自查询出口 IP浏览器搜「IP」或用curl -4 ifconfig.me。通常会得到同一个结果——这就是 SNAT 共享出口的体感证明。若一个是蜂窝、一个是家里 Wi‑Fi结果不同也很合理出口根本不是同一台 NAT。实验 C抓包看「谁在改地址」有权限时# 本机发起访问时源地址仍是私网——NAT 发生在路由器上 sudo tcpdump -ni any host 1.1.1.1 and tcp port 443你应看到本机用私网源地址在通信。公网侧「换马甲」发生在上行设备若你有实验路由再在 WAN 口对比源地址变化一次就能刻进脑子。实验 D体会「外网不能主动进来」查一下你的出口地址。不要在未做端口转发时指望朋友直接连你的192.168.x.x。若安全地在实验环境做端口转发只映射到实验机临时端口测完关闭。未转发外网 SYN 打到家宽公网 IP 的随机端口 → 通常无会话 → 丢 做了 DNAT该端口 → 指定内网主机:端口 → 才可能通 云上还要同时放行安全组实验 EUDP「过一会就不行」的思想实验回想游戏联机、部分语音你先发 → NAT 建映射 → 对方能回 你静音不动超过映射超时 → 表项消失 → 对方再发就进不来 保活包keepalive的意义刷新会话表不一定要抓到超时秒数懂机制就能看懂为啥产品爱发心跳。六、本篇知识地图NAT转发时改地址/端口 会话表让回程归位 SNAT/Masquerade出门换源DNAT进门改目的端口转发 五元组映射是核心超时与端口库存决定稳定性 外网默认进不来 无私网路由 无映射可归位 ALG / hairpin / CGNAT / 端口耗尽 常见坑 云上NAT 网关负责出网转换安全组负责放行——别混 下一章VPN/隧道——把私网「叠」在公网上本章小结私网能上网靠出口 NAT 换源并记住会话 会话表按大致五元组映射公网端口超时即失效 DNAT/端口转发才是「外网主动进来」的正规入口之一 单向不通、间歇失败、公网域名内网打不开——常指向 NAT 细节 安全组是过滤NAT 是改写云上两者经常一起出现但职责不同 工具直觉ss 看本机五元组tcpdump 验证方向会话表在网关侧