链路层:亲密的网络旅程(二十二):在互联网上架设一座“秘密空中立交桥”——隧道技术、GRE与PPTP深度解析
引言:为什么我们需要“套娃”式的网络传输?
你肯定遇到过这样的场景:在公司外面出差,想用咖啡馆的公共 Wi-Fi 访问公司内网的 ERP 系统或者内部文件服务器。但咖啡馆的 Wi-Fi 是不安全的,如果直接传输数据,你的账号密码甚至公司商业机密都可能被抓包窃取。
为了解决这个问题,工程师们发明了VPN(虚拟专用网络)。而支撑 VPN 这项神奇技术的底层骨架,就是我们今天要聊的“隧道(Tunneling)”。
让我们先来看看书上是怎么定义它的:
【穿插原文 1】
“在某些情况下,两台计算机通过 Internet 或其他网络建立一条虚拟链路是有用的。虚拟专用网络(VPN)提供这种服务。实现这类服务的最常用方法称为隧道。一般来说,隧道是在高层(或同等层)分组中携带低层数据。例如,在一个 IPv4 或 IPv6 分组中携带 IPv4 数据,或在一个 UDP、IPv4 或 IPv6 分组中携带以太网数据。”
【通俗解析】
这段话的核心关键就在“在高层分组中携带低层数据”。
简单来说,就是**“套娃”。你在公司内网发出一个正常的以太网数据包(内网 IP),到了网关这里,网关不会直接把它扔到公网去。网关会把它当成一封信,塞进一个新的、外面套着公网 IP 的“大信封”里**。然后,这个“大信封”在公网上飞到目的地,目的地(另一端的网关)再把里面的“小信”拆出来,还原成内网数据包。
这种**“双层包装”**的技术,就叫隧道技术。公共互联网只是它的一层“通道外壳”,真正的数据在隧道里面“安全行驶”。
【图片占位符:VPN 隧道概念图】
此处可插入一张示意图:左侧内部网络(内网 IP)-> VPN 隧道(外层公网 IP 包裹) -> 公共互联网云朵 -> VPN 隧道(拆包) -> 右侧企业内部网络。
第一部分:GRE——隧道最基础的“砖块”
实现隧道有很多种协议,但在互联网早期,最基础、最通用的就是GRE(通用路由封装)。它是隧道技术的“地基”。
1.1 基础版的 GRE 报头(RFC 2784)
书里先给我们展示了最经典的 GRE 报头结构。
【穿插原文 2】
“图 3-26 中基本的 GRE 头部只有 4 字节,包括一个 16 位的校验和选项(很多 Internet 协议中的典型选项)。后来,这个头部被扩展为包括一个标识符(密钥字段)、该标识符是同一流中的多个分组所必须的,还包括一个序列号(用于顺序混乱的分组重新排序)。”
结合书中的图 3-26,我们来看看这个 4 字节的基础报头长什么样:
【图片占位符:基础 GRE 报头结构图(RFC 2784)】
此处需插入图 3-26 的第一部分,展示:C(标志位,1位)、保留0(12位)、版本(3位)、协议类型(16位)、校验和(可选,16位)、保留1(可选,16位)。
- C 位(Flag):表示这个包里是否包含了“校验和”字段。
- 协议类型(Protocol Type):极其重要!它告诉外层的解包器:“我这个大信封里,装的是什么协议的包?”(比如装的是 PPP 协议的包,或者以太网协议)。
- 校验和(Checksum):用来检查整个 GRE 头和数据是否在路上损坏了。
1.2 进化版的 GRE 报头(RFC 2890)
原始的 GRE 有个致命弱点:它不负责区分“这是哪一个 VPN 连接的数据”。如果公司有 100 个员工同时连到 VPN 服务器,谁的数据是谁的?传统的 GRE 分不清。所以,后来出现了扩展版的 GRE 报头(RFC 2890)。
【穿插原文 3】
“RFC 2890 扩展了基本格式,包括可选的密钥和序列号字段,如 3-26 中的 K 和 S 位字段分别被设置为 1。如果校验和字段在多个分组中被分配了同样的值,表示它们是属于同一流中的分组。如果分组顺序被打乱(例如通过不同链路),可利用序列号字段对分组重新排序。”
【图片占位符:扩展 GRE 报头结构图(RFC 2890)】
此处需插入图 3-26 的第二部分,增加 K位、S位,以及后续的 密钥(可选,16位或32位)、序列号(可选,16位或32位)。
看到书里的公式了吗?
- 密钥(Key):相当于给同一个 VPN 隧道里的所有数据包发了同一个“通行证”。只有持有同样密钥的数据包,才是一家人。
- 序列号(Sequence Number):数据包有可能因为走得不同网络路径,导致后发的先到了。有了序列号,接收方就能把它们重新按 1、2、3 的顺序排好,保证数据不乱。
第二部分:PPTP——PPP 与 GRE 的绝佳联姻
PPTP(点对点隧道协议)是我们在上一章刚学完的 PPP 协议与 GRE 隧道结合出来的产物。它是早期 Windows 系统(如 XP、Vista)最常用的 VPN 协议。
【穿插原文 4】
“PPTP 本质上是在 GRE 和 PPP 的结合,因此 GRE 可基于 PPP 提供虚拟的点到点链路。GRE 使用 IPv4 或 IPv6 携带流量,因此它更像是一种第 3 层隧道技术。PPTP 常用于携带第 2 层帧(例如以太网),因此需要模拟一条直接的局域网(链路层)连接。例如,它可用于对企业网络的远程访问。”
通俗理解:
- 我们在拨号时,PPPoE 把 PPP 包套在以太网里。
- 在 VPN 中,PPTP 把 PPP 包套在GRE 隧道里。这样,不论你的家庭网络用的什么 IP,你的 PPP 包都能牢牢地通过 GRE 隧道传回公司。
【图片占位符:PPTP 报头结构图】
此处需插入图 3-27。这是一个比标准 GRE 报头更复杂的 PPTP 特定报头,展示了 C, R, K, S, Recurs, A, 标志, 版本, 协议类型, 密钥, 序列号, 确认号等。
第三部分:一场真实的 PPTP VPN 拨号“战役”——深读 Linux 日志(上)
理论说完了,书本接下来的篇幅,给我们展示了一段极度经典的Linux PPTP 服务器与 Windows Vista 客户端的连线真实日志。这段日志比我们上次学的 PPP 拨号更全面,因为它包含了“建立控制隧道”和“建立数据隧道”的完整流程。
【穿插原文 5】
“我们建立一个 PPTP 会话,稍后对 PPTP 的其他功能进行简单讨论。下面的例子类似于前面给出的 PPP 链路建立的例子,区别在于现在不使用拨号连接,PPTP 为 PPP 提供了一条‘原始’链路。第二个客户端使用 Windows Vista 系统,服务器使用 Linux 系统。当调试选项启用时,这个输出保存在 /var/log/messages 文件中:”
让我们把它切成三个阶段来细致观察。
3.1 第一阶段:握手准备(建立 TCP 控制连接)
PPTP 和普通的 GRE 隧道最大的不同是:PPTP 建立隧道之前,必须先跑一个 TCP 连接。这个 TCP 连接就是“VPN 的总指挥”,它位于 TCP 端口1723。
pptp: MGR: Manager process started pptp: MGR: Maximum of 100 connections available pptp: CTRL: Local address = 192.168.0.1 pptp: CTRL: Remote address = 192.168.1.1 pptp: CTRL: Received PPTP Control Message (type: 1) pptp: CTRL: Made a START CTRL CONN REPLY packet pptp: CTRL: I wrote 156 bytes to the client. pptp: CTRL: Sent packet to client pptp: CTRL: Received PPTP Control Message (type: 7) pptp: CTRL: Set parameters to 100000000 maxbps, 64 window size pptp: CTRL: Made a OUT CALL REPLY packet【通俗解析】
type: 1:客户端发来第一个消息,要求**“建立控制连接”**。type: 7:客户端发来第二个消息,要求**“发起外呼请求”**。这相当于在向 VPN 服务器申请:“我想连接你的内部网络!”window size 64:里面出现了“64 窗口大小”。这是 TCP 协议里的流量控制,后面书里特意提到 “设置非常大的值 100 000 000 bps”,这是不限制带宽的玩法。
3.2 第二阶段:隧道正式开挖(协商 GRE 隧道)
TCP 控制连接打通后,服务器开始正式建立基于GRE 协议(协议号 47)的隧道。
GRE: accepting packet #0 GRE: accepting packet #1 ... GRE: accepting packet #2【通俗解析】GRE: accepting packet #x表示 PPTP 的 GRE 隧道已经正式上线,后续所有经过 VPN 的真实数据包,都会通过 GRE 协议来传输。
3.3 第三阶段:安全审查与网络注册(隧道内的 PPP 握手)
现在,数据隧道通了,但是**“谁有资格上车呢?”** 这个时候,PPP 的经典套路在 GRE 隧道内部上演了。
pppd: sent [LCP ConfReq id=0x1 <asyncmap 0x0> <auth chap MS-v2> <magic 0x4e2ca200> <pcomp> <accomp>] pppd: rcvd [LCP ConfAck id=0x0 <mru 1400> <magic 0x5e565505> <pcomp> <accomp>] ... pppd: sent [CHAP Challenge id=0x1 ...] pppd: rcvd [CHAP Response id=0x1 ...] pppd: sent [CHAP Success id=0x1 "S=...M=Access granted"] ... pppd: sent [CCP ConfReq id=0x1 <mppe +H -M +S +L -D -C>] pppd: sent [IPCP ConfReq id=0x1 <addr 0.0.0.0> ...] pppd: sent [IPCP ConfAck id=0x1 <addr 192.168.0.1>]【通俗解析】
你看,这三行太熟悉了,就是我们上一章分析过的 PPP 握手流程:
- LCP协商链路参数。
- CHAP加密身份验证(顺利拿到
Access granted)。 - CCP商议使用 128 位的 MPPE 加密。
- IPCP分配 VPN 内部 IP 地址。
第四部分:隧道内部与流量控制——深读日志(下)
VPN 建立完成,数据开始传输后,还有哪些有趣的事情?书里继续给出了后续的日志。
pppd: local IP address 192.168.0.1 pppd: remote IP address 192.168.1.1 GRE: accepting packet #15 ppptd: CTRL: Sending ECHO REQ id 1 ppptd: CTRL: Made a ECHO REQ packet ppptd: CTRL: Sent packet to client【通俗解析】
local IP 192.168.0.1、remote IP 192.168.1.1:宣告拨号成功,VPN 链路正式成立。Sending ECHO REQ:这也是一个极为亮眼的细节!在 VPN 运行期间,VPN 服务器会定期发送ECHO REQ(类似 TCP 的 Keep-Alive 心跳包)。它用来探测:“客户端还在线吗?没掉线吧?”- 如果客户端没在规定时间内回复
ECHO REP,服务器就知道 VPN 断了,自动清空资源并重连。这就是 PPTP 的自愈流量控制机制。
第五部分:3.9.1 单向链路——不对等的“单行道”
在最后,书本抛出了一个新的挑战:单向链路(UDL)。
【穿插原文 6】
“当链路仅在一个方向工作时出现一个有趣的问题。这种在一个方向工作的链路称为单向链路(UDL),由于它们需要交换信息(例如 PPP 配置消息),因此前面介绍的很 多协议在这种情况下不能正常运行。为了解决这种问题提出了一种标准,可在辅助 Internet 接口上创建一条隧道,它可与 UDL 操作相结合。”
“典型情况是由卫星提供下行流量(流向用户)而拨号调制解调器提供上行流量而形成一条拨号链路。”
【通俗解析】
这在早期的卫星上网时代非常常见。你家有一个小锅(卫星天线),接收下行数据极快(比如几十 Mbps);但你要发数据上去(比如点播一个电影),由于没有上行天线,只能用家里的 56k 老式电话线拨号发请求。
这就导致“下发飞快,上行极慢”。传统的 TCP 协议是无法在这种极不对称的链路上正常工作的,因为 TCP 必须两方都有来有回(请求-确认)。
因此,工程界专门发明了UDL(单向链路)路由协议。它的解决思路类似于:让“快车道”(卫星下行)负责运货,让“慢车道”(电话线上行)只负责拿个对讲机喊话“货收到了”。
结语:隧道——穿越公共互联网的隐形捷径
今天,我们通过这几页书,完成了从“单点直连”到“跨越公网穿行”的宏大飞跃。
- 我们明白了什么是隧道技术:把内部数据装进外层包裹,搭建一座横跨互联网的空中天桥。
- 我们看清了GRE协议的内核:通过基本的 4 字节报头,赋予隧道以“通行证(密钥)”和“顺序(序列号)”。
- 我们拆解了PPTP协议的真实日志:见证了一个 VPN 连接从控制通道(TCP 1723)开启,到数据通道(GRE)建立,再到内部 PPP 安全认证的完整历程。
- 我们瞥见了单向链路的奇观:即使在卫星与电话线这种极不对称的链路上,工程界依然能用隧道和路由协议巧妙地解决问题。
当你现在连接到公司的企业 VPN,并看到右下角网络图标亮起时,你可以默默回想刚才那段日志:在那座看不见的空中天桥(GRE 隧道)里,您的账号密码经过了 CHAP 的质询握手,您的数据被加上了 128 位的 MPPE 加密锁,正安全地穿梭在互联网的广阔云端。
