1 NAT 与 VPN 要解决什么连接问题
在 Linux 主机的 shell 中执行 curl https://example.com,终端得到页面,并不意味着公网服务器能主动连接这台主机。假设主机地址为 10.20.0.10,默认网关为 10.20.0.1,网关的出口地址为 192.0.2.10。主机先按路由把报文交给网关,网关可能改写源地址,公网侧看到的就不再是原来的私有地址。页面能返回,依赖去程、地址转换状态与回程共同成立。
本课中的 192.0.2.0/24、198.51.100.0/24 和 203.0.113.0/24 都是文档示例地址,不能当作实际可访问的公网地址。10.20.0.0/24 等私有网段适合示例内网,但真实使用前仍要检查是否与现有网络冲突。地址看起来正确,只说明格式合理,不说明路由、权限和服务已经准备完成。
NAT 是网络地址转换,解决的是报文经过设备时如何改写地址及必要的端口。常见用途是让多台私有地址主机共享出口,或把某个入口端口转到内部服务。NAT 本身不建立加密通道,也不决定用户身份。防火墙可以和 NAT 位于同一台设备上,但“如何改地址”与“允许谁通过”仍是不同的决策。
VPN 是虚拟专用网络,常见用途是让远程主机或不同站点通过已有网络交换内部流量。本课讨论带加密保护的 VPN:内部报文被封装进外层报文,在隧道端点之间传输,再在对端解封装。要真正访问内部文件服务,还需要身份认证、路由、转发与访问策略配合。VPN 连上只能说明某些建立连接的步骤成功,不能证明全部业务地址可达。
可以把问题拆为 3 个问题:应用要连接哪个目的地址,系统会从哪个接口发送,途中设备是否改变地址或封装报文。例如远程运维人员访问 10.60.0.20:22,VPN 可能负责把流量送到机房,NAT 则可能出现在隧道建立前的家庭路由器上。两者能同时存在,但不能互相代替。排查时应先画清路径,再讨论其中某项功能。

2 SNAT、DNAT 与端口映射边界
SNAT 改写源地址。内网进程建立 TCP 连接时,报文可表示为 10.20.0.10:43120 → 198.51.100.20:443;经过出口后,可能变成 192.0.2.10:52001 → 198.51.100.20:443。目的服务没有改变,改变的是对方看到的来源。网关保存这次连接对应的转换关系,使返回到出口地址和端口的报文能够还原并交给内网主机。
多个主机访问同一个目标时,出口通常还要利用端口区分连接,这种做法常称为端口地址转换。连接识别同时涉及协议、源地址、源端口、目的地址和目的端口。不要只凭某个端口号判断连接归属,也不要假定每次转换都会保留原端口。转换状态有生命周期,长时间空闲、设备重启或状态丢失都可能让既有连接失败。
DNAT 改写目的地址。外部客户端访问 192.0.2.10:8443,入口设备可把它转为 10.20.0.20:443。内部服务通常仍监听 443,客户端则使用外部公布的 8443。所谓端口映射通常是在描述这类入口规则,但具体设备也可能同时改写来源。方案应明确转换前后的完整地址和端口,而不能只写“开放 8443”。
返回报文还需要经过掌握该连接转换状态的设备,才能恢复客户端预期的对端地址。假如内部服务器通过另一台网关直接回包,入口设备就看不到回程,连接可能停在建立阶段。这也是为什么端口映射配置正确,并不能单独证明服务可用。内部监听地址、转发开关、防火墙和回程路由都必须符合这条路径。
NAT 还有明确的能力边界。它不替应用补上认证,不保证通信保密,也不能替代备份和审计。私有地址没有直接发布到公网,可以减少某些直接访问路径,但真正的访问限制仍应由策略表达。发布管理端口时,应说明允许的来源范围、目标服务和撤销方法。需要保留真实客户端地址的日志系统,还必须确认来源是否被转换,否则审计记录可能只剩网关地址。

3 VPN 隧道、加密与路由注入
把 VPN 想象为报文的运输通道,比把它理解成“网络已经打通”更准确。远程主机要访问 10.60.0.20,内部报文的目的地址保持为这个文件服务器;发送时,VPN 把它封装为发往隧道对端的外层报文。中间网络主要根据外层地址转发。到达对端后,端点验证并解封装,再把内部报文交给后续网络。
加密保护的范围一般是隧道端点之间。报文离开端点、继续前往内部服务器时,是否还有应用层加密,要看 SSH、HTTPS 等协议自身。VPN 服务进程也有运行用户、配置文件、密钥和日志;配置目录的访问权限不当,可能导致凭据泄露。不要把私钥放进共享脚本、命令行参数或排查截图,观测网络也需要遵守文件权限边界。
建立隧道后,操作系统还需要知道哪些目的地址应走隧道。连接工具可能添加虚拟接口、分配地址并注入路由。分流模式只把指定网段送进隧道,例如 10.60.0.0/24;全隧道模式会让更广泛的流量,包括通常的互联网访问,经 VPN 出口转发。两种模式对出口容量、访问策略和故障影响范围的要求不同,应在接入前写清楚。
路由选择通常先比较目的前缀的具体程度,后续再结合相关规则与优先级。初学时应先查看 ip route,再用 ip route get 10.60.0.20 检查实际选择。如果连接工具更新了路由,却没有正确配置内部 DNS,使用 IP 可能成功,使用服务名却失败。DNS 解析和报文转发是相关但独立的步骤,不能把域名失败直接归因为隧道加密故障。
还要确认隧道对端本身的外层连接能持续到达。若路由变更让对端地址也被错误导入隧道,连接可能建立后立即中断。虚拟接口名取决于具体实现,本课用 tun0 作为示意,不要求所有 VPN 都出现这个名字。接口显示为已启用,也只能证明本机接口状态;对端授权、内部路由和回程仍需另外确认。

4 动手:对照一次内网访问公网与回程路径
实验使用获得管理授权的 Linux 隔离网络:内网客户端为 10.20.0.10,网关内侧为 10.20.0.1,网关外侧为 192.0.2.10,测试服务器为 198.51.100.20。服务器事先提供 TCP 8080 的 HTTP 服务,外侧网络已配置双向路由。这里的“公网侧”是实验中的外侧网络,示例地址不会自动连到真实互联网。先保留配置与回退方法,再进行任何规则修改。
先在客户端确认地址、路由与实际选择。接口可能叫 ens3 或其他名字,应以输出为准。若 ip route get 返回不可达,就先修复本机路由;若它显示了意外接口,后面的抓包也应据此调整。不要在错误出口上持续抓包,然后把没有观察到报文误判为应用没有发送。
ip -br addr
ip route
ip route get 198.51.100.20
curl --connect-timeout 3 --max-time 8 http://198.51.100.20:8080/
在网关上,假设实验接口确认为 lan0 和 wan0,分别在 2 个终端观察同一次请求。抓包需要相应权限,且可能包含敏感业务数据,应只对授权目标短时采集。下面的过滤条件只观察测试服务器的目标端口,-nn 避免名称解析干扰,-c 20 限制采集数量;流量不足时可以手动停止等待。
sudo tcpdump -nn -i lan0 -c 20 'host 198.51.100.20 and tcp port 8080'
sudo tcpdump -nn -i wan0 -c 20 'host 198.51.100.20 and tcp port 8080'
客户端发起请求后,内侧应能看到来源 10.20.0.10;若出口实施 SNAT,外侧应看到来源 192.0.2.10。返回方向则相反:外侧报文先以出口地址为目的,内侧报文再以客户端地址为目的。端口是否变化要以实际输出为准。把同次请求的时间、方向和地址对应起来,比仅记录“抓到了包”更有解释力。
继续检查网关是否允许转发,以及当前规则的实际内容。这里使用 nftables 作为 Linux 示例;规则集可能很长,也可能由其他管理工具维护。读到某条 NAT 规则不等于已经命中,需要结合抓包或已有计数器判断。不要为了完成实验清空整套防火墙,尤其不要在远程管理连接所依赖的网关上这样做。
sysctl net.ipv4.ip_forward
sudo nft list ruleset
若结果为 net.ipv4.ip_forward = 0,网关不会按预期承担 IPv4 转发。若转发开启而请求只出现在内侧,继续查路由与过滤规则。若请求已经从外侧发出却没有返回,检查外侧下一跳、测试服务和回程。若返回已到外侧却未到内侧,再检查转换状态、过滤及内部邻接。每次只改变有证据指向的配置,并使用新的测试连接确认结果。

5 站点到站点与远程接入的取舍
站点到站点 VPN 通常连接固定网络,例如把办公室 10.20.0.0/24 与机房 10.60.0.0/24 接起来。隧道端点由网络设备或专用主机承担,普通业务进程往往无需逐个建立 VPN。它适合持续、稳定的网段互访,但也意味着站点边界承担了更多授权责任:隧道存在以后,哪些主机能访问哪些服务,仍须通过规则限制。
远程接入 VPN 面向具体用户或终端,例如运维人员从外部网络接入。它更适合流动办公,可以按人员授予范围并撤销权限,但需要维护终端状态、凭据生命周期和地址池。人员离职时,停用账号与撤销凭据必须落实;只删除某台机器上的配置文件,不能证明那份凭据已经无法使用。
选择时先列出访问对象与持续时间。若只有运维终端访问少量内部服务,给所有接入者发布全部内部路由会增加误访问范围。若多个站点持续交换数据,则让每台业务主机维护独立接入配置,可能提高运维成本。隧道的粒度、身份的粒度、访问策略的粒度可以不同,方案必须说明它们如何对应。
分流和全隧道还会改变流量集中程度。分流让指定内部目标走 VPN,其余访问使用本地出口;全隧道便于统一出口管理,但会增加中心出口负载,也可能让隧道故障影响更多应用。这里没有通用的最优比例。应结合业务目标、终端管理能力、出口容量及故障容忍度进行选择,不能把“全部流量经过中心”直接等同于安全已经完成。
交互中的滑块用于比较固定假设下的运维影响,不是性能预测器。实际带宽还受链路、终端和服务端能力影响;实际权限则由访问规则决定。无论选择哪种接入形式,都应明确连接失败时的用户提示、排查入口和恢复责任,避免用户为了恢复访问而自行关闭必要的安全控制。
6 常见坑:重叠网段与策略路由遗漏
远程人员的家庭网络和公司网络都使用 192.168.1.0/24 时,同一个目的地址可能指向不同主机。访问 192.168.1.20,系统可能优先选择本地直连接口,报文根本没有进入 VPN。此时隧道状态正常、认证成功,仍然无法访问公司服务。第一步应查看路由选择和本地地址,而不是反复重启 VPN 进程。
长期修复通常是重新规划不重叠的网段;临时方案可能采用专门的映射地址或更具体的路由,但必须评估本地访问损失与维护成本。给某个地址增加更具体的路由,可能让同地址的家庭设备不可达。NAT 可以帮助映射重叠地址,却会增加日志解释和双向访问的复杂度,不能靠随意增加地址转换规则掩盖地址规划问题。
另一个常见遗漏是只检查主路由表。Linux 可以根据来源等条件使用不同路由表。主表里有 VPN 路由,不代表来自某个地址的流量也会命中它。下面的只读命令用于发现是否存在额外规则;10.20.0.10 应替换成实际测试来源,并在承担该路径选择的主机或网关执行。
ip rule show
ip route show table all
ip route get 10.60.0.20 from 10.20.0.10
如果业务运行在容器或独立网络命名空间中,宿主机 shell 的路由结果也可能不能代表业务进程。应记录进程所在网络环境,在相同环境中检查接口、路由和解析。相似地,curl 可能使用代理环境变量,实际连接的是代理服务器。排查前确认请求目标与应用配置,才能避免用直接连接实验解释代理连接的故障。
还有 2 类容易误判的现象。其一是服务名解析失败:检查 getent ahosts 服务名,将解析结果与预期地址对照。其二是小请求正常、大传输停顿:隧道封装增加额外开销,可能暴露路径 MTU 问题。应先记录报文大小相关性,再沿隧道内外检查,不要直接禁用加密或任意降低所有接口的 MTU。
例如外层路径允许的 IP 报文最大为 1500 字节,某种隧道在当前配置下增加 80 字节开销,那么内部 1500 字节报文封装后就无法原样通过,内部可用上限至多为 1420 字节。这里的开销只是算例,实际值取决于外层地址族、封装协议和加密参数。若外层 IPv4 报文不允许分片,中间设备应丢弃超限报文并返回需要分片的 ICMP 错误;错误若被过滤,发送端可能一直重传原大小报文,形成路径 MTU 黑洞。外层 IPv6 路由器也不会替发送端分片,需要依靠 Packet Too Big 消息反馈限制。
这解释了为什么隧道握手、小型探测都成功,下载文件却停住:前两者可能根本没有触及大小上限。排查时可在授权实验中逐步改变测试报文大小,同时对照隧道接口和物理出口,寻找超限丢弃或 ICMP 反馈。即使没有收到错误,也不能直接断定路径支持该大小,因为反馈本身可能不可达。调整隧道 MTU 后,要用实际大文件传输验证双向结果;TCP 的 MSS 限制只能影响相应 TCP 流量,不能修复 UDP 大报文,也不能替代正确的路径 MTU 处理。
另一种现象是刚连接时可用,空闲后对端主动发送就失败。若 VPN 使用 UDP 承载外层流量,家庭路由器可能在空闲超时后删除 NAT 映射。VPN 进程仍保留会话,并不意味着路由器仍知道该把入站报文交给哪台终端。终端重新发出报文后可能建立新映射,表现为访问一次便恢复。应对照空闲时长、两端外层地址端口以及网关转换状态,区分映射消失与凭据过期;若实现支持,可按实际超时配置保活,代价是持续流量和终端耗电。
保活只能维持已经建立的可用路径,不能让任意入站报文穿过多层 NAT。家庭路由器外侧若仍是运营网络的私有地址,只在家庭设备上配置端口映射,不会自动获得公网入口。此时应确认双方谁能主动连接到可达端点,必要时采用受控的中继或调整接入拓扑。验收要分别覆盖首次建立、长时间空闲和出口地址变化后的重连,不能用一次短请求代表隧道长期可用。

7 案例:错误 SNAT 导致的回程黑洞
某实验站点的客户端 10.20.0.10 通过 VPN 访问机房文件服务 10.60.0.20:443。设计要求保留客户端来源,机房已有指向 10.20.0.0/24 的隧道路由。但站点网关保留了一条范围过宽的 SNAT 规则,把所有来自内网的流量都改成出口地址 192.0.2.10,没有限定目的范围或实际出口,连进入 VPN 的流量也被改写。
用户看到的现象是连接超时,VPN 管理界面却显示已连接。客户端抓包能看到 SYN 重传,网关也能看到隧道流量增加。仅凭这些证据,不能判断机房服务拒绝连接,更不能判断加密算法有问题。需要继续确认机房收到的内部报文是什么来源,以及它准备怎样回复这个来源。
机房服务器观察到的来源是 192.0.2.10,而不是预期的 10.20.0.10。在这个实验中,服务策略允许该测试请求,服务器发出 SYN-ACK;机房网关却把发往 192.0.2.10 的回包交给普通默认路由,没有送回 VPN。该外侧路径没有通往这个实验地址的有效后续转发,于是回包消失。这里的“黑洞”指报文进入了不能完成交付的路径。
关键证据由 3 项组成:站点隧道出口前后的来源对照、机房服务端的请求与响应、机房网关对响应目的的路由选择。它们共同说明错误发生在地址身份和回程选择的组合上。若只在客户端观察超时,就无法区分服务未监听、过滤丢弃与回程偏离。若只看隧道计数器增长,也无法证明承载的是正确地址的业务流量。
修复应把出口 SNAT 约束到确实需要转换的流量,确保站点到机房的路径保留设计中的来源,同时确认双方路由和允许规则匹配。具体修改必须依照现有规则集进行,不能把另一台设备上的规则编号照搬过来。变更前保存相关配置,明确撤销方式;变更后用新的 TCP 连接测试,避免已有连接状态继续保留旧映射而干扰判断。
验收时重新查看客户端、站点网关和机房服务端。请求来源应恢复为 10.20.0.10,机房回程应进入 VPN,客户端应完成连接并获得服务响应。还要抽查正常互联网出口仍按原设计转换,证明规则收窄没有破坏其他用途。本案例的重点是让每条地址转换规则具有明确范围,并用对端实际看到的地址验证设计。

8 把地址转换与隧道写进网络方案
可执行的网络方案要同时描述地址、路径与权限。先列出客户端网段、服务网段、VPN 地址池、隧道外层端点和所有转换地址,标注哪些地址属于业务身份,哪些只用于运输。若表中出现相同网段分配给不同位置,就必须在上线前处理,不能把冲突留给用户终端自行选择。
接着为每类流量写出转换前后的关系。例如互联网出口为“10.20.0.0/24 经指定外侧接口访问外部时使用出口地址”,机房访问为“目的 10.60.0.0/24 进入 VPN 并保留来源”。入口发布则写清外部地址端口、内部地址端口、协议、允许来源以及回程网关。这样才能发现规则重叠,也能让审计者理解日志中的地址属于哪个阶段。
隧道部分应说明端点责任、接入身份、路由范围、DNS 使用方式和退出后的清理行为。连接建立、断开、凭据失效分别会产生什么状态,需要有可观察结果。尤其要说明 VPN 故障后内部目标是立即不可达,还是可能落到其他出口;应按组织要求配置相应路由与过滤,不能依赖用户发现异常后手动断网。
验证也应写成能复现的步骤:在指定客户端发起指定协议请求,在网关内外侧和隧道对端检查地址,再确认响应沿预期路径返回。ping 可以提供部分可达性证据,但它不代表目标 TCP 端口、应用认证或文件权限正常。文件服务验收还应以授权账号读取指定测试文件,避免把网络通达误当作业务授权已经通过。
最后把变更边界写进维护记录:涉及哪台设备、哪些规则、何时执行、由谁恢复、保留哪些去敏证据。NAT 状态和 VPN 会话可能影响既有连接,因此成功验证应明确使用了新连接还是持续连接。把配置、观测和业务结果放在同一条验收记录中,后续排查才能区分设计变化、环境变化和偶发故障。
9 从 NAT/VPN 走向负载均衡(S36)
现在可以区分 3 个不同层次的问题:路由决定报文往哪里走,NAT 决定经过某处后地址如何呈现,VPN 决定哪些流量通过怎样的隧道运输。它们共同帮助请求到达服务,但还没有回答“有多台服务主机时,应该把新请求交给谁”。这个选择将进入 S36 的负载均衡主题。
假设内部有 10.60.0.20 和 10.60.0.21 两台服务主机,简单端口映射只指向前者。即便后者正常运行,前者停止监听时,这条映射也不会自然知道该切换目标。需要某种机制选择后端、判断后端是否可用,并处理选择变化对连接的影响。不要把“配置了 2 个地址”直接理解为已经获得容错能力。
负载均衡可能与 NAT 同时出现,也可能通过代理建立新的后端连接。学习下一课时,应继续追问客户端地址在哪里保留、连接在哪个位置结束、返回报文经过谁。现阶段无需展开调度算法或内部实现,只要保持对地址和路径的敏感,就能识别很多看似相同、实际不同的部署方式。
在进入下一课前,试着口头解释本课案例:为什么请求进入隧道仍然会失败,为什么对端看到的源地址会影响回程,以及为什么修复以后必须建立新的连接测试。能把这些关系说清楚,比记住某条防火墙命令更有迁移价值。具体工具会改变,转换前后报文与双向路径的核对方法仍然适用。
放进方案里
把本课落到方案时,先提交地址与路径表。表中列出客户端、服务端、网关内外接口、VPN 端点与接入地址池,明确网段归属并检查重叠。每类访问都要写出原始源与目的、转换后的源与目的、选用接口和回程下一跳。采用示例地址编写草案时,交付前必须替换成实际分配结果,不能把文档保留地址直接用于生产连接。
再提交访问矩阵:哪些人员或站点通过何种身份接入,可以访问哪些目标协议与端口,是否保留来源,是否使用内部 DNS。选择分流或全隧道时,写明中心出口承载范围和故障影响。入口端口映射还要列出允许来源及撤销方式;“已做 NAT”或“已连 VPN”都不能替代明确的访问授权。
验收记录至少覆盖正常访问、禁止访问和路径故障。正常访问要观察请求与响应,确认服务端看到的来源符合设计;禁止访问要确认限制真正生效;路径故障要观察隧道断开后流量去向及恢复结果。测试使用授权账号和无敏感内容的测试文件,保存必要的时间、接口、地址与命令结果,避免把密钥、令牌或业务正文纳入附件。
变更单写清规则范围、执行设备、恢复步骤和负责人。已有连接可能继续使用原转换状态,因此验证必须注明是否重新建连;不要通过清空全部连接状态来追求快速见效。交付时让接手者能够根据记录重现访问,指出报文在哪个位置改地址、在哪个位置进出隧道,并在失败时找到下一个观察点。做到这些,网络方案才具备可执行、可验收和可维护的基础。
10 小结:下一步负载均衡(S36)
NAT 改写地址或端口,VPN 为指定流量建立隧道;通信能否完成,还取决于路由、转发、过滤、解析与应用状态。排查时对照转换前后、隧道内外及请求回程,用实际报文解释超时。
自测:SNAT 后服务端看到谁?端口映射为什么需要正确回程?VPN 已连接但目的路由走本地接口时,请求会去哪里?S36 将在这条双向路径上加入多台后端,讨论如何选择服务目标并应对后端失效。