WireGuard:以密钥与路由为核心的 VPN 隧道
先给结论
WireGuard 是一个基于 UDP 的三层加密隧道协议与实现。每台设备创建一个网络接口,并通过静态公私钥配置彼此为 peer;发送方依据目标地址选择 peer、封装并加密 IP 包,接收方仅接受与该 peer 的 AllowedIPs 相符的流量。它的配置面小、会话密钥自动轮换,并能在已认证包到来时更新 peer 的公网 Endpoint,因而适合远程接入、站点互联和为服务构建受控私网。^[来源:WireGuard Protocol、wg(8)]
WireGuard 不是用户身份系统、访问审计平台或应用层授权的替代品:它把“哪把密钥可以从哪些隧道 IP/网段收发包”落实到网络层;应用仍应使用自身的账号、授权、日志和最小权限。它也不会自动转发或 NAT 内网/互联网流量,路由、内核转发和防火墙仍须按部署目标单独设计。
组件与数据路径
客户端应用
│ 明文 IP 包(目标决定匹配哪个 peer)
▼
客户端 wg0 ── UDP 加密数据报 ── 公网 / NAT ── UDP 加密数据报 ── 服务端 wg0
10.66.0.2/32 10.66.0.1/24
│ │
└──────────── 仅路由到 AllowedIPs 覆盖的网段 ──────────────────┘| 对象 | 作用 | 关键边界 |
|---|---|---|
wg0 | 操作系统网络接口 | WireGuard 只加密与封装 IP 包;接口地址、路由、DNS 和防火墙仍由系统管理。 |
| 私钥 / 公钥 | peer 身份与握手材料 | 私钥绝不能共享或提交;公钥可带外分发,服务端只为已批准的公钥配置 peer。 |
Endpoint | peer 的可达 UDP 地址 | 对主动连接的客户端通常必填;已认证报文可使对端学习到新的源地址和端口。 |
AllowedIPs | 目标路由选择与入站地址约束 | 它既不是单纯 ACL,也不是自动生成所有 OS 路由的通用网络策略。 |
PersistentKeepalive | 维持 NAT/有状态防火墙映射 | 默认关闭;通常只在 NAT 后、需要长期被动接收的 peer 上设置。 |
协议使用 Noise IK 握手,并采用 Curve25519、ChaCha20-Poly1305、BLAKE2s 与 HKDF 等构件;所有协议包通过 UDP 发送。握手会定期换出会话密钥,以获得前向保密等属性。可选 PresharedKey 会混入额外对称密钥材料,但不应被当成私钥泄漏后的万能补救。^[来源:WireGuard Protocol、wg(8) 配置格式]
最小的点对点远程接入
以下示例仅让客户端访问隧道网段 10.66.0.0/24。它不把客户端所有互联网流量导入隧道,也不隐含对其他内网的访问。示例密钥均为占位符,必须由每台主机本地生成。
先在每台 Linux 主机上生成自己的密钥对:
umask 077
wg genkey | tee privatekey | wg pubkey > publickey服务端 /etc/wireguard/wg0.conf:
[Interface]
Address = 10.66.0.1/24
ListenPort = 51820
PrivateKey = <SERVER_PRIVATE_KEY>
[Peer]
# 客户端的 publickey;服务端不需要为这个 NAT 后客户端配置 Endpoint。
PublicKey = <CLIENT_PUBLIC_KEY>
AllowedIPs = 10.66.0.2/32客户端 /etc/wireguard/wg0.conf:
[Interface]
Address = 10.66.0.2/32
PrivateKey = <CLIENT_PRIVATE_KEY>
[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
Endpoint = vpn.example.com:51820
AllowedIPs = 10.66.0.0/24
# 仅当客户端位于 NAT/防火墙后且需要长期接收入站包时启用。
PersistentKeepalive = 25放行服务端的 51820/udp 后,在两端执行:
sudo wg-quick up wg0
sudo wg show wg0wg-quick 会处理接口地址与 AllowedIPs 对应路由等便捷操作;Address、DNS、MTU、Table 以及 PostUp 等字段是它的扩展,而非裸 wg setconf 的通用配置字段。停止接口可使用 sudo wg-quick down wg0。^[来源:WireGuard Quick Start、wg-quick(8)]
AllowedIPs:最容易配置错的字段
对某个 peer 而言,AllowedIPs 同时表达两件事:
- 出站选择:本机要发往这些前缀的包,应该封装给该 peer。
- 入站校验:从该 peer 解密出的包,其源地址必须属于这些前缀。
因此服务端为每个远程客户端分配一个唯一 /32(IPv6 为 /128)通常是安全的起点;不要把同一隧道地址或宽泛的 0.0.0.0/0 随意分给多个 peer。站点互联时,服务端可把某 peer 后面的 LAN 前缀写入该 peer 的 AllowedIPs,但应确保所有 peer 的路由前缀不产生非预期重叠。^[来源:wg(8)]
AllowedIPs = 0.0.0.0/0, ::/0 表示全隧道:IPv4 与 IPv6 默认流量都可选到该 peer。wg-quick 对默认路由会使用策略路由机制,避免立刻把到 WireGuard Endpoint 本身的包送进隧道;但服务端仍必须提供 IP 转发、回程路由或 NAT、DNS 和 IPv6 策略。全隧道应同时测试 IPv4、IPv6 与 DNS,避免出现“流量绕过隧道”或“客户端失联”。^[来源:wg-quick(8)]
NAT、漫游与保活
WireGuard 在没有业务数据时默认保持静默。若一个 peer 位于 NAT 或有状态防火墙之后,却要在长时间空闲后接收服务端的新流量,可用 PersistentKeepalive = 25 周期性发送认证空包,维持映射;不需要这种可达性时应保持默认关闭。这个值不是“提升连接质量”的通用调优参数。^[来源:WireGuard Quick Start]
peer 的 Endpoint 不是严格绑定的静态身份。WireGuard 会在收到正确认证的数据包时,将 endpoint 更新为最近的源 IP/端口,因此移动网络、切换 Wi-Fi 或 NAT 端口变化通常无需重建配置。可达性失败时先检查 UDP 防火墙、DNS、路由与两端时间,再看 wg show 的 latest handshake、端点和收发字节;不要通过放宽 AllowedIPs 来掩盖网络问题。^[来源:wg(8)]
部署模式与已有知识的关系
| 需求 | WireGuard 的合适角色 | 不应混淆的能力 |
|---|---|---|
| 远程管理私有服务 | 让运维设备加入受控私网,再访问私有地址 | 仍须限制 SSH/后台账号、来源网段与审计。 |
| 两个 LAN 互联 | 在两侧 peer 的 AllowedIPs 写入对端 LAN 前缀,并配置转发/防火墙 | 不等于自动处理 LAN 内所有路由、DHCP 或 DNS。 |
| 全隧道出网 | 客户端默认路由经服务器,服务器承担转发/NAT 或有可达回程 | 必须测试 IPv4、IPv6、DNS、MTU 与断网保护。 |
| 公开单个 Web 服务 | 通常优先由 Caddy 提供 TLS 和 HTTP 路由 | VPN 不应被当作公开 Web 入口的替代。 |
| 将内网服务临时暴露到公网 | FRP 可代理明确的服务端口或域名 | FRP 的服务发布模型不等同于用户、设备和网段级私网接入。 |
运维与安全清单
- 每个设备独立生成密钥;私钥文件用
umask 077和最小文件权限保护,密钥轮换时先增加新 peer、验证后再删除旧 peer。 - 服务端仅放行实际监听的 UDP 端口,管理服务只监听 WireGuard 地址或受控管理网;不要因 WireGuard 可达而公开管理端口。
AllowedIPs按最小网段分配,检查 peer 间重叠;站点互联还要验证正反向路由与防火墙规则。- 仅对确有入站需求的 NAT 后 peer 启用
PersistentKeepalive;记录其资源与电量影响。 - 用
wg show观察最近握手、Endpoint、收发计数;配置更新可使用wg syncconf wg0 <(wg-quick strip wg0),以避免不必要地中断活动会话。^[来源:wg(8)、wg-quick(8)]
开放问题
- 多 peer、重叠网段、容器网络命名空间与策略路由同时存在时,如何用网络图和自动化检查证明路由没有泄漏?
- 团队设备的密钥生命周期如何与人员离职、设备丢失、审批和审计流程结合,而不把私钥集中进普通配置仓库?
- 对需要精细用户授权的内部应用,WireGuard 的网络层可达性应如何与身份代理和应用授权组合?