WireGuard 组网实战:点对点与中心辐射两种拓扑的落地

跨机房、跨云的服务器之间要互通内网,传统做法是 IPsec 或 OpenVPN:配置项多、协商过程复杂,排障时一半时间花在确认参数对没对上。WireGuard 把这件事做到极简——没有证书体系,没有复杂的协商阶段,一对密钥就是一个节点的身份,配置文件十几行就能跑。本文以点对点、中心辐射(hub-spoke)两种拓扑为例,走通部署、转发、排障与密钥轮换全流程。示例环境为 Rocky Linux 9(Ubuntu 22.04 差异处注明),内核 5.6 以上已内置 WireGuard 模块,只需装用户态工具 wireguard-tools。

先讲清模型:密钥即身份,AllowedIPs 一词两义

WireGuard 的核心概念叫 Cryptokey Routing:每个节点持有一对 Curve25519 密钥,私钥不出本机,公钥就是它在网络里的身份。配置文件里每个 [Peer] 段写明「某个公钥,对应哪些 IP 段」,接口按这张表做两件事。理解 AllowedIPs 的双重语义是配好 WireGuard 的关键,新手的大半故障都源于此:

  • 出方向(路由语义):发包时查哪位 Peer 的 AllowedIPs 覆盖了目标地址,就用其公钥加密发出——它本质上是接口内的一张路由表。
  • 入方向(白名单语义):收到某 Peer 解密后的包,检查源 IP 是否在其 AllowedIPs 内,不在直接丢弃——等于一条按源地址过滤的防火墙规则。

推论有两个。第一,隧道地址(本文用 10.66.0.0/24)必须为每个节点分配不重叠的地址,且 Peer 的 AllowedIPs 至少要包含对端的隧道地址,否则握手能成、业务不通。第二,想让分支访问中心背后的整个局域网,就要在分支的中心 Peer 上把那个局域网网段也写进 AllowedIPs,并在中心侧配好转发。

前置条件

  • 两台以上 Linux 主机,具备 root 权限,其中作为服务端的一台有固定公网 IP 或可达的监听地址;
  • 服务端防火墙与云安全组放行 UDP 51820(WireGuard 只走 UDP);
  • 各主机时钟偏差在几分钟内(握手带时间戳,偏差过大会被拒);
  • 若要转发到隧道之外的局域网,服务端需允许开启 IP 转发与 NAT。

第一步:安装工具并生成密钥

每台机器各生成一对密钥,私钥仅 root 可读。公钥通过带外方式(工单、加密通道)交换,不要用不可信渠道互发。

# Rocky Linux 9 / RHEL 系
dnf install -y wireguard-tools
# Ubuntu 22.04
# apt install -y wireguard

umask 077
wg genkey | tee /etc/wireguard/privatekey | wg pubkey > /etc/wireguard/publickey
cat /etc/wireguard/publickey

第二步:点对点配置

先跑通最简单的形态:node-01(10.66.0.1)与 node-02(10.66.0.2)直连。node-01 侧的 /etc/wireguard/wg0.conf 如下,逐项解释:Address 是本机隧道地址(掩码表示隧道网段),ListenPort 是监听端口,PrivateKey 填本机私钥;[Peer] 段的 PublicKey 是对端公钥,Endpoint 是对端「公网 IP:端口」(主动发起方必填,两端有固定地址时可互写),AllowedIPs 按模型填对端隧道地址。

# node-01 的 /etc/wireguard/wg0.conf
[Interface]
Address = 10.66.0.1/24
ListenPort = 51820
PrivateKey = 填入 node-01 的私钥

[Peer]
PublicKey = 填入 node-02 的公钥
Endpoint = 203.0.113.20:51820
AllowedIPs = 10.66.0.2/32

node-02 侧对称地写一份:Address 换成 10.66.0.2/24,可不写 ListenPort,[Peer] 填 node-01 的公钥与 Endpoint,AllowedIPs = 10.66.0.1/32。两端启动并设为开机自启:

systemctl enable --now wg-quick@wg0
wg show

第三步:中心辐射拓扑

分支增多时逐对直连不可维护,改用中心辐射:中心节点(10.66.0.1,有固定公网地址)为每个分支写一个 [Peer] 段;分支只配中心一个 Peer。若分支背后还有局域网(如 192.0.2.0/24)需要被中心访问,在中心侧该 Peer 的 AllowedIPs 里追加这个网段——入方向白名单语义的应用。

# 中心节点的 /etc/wireguard/wg0.conf(节选)
[Interface]
Address = 10.66.0.1/24
ListenPort = 51820
PrivateKey = 填入中心节点的私钥

[Peer]
# 分支 node-01,及其背后的局域网
PublicKey = 填入 node-01 的公钥
AllowedIPs = 10.66.0.2/32, 192.0.2.0/24

[Peer]
# 分支 node-02,仅隧道地址
PublicKey = 填入 node-02 的公钥
AllowedIPs = 10.66.0.3/32

分支侧把中心的 [Peer] 作为出口:AllowedIPs 填 10.66.0.0/24,分支间经中心中转互访。分支在 NAT 后、无固定地址时不写 Endpoint(由它主动建链),并加 PersistentKeepalive = 25 保活 NAT 映射,这是 NAT 环境不掉线的关键一行;中心侧对应 Peer 同样不写 Endpoint,靠握手学到的地址回包。

第四步:转发与 NAT

隧道通了只代表两端接口互通;要让流量穿过中心去往其局域网或其他分支,中心必须开转发。长期生效写进 sysctl 配置,并用 wg-quick 的 PostUp/PostDown 挂上 NAT 规则,出接口名按实际替换(示例 eth0):

echo 'net.ipv4.ip_forward = 1' > /etc/sysctl.d/99-wireguard.conf
sysctl -p /etc/sysctl.d/99-wireguard.conf
# 追加到中心节点 wg0.conf 的 [Interface] 段
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

注意区分两种需求:分支经中心「上公网」才需要 NAT 伪装;分支之间、分支与中心局域网之间只是互访时,应各端补静态路由、不要做 NAT,否则源地址被改写后审计与访问控制都会失真。firewalld 环境下还要放行 wg0 的转发。

第五步:客户端的全隧道与分流

把笔记本、办公机接入时,[Peer](中心)的 AllowedIPs 决定流量走向。分流模式只把隧道网段和内网段写进去,其余流量走本地网络;全隧道写 0.0.0.0/0,所有流量经中心出口,适合借道可信出口。两者只差一行,但全隧道必须同时处理好 DNS(在 [Interface] 里加 DNS)与中心侧 NAT,否则会出现「能 ping 通内网、打不开网页」的半通状态。

# 分流:只有内网流量进隧道
AllowedIPs = 10.66.0.0/24, 192.0.2.0/24

# 全隧道:全部流量经中心出口
AllowedIPs = 0.0.0.0/0
# 并在 [Interface] 段加:DNS = 192.0.2.53

第六步:密钥轮换与吊销

WireGuard 没有吊销列表,吊销一个节点就是删掉它的 [Peer] 段并重载配置——删了即刻生效,日常运维同理:人员离场、设备退役时同步清理各端 Peer,并留一份「公钥—节点—责任人」台账,否则无人说得清公钥归属。轮换密钥的标准顺序是先加新、后删旧,避免中断:

# 1) 节点本地生成新密钥对(命令同第一步),把新公钥报给对端管理员
# 2) 对端先追加新 Peer(与旧 Peer 并存,AllowedIPs 分配新隧道地址)
# 3) 节点切换到新私钥并重启接口,验证连通
systemctl restart wg-quick@wg0
# 4) 对端删除旧 Peer,二选一:
wg set wg0 peer 旧公钥 remove          # 临时生效
# 或编辑 wg0.conf 删掉旧 [Peer] 段后执行 wg syncconf 重载(持久化)

改配置后优先用 wg syncconf 无中断重载,restart 会断开所有现有会话。私钥只存本机、权限 600,不要进 Git 等明文仓库。

验证

三看确认状态。一看握手:wg show 里每个 Peer 应有 latest handshake 且时间在两分钟内(空闲无保活时可能较久远,主动 ping 一下对端再看);二看流量:transfer 双向计数都在增长;三看业务:ping 隧道地址、再 ping 对端局域网地址、最后用实际业务端口确认端到端可用。

wg show
ping -c 3 10.66.0.2
# 中心节点上确认转发计数在涨(可选)
sysctl net.ipv4.ip_forward

常见问题

  • wg show 里没有 handshake:按顺序查——UDP 51820 是否被安全组或防火墙拦、Endpoint 是否写对、两端公钥是否配反(最常见的低级错误)、时钟偏差是否过大。抓包看服务端有没有入方向 UDP 包,定界网络还是配置问题。
  • 握手成功但 ping 不通:九成是 AllowedIPs 没覆盖目标地址,或回程某端的 AllowedIPs 不含源网段。按「去向查出方向表、回程查入方向白名单」逐端核对即可。
  • 能通内网、上不了外网(全隧道):中心侧没开转发或缺 NAT,其次是 DNS 没随隧道切换。先在中心抓包看包是否出外网口、回包是否回来。
  • NAT 环境下隔一会儿就断:分支侧补 PersistentKeepalive = 25。另外注意 MTU:某些 PPPoE、移动网络下默认 MTU 偏大,表现为小包通、大包卡,可在 [Interface] 里把 MTU 调到 1280–1420 试。

小结

WireGuard 的配置量与模型一样克制:想通「密钥即身份、AllowedIPs 双重语义」,点对点与中心辐射只是 Peer 段数量的差别。真正要花心思的是运维纪律——公钥台账、离场即删 Peer、改配置用 syncconf、私钥不落明文仓库。本文只讨论企业内网互联与远程办公接入的正规自建场景,生产环境请同时落实本单位的安全与合规要求。

发表回复

后才能评论