欢迎光临
我们一直在努力

家里上网为什么能共享一个公网 IP?NAT 会话表拆解

专栏:《计算机网络基础》
对应总览: 第四篇 网络层:让包跨越「很多个网络」
本篇角色: NAT 专章——公私网地址如何转换、会话表长什么样
承接:《路由基础》——包已经知道「下一跳去网关」;本篇看网关出口如何「换皮」
读完你能: 说清 SNAT/DNAT;画出一张五元组映射;解释为何外网不能随便连进你家;区分 NAT 与云安全组

导读:路由送到门口,谁负责「出门换马甲」?

上一章路由表解决的是:包该扔给谁。
家里十几台手机、电脑,地址却都是 192.168.x.x 这种私网地址——公网上并不路由它们。

运营商通常只给你家(或整栋楼的某个出口)有限的公网 IPv4。于是家用路由器在 WAN 口做了一件天天发生、却很少被看穿的事:

把「很多个内网五元组」临时映射成「少量公网 IP + 端口」,让回复还能找回家。

这就是 NAT(Network 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:出门换源地址

SNAT(Source 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 / 端口转发:进门改目的地址

DNAT(Destination 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
超时:剩余 30s(UDP 往往更短) / 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:聪明反被聪明误

    ALG(Application Layer Gateway) 会「看懂」应用载荷里的地址端口(经典如部分 FTP、SIP),并帮忙改写。

    理想很丰满,现实常翻车:

    • 加密流量看不懂,ALG 帮不上

    • 帮错了:改坏载荷、和现代协议打架

    • 排障时多了一个「看不见的改包者」

    直觉:遇到诡异的「只有某个老协议不行」,想想有没有 ALG/助手功能在掺和;能关的测试环境不妨对比开关。

    2.6 Hairpin NAT(回环 / NAT 环回)

    同一内网里的 A,用 公网 IP + 转发端口 去访问家里的 B:

    A(内网)──► 访问 公网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,还可能改源端口,以避免两台内网机器碰巧用了同一个源端口时冲突。

    内网 A:192.168.1.8:50123 → 映射成 公网:40001
    内网 B:192.168.1.9:50123 → 映射成 公网:40002

    于是你在服务器日志里看到的源端口,未必等于客户端 ss 里看到的本地端口。
    排障时如果强行「按端口一一对上」,会对不上号——要以会话表(或两端抓包)为准。

    TCP 与 UDP 在映射刷新上也不一样:TCP 有连接状态,映射往往跟连接生命周期更齐;
    UDP 更像「一段时间内的对话」,静默太久就可能被忘掉。游戏、VoIP、部分 DNS 长流程,都在这条差异上栽过跟头。

    2.9 「看起来像防火墙」时,NAT 到底提供了什么

    默认丢弃「没有会话可归位」的入站包,客观上减少了暴露面。
    但它不是完整安全方案:

    NAT 不做的事(举例):
    – 细粒度「只允许某用户访问某服务」
    – 应用层审计与入侵检测
    – 替代补丁与强密码

    把 NAT 当成唯一防护,会高估安全性;完全忽略它带来的「默认不进得来」,又会低估家用拓扑的实际形态。
    更干净的心智模型是:NAT 负责翻译与会话;放行/拒绝交给防火墙或安全组。

    三、应用:家里、公司、云上怎么碰到 NAT?

    3.1 家用路由器:默认的 SNAT + 可选端口转发

    手机/电脑 → 默认路由到 192.168.1.1
    → WAN 口 Masquerade
    → 运营商(可能还有一层 CGNAT)

    管理页里的「端口映射 / 虚拟服务器 / UPnP」= 给入站开 DNAT(UPnP 是自动开映射的机制,便利也有安全争议)。

    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 能连 B,B 不能连 A → 两端 NAT/防火墙不对称;或只有一边建了会话
    「刚才还行,过一会不行」 → UDP 映射超时;移动网络切换导致公网侧五元组变了
    外网 OK、内网用公网域名不行 → hairpin 缺失
    偶发新建失败 → 端口耗尽、连接跟踪表满
    某个老协议独惨 → ALG / 载荷内嵌地址
    家端口转发怎么都不生效 → 先怀疑 CGNAT / 上游还有 NAT

    4.2 决策树

    4.3 实操命令与观察点

    思路,不必在家路由器里瞎改生产规则:

    # 本机私网地址
    ip -br addr

    # 外网看见的地址(若可达)
    curl -4 ifconfig.me

    # 看自己到外网的连接(本机五元组)
    ss -tnp | head
    ss -tn dst :443

    ipconfig
    # 查建立中的 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 :443

    Get-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:该端口 → 指定内网主机:端口 → 才可能通
    (云上还要同时放行安全组)

    实验 E:UDP「过一会就不行」的思想实验

    回想游戏联机、部分语音:

    你先发 → NAT 建映射 → 对方能回
    你静音不动超过映射超时 → 表项消失 → 对方再发就进不来
    保活包(keepalive)的意义:刷新会话表

    不一定要抓到超时秒数;懂机制就能看懂为啥产品爱发心跳。

    六、本篇知识地图

    NAT:转发时改地址/端口 + 会话表让回程归位
    SNAT/Masquerade:出门换源;DNAT:进门改目的(端口转发)
    五元组映射是核心;超时与端口库存决定稳定性
    外网默认进不来 = 无私网路由 + 无映射可归位
    ALG / hairpin / CGNAT / 端口耗尽 = 常见坑
    云上:NAT 网关负责出网转换;安全组负责放行——别混
    下一章:VPN/隧道——把私网「叠」在公网上

    本章小结

    私网能上网,靠出口 NAT 换源并记住会话
    会话表按(大致)五元组映射公网端口,超时即失效
    DNAT/端口转发才是「外网主动进来」的正规入口之一
    单向不通、间歇失败、公网域名内网打不开——常指向 NAT 细节
    安全组是过滤,NAT 是改写;云上两者经常一起出现但职责不同
    工具直觉:ss 看本机五元组,tcpdump 验证方向,会话表在网关侧

    赞(0)
    未经允许不得转载:171主机测评 » 家里上网为什么能共享一个公网 IP?NAT 会话表拆解
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址