📚 第五章 IP协议相关技术
📄 一句话概括

NAT 解决了地址不够,代价是「连接的方向性」没了:外面再也主动连不进来。 四个后遗症——不可入、端口耗尽、载荷被改、身份丢失,每一个都只能绕,不能消。

📝 本节和前面几节的关系

5.6.2 讲了那张表怎么建,这一节讲「这张表带来的副作用」。 5.8.5 的 Mobile IP 撞的是同一堵墙,都属于「地址被中间设备改了」。

一、四个后遗症一览

这些不是「配置没做好」,是 NAT 的原理决定的:

编号 问题 表现 能不能修
1 外面连不进来 P2P、远程访问都要打洞 只能绕
2 端口会耗尽 高并发时新连接建不起来 加地址缓解
3 载荷被改不了 FTP 主动模式、SIP 失效 打补丁
4 身份不可见 日志里只有公网地址 记映射日志

第四列的「只能绕」最重要:第一行是结构性缺陷,因为表项本来就只能「由内向外」建出来。 想反过来,必须有人事先钉一条固定的表项。

二、外面为什么连不进来

因为 NAT 表是「谁先发谁建表」: 内网先发包,表里才有这条会话;外面的包进来时,表里没有对应项,只能丢。 这是设计,不是 bug——不然内网就等于完全暴露了。 要让人连进来,只有「事先钉一条」这一条路,具体有三种形态:

做法 钉的是什么 代价
端口映射 公网端口 → 内网某台某端口 钉死的端口永久暴露
DMZ 主机 所有未用端口都给它 风险最大
UPnP 自动开洞 程序自己申请 等于放权给应用

第一行的代价经常被低估:只要映射还在,那个端口就一直在扫, 所以「临时开一下再关掉」是必须养成的习惯。 第三行是家用场景的常态:游戏机、下载工具都靠它自动开洞, 方便,但也意味着「哪个程序在监听」你未必知道。

三、端口耗尽能算出来

一个公网地址 65535 个端口,能带几台设备取决于「每台开几个连接」:

每台连接数 能带几台 场景
10 约 6553 台 只看网页
100 约 655 台 正常办公
500 约 131 台 开视频会议
5000 约 13 台 P2P 下载

第四行是很多「网络慢」的真凶:P2P 软件一次开几千个连接,把表填满之后,别人连网页都连不上。 而症状是「已经连上的不卡、新连接建不起来」,所以常被误判成「带宽不够」或「DNS 坏了」。 缓解办法有三个:加公网地址(分池)、缩短老化时间、限制单机连接数。 第三个最有效,但也最容易引起用户投诉。

四、载荷被改与身份丢失

第三行的典型是 FTP 主动模式:它在报文里写「请连我的 192.168.3.152:20」, 而 NAT 只改 IP 头、不改载荷,所以对方拿到一个私网地址,永远连不上。 解决办法是「让 NAT 设备读懂这个协议并改写载荷」:这叫 ALG(应用层网关)。 它的毛病和 5.6.3 的 NAT-PT 一模一样:每支持一个协议就要加一段代码,而协议是无穷的。 所以现在很多设备干脆把 FTP 的 ALG 关掉,让人改用被动模式——这是「承认修不好」的做法。 第四行是排查时最烦的:日志里只有 203.0.113.7,看不出是内部哪台机器干的。 所以运营商级 NAT 环境下,很多地方要求「每次映射都留日志」, 包括时间、内网地址、公网端口、目的地址。 没有这份日志,出了事就真的追不到人。

五、动手 Demo:一个公网地址到底能带几台设备

算三档:只看网页、正常办公、开视频会议。 这个数不是理论玩具,它决定了「一个出口能带多大办公室」。

ports = 65535
for per_host in (10, 100, 500, 5000):
    print('%5d 个连接/台 -> 约 %d 台' % (per_host, ports // per_host))

实跑输出:

--------------------------------------------------------------------
NAT 的四个老问题
--------------------------------------------------------------------
**NAT 解决了地址问题,但留下了四个后遗症**:**每一个都真实存在,而且没法靠「配置好一点」消掉。**

  编号      问题                     表现
  ----------------------------------------------------------------
  **1**     **外部不能主动连入**     **P2P、远程访问都要打洞**
  **2**     **端口会耗尽**           **高并发时新连接建不起来**
  **3**     **协议被改写**           **FTP 主动模式、SIP 会失效**
  **4**     **身份不可见**           **日志里只有公网地址**

**第三行最典型的是 FTP 主动模式**:**它在报文里写「请连我的 192.168.3.152:20」**,
**NAT 只改 IP 头不改载荷,所以对方拿到的是一个私网地址,永远连不上。**
**解决办法是「NAT 设备要能识别 FTP 协议并改写载荷」**——
**这叫 ALG(应用层网关),但它每支持一个协议就要加一段代码。**

**第二行可以量化**:
**一个公网地址 65535 个端口,如果每台设备开 500 个连接,理论上只够 131 台设备同时用。**
**所以「全公司一起开视频会议」时,NAT 表真的会被填满**——
**症状是「网页打不开、但已经连上的不卡」,很容易被误判成「带宽不够」。**

**第四行是排查时最烦的**:**日志里只有 203.0.113.7,看不出是内部哪台机器干的**。
**所以现在企业出口都要记「NAT 映射日志」**,**否则出了事根本追不到人。**

131 台这个数很说明问题:一个 200 人的办公室,如果人人开视频会议,一个公网地址就不够了。 所以企业出口要么有多个公网地址,要么就得限制单机并发。 「131 台」还是乐观估计:因为每台设备除了「自己开的连接」,还有后台的更新、推送、心跳。 实际可用数往往只有理论值的一半。 这也是「为什么现在都往 v6 走」的一个实际理由: 地址够用就不需要 NAT,不需要 NAT 就没有这张表,也就没有端口耗尽、没有 ALG、没有打洞。 但防火墙还是要有——那是策略问题,和地址够不够是两件事。

30 秒实验

  1. 算一下:每台开 300 个连接,一个公网地址能带几台?
  2. 想一下:为什么「已经连上的不卡、新连接建不起来」会被误判成带宽不够?
  3. 想一下:ALG 越加越多的根本原因是什么?

常见误区

  1. 以为「外面连不进来是配置问题」。 是原理问题,表项只能由内向外建。
  2. 以为「端口够用就行」。 还要看每台开几个连接,视频会议和 P2P 会把它吃光。
  3. 以为「ALG 能彻底解决载荷里的地址」。 每支持一个协议加一段代码,加不完, 所以现在多改用被动模式绕开。
自测三问(点开对答案) 1. NAT 后面为什么外面连不进来? —— **因为表项是「内网先发包」才建出来的**,外面的包找不到对应项,只能丢。 2. 一个公网地址能带多少台设备? —— **理论 65535 个端口除以每台连接数**:每台 500 个连接就只有 131 台,还要扣掉后台连接。 3. FTP 主动模式为什么过不了 NAT? —— **它把 IP 写在报文载荷里**,NAT 只改头不改载荷,对方拿到一个私网地址连不上。

下一节讲这些问题的对策:静态映射、打洞、中转。

相关笔记