兰 亭 墨 苑
期货 · 量化 · AI · 终身学习
首页
归档
编辑文章
标题 *
URL 别名 *
内容 *
(支持 Markdown 格式)
#IP / Port 变化时,连接不需要重建、不中断、甚至不需要“感知恢复 这是 **WireGuard 最“魔法”的地方之一**: **IP / Port 变化时,连接不需要重建、不中断、甚至不需要“感知恢复”。** 结论先行一句话: > **WireGuard 根本不把“连接”绑定在 IP/Port 上,而是绑定在密钥身份上。** 下面我从 **机制 → 数据路径 → 时序 → 边界条件** 四个层次,把它彻底拆开。 --- ## 一、WireGuard 的“连接”到底是什么? 在 WireGuard 里: | 传统 VPN | WireGuard | |--------|-----------| | 连接 = TCP/UDP 会话 | **连接 = 公钥身份 + 会话密钥** | | IP/Port 是身份的一部分 | **IP/Port 只是“最近一次可达路径”** | | 断链要重连 | **路径变了自动学习** | ✅ **IP/Port 不是连接的锚点** 真正的锚点是: ``` Peer Public Key → Session (Noise IK) ``` --- ## 二、核心设计:Endpoint 是“可学习”的 在 `struct wg_peer` 里,有一个非常关键的字段: ```c struct endpoint endpoint; ``` 这个 endpoint: - ✅ **不是配置死的** - ✅ 可以被运行时更新 - ✅ 每次收到合法数据包都可能刷新 --- ## 三、IP/Port 变化时发生了什么?(完整时序) 我们假设一个最常见的场景: > 手机从 **Wi‑Fi → 4G** > IP 变了,端口也变了 --- ### 🟢 第 1 步:客户端发送任意 WireGuard 数据包 - 可能是: - keepalive - 数据包 - rekey 包 - 使用 **已有会话密钥** 加密 - UDP 源 IP / Port 已经变了 --- ### 🟢 第 2 步:服务端收到 UDP 包 服务端做的第一件事**不是**: ❌ “你 IP 变了,拒绝” 而是: ✅ **先尝试解密** 流程是: ``` UDP 包 → 解析 WireGuard 消息类型 → 用所有 peer 的 key 尝试匹配 → 找到能成功解密的 peer ``` > ⚠️ 这里的查找是 **基于 key,而不是 IP** --- ### 🟢 第 3 步:认证成功 → 更新 endpoint 一旦解密 + 认证成功: ```c peer->endpoint = skb->src_ip:src_port; ``` ✅ **endpoint 被原子性更新** 这一步叫: > **Endpoint Roaming** 而且是: - 无日志 - 无状态切换 - 无 reconnect --- ### 🟢 第 4 步:后续所有包都走新路径 之后服务端发包: ``` peer->endpoint → 新 IP/Port ``` 旧路径自然失效。 --- ## 四、为什么这样做是安全的? 关键在于这条铁律: > **只有能通过 Noise 认证的包,才有资格更新 endpoint** 也就是说: - ❌ 伪造源 IP 不行(解不开) - ❌ 猜端口不行 - ❌ 重放旧包不行(counter / replay window) --- ## 五、代码层面的“无感知”来源 ### 1️⃣ 查找 peer 不靠 IP 核心路径: ```c wg_receive_handshake_packet() wg_receive_data_packet() ``` 它们最终都是: ``` → 根据 key 找 peer → 而不是根据 src IP ``` --- ### 2️⃣ endpoint 更新是“副作用” 你可以理解为: ```text “如果你能证明你是谁, 那你现在从哪来我就信” ``` 所以 endpoint 更新只是: - 一次 `memcpy` - 一次 RCU-safe 更新 - 不影响 fast path --- ### 3️⃣ Keepalive 的真实意义 很多人误解 keepalive 是“保活连接”。 实际上它是: > **NAT 穿透 + endpoint 探测包** - 保证 NAT 映射不消失 - 确保对端知道“我现在在哪” --- ## 六、为什么 TCP VPN 做不到? 因为 TCP: - ✅ IP/Port 是连接五元组的一部分 - ❌ IP 变了 = 连接必断 - ❌ NAT 变化 = RST / timeout WireGuard: - ✅ UDP 无连接 - ✅ 自己在加密层维护“逻辑会话” - ✅ 会话 ≠ 传输路径 --- ## 七、几个非常重要的边界条件(容易踩坑) ### ⚠️ 1. 双方都在 NAT 后面? - ❌ 无法首次建立连接 - ✅ 但一旦建立,**双方 roaming 都没问题** - 解决方案:中继 / 固定一端公网 --- ### ⚠️ 2. 长时间完全静默? - NAT 映射过期 - 下一包可能丢 - ✅ **PersistentKeepalive** 就是为这个准备的 --- ### ⚠️ 3. 同一 peer 同时从两个 IP 发包? - WireGuard **最后一个成功认证的 endpoint 生效** - 不是负载均衡 - 是“单活” --- ## 八、一句话总结“无感知恢复”的本质 > **WireGuard 把“身份”和“路径”彻底解耦了。** - 身份:公钥(不可伪造) - 会话:Noise state - 路径:随时可变、随时学习 所以: > **IP/Port 变化不是异常,只是一次新的事实被观察到。** ---
配图 (可多选)
选择新图片文件或拖拽到此处
标签
更新文章
删除文章