WireGuard:以密钥与路由为核心的 VPN 隧道

先给结论

WireGuard 是一个基于 UDP 的三层加密隧道协议与实现。每台设备创建一个网络接口,并通过静态公私钥配置彼此为 peer;发送方依据目标地址选择 peer、封装并加密 IP 包,接收方仅接受与该 peer 的 AllowedIPs 相符的流量。它的配置面小、会话密钥自动轮换,并能在已认证包到来时更新 peer 的公网 Endpoint,因而适合远程接入、站点互联和为服务构建受控私网。^[来源:WireGuard Protocolwg(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。
Endpointpeer 的可达 UDP 地址对主动连接的客户端通常必填;已认证报文可使对端学习到新的源地址和端口。
AllowedIPs目标路由选择与入站地址约束它既不是单纯 ACL,也不是自动生成所有 OS 路由的通用网络策略。
PersistentKeepalive维持 NAT/有状态防火墙映射默认关闭;通常只在 NAT 后、需要长期被动接收的 peer 上设置。

协议使用 Noise IK 握手,并采用 Curve25519、ChaCha20-Poly1305、BLAKE2s 与 HKDF 等构件;所有协议包通过 UDP 发送。握手会定期换出会话密钥,以获得前向保密等属性。可选 PresharedKey 会混入额外对称密钥材料,但不应被当成私钥泄漏后的万能补救。^[来源:WireGuard Protocolwg(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 wg0

wg-quick 会处理接口地址与 AllowedIPs 对应路由等便捷操作;AddressDNSMTUTable 以及 PostUp 等字段是它的扩展,而非裸 wg setconf 的通用配置字段。停止接口可使用 sudo wg-quick down wg0。^[来源:WireGuard Quick Startwg-quick(8)]

AllowedIPs:最容易配置错的字段

对某个 peer 而言,AllowedIPs 同时表达两件事:

  1. 出站选择:本机要发往这些前缀的包,应该封装给该 peer。
  2. 入站校验:从该 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 showlatest 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 的服务发布模型不等同于用户、设备和网段级私网接入。

运维与安全清单

  1. 每个设备独立生成密钥;私钥文件用 umask 077 和最小文件权限保护,密钥轮换时先增加新 peer、验证后再删除旧 peer。
  2. 服务端仅放行实际监听的 UDP 端口,管理服务只监听 WireGuard 地址或受控管理网;不要因 WireGuard 可达而公开管理端口。
  3. AllowedIPs 按最小网段分配,检查 peer 间重叠;站点互联还要验证正反向路由与防火墙规则。
  4. 仅对确有入站需求的 NAT 后 peer 启用 PersistentKeepalive;记录其资源与电量影响。
  5. wg show 观察最近握手、Endpoint、收发计数;配置更新可使用 wg syncconf wg0 <(wg-quick strip wg0),以避免不必要地中断活动会话。^[来源:wg(8)wg-quick(8)]

开放问题

  • 多 peer、重叠网段、容器网络命名空间与策略路由同时存在时,如何用网络图和自动化检查证明路由没有泄漏?
  • 团队设备的密钥生命周期如何与人员离职、设备丢失、审批和审计流程结合,而不把私钥集中进普通配置仓库?
  • 对需要精细用户授权的内部应用,WireGuard 的网络层可达性应如何与身份代理和应用授权组合?