WireGuard原本是我在使用OpenVPN后发现的一个挺不错的VPN技术。
由于最开始我是被它极简的配置文件所吸引来学习并使用的,所以本篇文章也从配置文件入手来讲解它。
为了方便讲解,我们先假设一个情景。
现在有一台拥有公网IP的服务器(Server)、一台电脑(PC)和一台手机(Phone),PC和Phone要使用WireGuard创建VPN隧道连接Server访问其内网服务。
配置文件示例
Server配置示例
# 本机配置
# Server
[Interface]
PrivateKey = <SERVER_PRIVATE_KEY>
Address = 10.0.0.1/24
ListenPort = 51820
MTU = 1420
# 对端配置
# PC
[Peer]
PublicKey = <PC_PUBLIC_KEY>
AllowedIPs = 10.0.0.2/32
# Phone
[Peer]
PublicKey = <PHONE_PUBLIC_KEY>
AllowedIPs = 10.0.0.3/32PC配置示例
# 本机配置
# PC
[Interface]
PrivateKey = <PC_PRIVATE_KEY>
Address = 10.10.0.2/32
DNS = 10.0.0.1
MTU = 1420
# 对端配置
# Server
[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
AllowedIPs = 0.0.0.0/0
Endpoint = <SERVER_PUBLIC_IP>:51820
PersistentKeepalive = 25Phone配置示例
# 本机配置
# Phone
[Interface]
PrivateKey = <PHONE_PRIVATE_KEY>
Address = 10.10.0.3/32
DNS = 10.0.0.1
MTU = 1420
# 对端配置
# Server
[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
AllowedIPs = 0.0.0.0/0
Endpoint = <SERVER_PUBLIC_IP>:51820
PersistentKeepalive = 25简单十几行就能创建连接的,相比于OpenVPN的配置来说真的强了不少。
配置字段解析
WireGuard不主动区分谁是客户端谁是服务端,而是区分本机(Interface)与对端(Peer),但是由于在实际环境中公网IP并不容易获取所以通常会把拥有公网IP的终端作为服务端。
服务端
客户端
从简单密码学理解PrivateKey与PublicKey
首先需要知道一下两点,这也是非对称加密的关键:
私钥与公钥成对出现
私钥能轻松计算公钥,但公钥计算私钥困难
或许你会惊奇的发现:欸!为什么配置文件里面存储的PublicKey不是本机的PublicKey?
所以下面展示一下简要的加密流程(实际并非如此简单):
客户端发起请求使用服务端公钥加密客户端公钥,传递给服务端
服务端使用私钥解密并确认客户端公钥正确,使用客户端公钥加密服务端公钥,传递给客户端
客户端使用私钥解密并确认服务端公钥正确
客户端使用私钥与服务端公钥运算出对话密钥,后续对话使用该密钥加密
服务端使用私钥与客户端公钥运算出对话密钥,后续对话使用该密钥加密
多层NAT环境下的MTU
MTU 的基本原理
MTU(Maximum Transmission Unit,最大传输单元)是指一条网络链路能够承载的最大网络层数据包大小,通常以字节为单位。
以太网常见 MTU 为 1500 字节,即单个 IP 数据包的总长度通常不能超过 1500 字节。MTU 不代表网速或总传输量,而是限制单个数据包的大小。
当数据包超过链路 MTU 时,可能发生 IP 分片、数据包丢弃或发送端调整数据包大小等情况,具体取决于协议和网络设备的处理方式。
VPN 为什么需要考虑 MTU?
VPN 会对原始 IP 数据包进行加密和封装,在外层增加 IP、UDP 及 VPN 协议头部,从而增加数据包的总长度。
以常见的 WireGuard over IPv4 为例,封装开销通常约为 60 字节:
外层 IPv4 头:20 字节
UDP 头:8 字节
WireGuard 数据头及认证标签:约 32 字节
假设外层路径 MTU 为 1500 字节,则内层 IP 数据包的理论上限约为:
1500 − 20 − 8 − 32 = 1440 字节
因此,WireGuard 常用 MTU 设定值为 1420,但实际合适的数值取决于底层网络、外层 IP 版本及其他封装开销。
多层 NAT 环境下 MTU 的必要性
多层 NAT 本身并不必然要求降低 MTU。 NAT 主要修改 IP 地址和端口,通常不会像 VPN 隧道一样额外增加一整套封装头部。
真正影响 MTU 的因素包括:
路径最小 MTU:数据包必须能够通过整条传输路径中 MTU 最小的链路。
VPN 封装开销:封装后的外层数据包必须符合底层网络的 MTU 限制。
路径 MTU 发现(PMTUD):依赖网络设备通过 ICMP 等机制反馈数据包过大的问题。如果相关报文被防火墙过滤,可能导致发送端无法及时调整数据包大小。
额外隧道封装:如果 VPN 流量还经过其他 VPN、隧道或特殊网络链路,可用 MTU 可能进一步减小。
因此,多层 NAT 环境下是否需要调整 MTU,应根据实际传输路径判断,而不是简单地按照 NAT 层数计算。
MTU 不合适的典型表现
VPN 显示已连接,但网页加载不完整或停顿。
小型 Ping 请求正常,大数据包传输失败。
文件传输速度异常,或者部分网络服务无法正常使用。
这些现象可能与 MTU 不匹配或路径 MTU 发现失效有关,但也可能由防火墙、路由或其他网络问题导致。
WireGuard 的 MTU 设置建议
网络正常时,优先使用客户端或软件的默认 MTU。
常规 IPv4 WireGuard 场景可以从 1420 开始测试。
如果存在移动网络、PPPoE、额外隧道封装或大数据包传输异常,可以尝试 1400、1380 等数值。
调整后应测试不同大小的数据包和实际业务,而不只是确认 VPN 是否能够连接。
设计巧妙的AllowedIPs
AllowedIPs 的作用
AllowedIPs 是 WireGuard 配置中用于指定某个 Peer 所对应的 IP 地址范围的参数,它兼具两种功能:
路由选择:决定哪些目标 IP 地址的流量应该通过哪个 Peer 发送。
来源地址校验:接收数据时,验证解密后的数据包源 IP 是否属于该 Peer 被允许使用的地址范围。
例如:
[Peer]
PublicKey = CLIENT_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32这表示该 Peer 对应 10.0.0.2 这个地址。发送到该地址的流量会选择这个 Peer;接收到来自该 Peer 的数据时,WireGuard 也会检查其源 IP 是否符合配置。
AllowedIPs 设计的巧妙之处
将路由选择与身份授权结合
传统网络中,路由表负责决定数据包发往哪里,访问控制机制则负责判断数据包是否有权使用某个地址。WireGuard 将 Peer 与 IP 地址范围关联起来,使路由选择和来源地址校验共享同一份配置,减少了配置复杂度。
以公钥识别 Peer,以 IP 范围约束其行为
WireGuard 使用公钥识别通信对端,而 AllowedIPs 规定这个 Peer 可以代表哪些源 IP 地址。即使数据包能够通过加密认证,如果其解密后的源 IP 不属于该 Peer 被允许的范围,也不会被接受。
支持灵活的网络拓扑
AllowedIPs 可以使用单个主机地址,也可以使用 CIDR 网段:
AllowedIPs = 10.0.0.2/32只允许对应单个 IPv4 地址。
AllowedIPs = 10.0.0.0/24覆盖整个 10.0.0.0/24 网段。
AllowedIPs = 0.0.0.0/0匹配所有 IPv4 目标地址,常用于 IPv4 全隧道配置。
让配置本身表达网络边界
通过为不同 Peer 指定不同的 IP 范围,可以明确哪些地址归哪个 Peer 负责。例如,服务器为每个客户端分配独立的 /32 地址,既便于路由,也能避免客户端冒用其他客户端的 VPN 地址。
额外的可选配置字段
WireGuard还有一些其他的配置字段,我没怎么用到过。