使用 WireGuard 构建站点到站点 VPN

另一种常见的 VPN 配置,是通过互联网连接两个不同网络,WireGuard 同样适用。下面是简化的网络图源码:


        flowchart LR
    subgraph alpha["alpha site — 10.10.10.0/24"]
        alpha_gw["wgA<br>10.10.10.1<br>10.10.9.0"]
        a_left["..."]
        a_right["..."]
    end
    subgraph beta["beta site — 10.10.11.0/24"]
        beta_gw["wgB<br>10.10.11.1<br>10.10.9.1"]
        b_left["..."]
        b_right["..."]
    end
    alpha_gw --- a_left & a_right
    beta_gw --- b_left & b_right
    alpha_gw -. ext .- internet(("public internet"))
    internet -. ext .- beta_gw
    alpha_gw -. "WireGuard tunnel<br>10.10.9.0/31" .- beta_gw

    style internet fill:#BBDEFB
    style alpha fill:#FFF9C4
    style beta fill:#C8E6C9
    

alpha 站点为 10.10.10.0/24,网关 wgA 的内部地址是 10.10.10.1;beta 站点为 10.10.11.0/24,网关 wgB 的内部地址是 10.10.11.1。两个网关通过公共互联网建立 WireGuard 隧道,隧道网络为 10.10.9.0/31,两端分别使用 10.10.9.0 和 10.10.9.1。

目标是将 alpha 与 beta 网络无缝整合,让 alpha 站点的系统透明访问 beta 站点的系统,反之亦然。

这种配置有几个特点:

  • 两个对等节点通常会一直运行。
  • 不能假设某一端始终主动发起连接,这与咖啡店中的笔记本场景不同。
  • 因此,两端都应当拥有静态端点,例如固定 IP 或有效域名。
  • 不会给两边的所有系统都分配 VPN IP,因此 VPN 网络很小,使用只容纳两个 IP 的 /31,且仅用于路由。只有网关自身拥有 VPN 网络中的 IP。
  • 经过 WireGuard 网络的流量不会做 NAT。因此,两站点的网络必须不同,不能重叠。

从 beta 网络的一台系统到 alpha 系统执行 MTR(My Traceroute),报告类似如下:

ubuntu@b1:~$ mtr -n -r 10.10.10.230
Start: 2022-09-02T18:56:51+0000
HOST: b1                Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 10.10.11.1       0.0%    10    0.1   0.1   0.1   0.2   0.0
  2.|-- 10.10.9.0        0.0%    10  299.6 299.3 298.3 300.0   0.6
  3.|-- 10.10.10.230     0.0%    10  299.1 299.1 298.0 300.2   0.6

注意:按照传统网络地址与广播地址的划分,/31 CIDR 的第一个地址是网络地址,第二个也是最后一个地址是广播地址,因而没有可用主机地址。RFC 3021 允许在点到点连接中使用它。如果遇到路由或其他网络问题,可以改用 /30 及其两个有效主机 IP。

配置 WireGuard

在每个站点的网关上,也就是具有互联网连接的系统上,安装 WireGuard 并生成密钥。alpha 站点执行:

$ sudo apt install wireguard
$ wg genkey | sudo tee /etc/wireguard/wgA.key
$ sudo cat /etc/wireguard/wgA.key | wg pubkey | sudo tee /etc/wireguard/wgA.pub

alpha 的配置如下:

[Interface]
PostUp = wg set %i private-key /etc/wireguard/%i.key
Address = 10.10.9.0/31
ListenPort = 51000

[Peer]
# beta site
PublicKey = <contents of /etc/wireguard/wgB.pub>
AllowedIPs = 10.10.11.0/24,10.10.9.0/31
Endpoint = <beta-gw-ip>:51000

beta 站点的网关执行类似步骤:

$ sudo apt install wireguard
$ wg genkey | sudo tee /etc/wireguard/wgB.key
$ sudo cat /etc/wireguard/wgB.key | wg pubkey | sudo tee /etc/wireguard/wgB.pub

然后创建 beta 对应的配置文件:

[Interface]
Address = 10.10.9.1/31
PostUp = wg set %i private-key /etc/wireguard/%i.key
ListenPort = 51000

[Peer]
# alpha site
PublicKey = <contents of /etc/wireguard/wgA.pub>
AllowedIPs = 10.10.10.0/24,10.10.9.0/31
Endpoint = <alpha-gw-ip>:51000

重要:WireGuard 配置在两个网络的网关上。因此,各网络中的单独主机无需修改。但请注意,WireGuard 隧道和加密只发生在 alpha 与 beta 网关之间,并不是两个网络中各主机之间的端到端加密。

启用接口

由于这是两个固定站点之间的长期 VPN,最好使用 wg-quick 的 systemd 单元启动并管理接口,尤其是让接口在重启后自动启动。

alpha 上执行:

$ sudo systemctl enable --now wg-quick@wgA

beta 上执行:

$ sudo systemctl enable --now wg-quick@wgB

这些命令既让接口开机自动启动,也立即启动接口。

防火墙与路由

两个网关可能已经存在路由和防火墙规则,根据当前配置,可能需要调整。

每个网络中的独立主机不需要针对远端 alpha 或 beta 网络修改配置,因为它们会像处理其他非本地流量一样,将流量发送到默认网关。wg-quick 已添加路由,因此网关知道如何转发。

至此的配置没有设置限制,两站点之间的流量可以自由通行。

通常需要完成或确认以下事项:

  • 确保两个网关可以通过指定端点地址和 UDP 端口互相联系。本例端口是 51000。为了进一步保护,可以设置防火墙,仅允许对应对等节点访问该端口,而不是向整个互联网开放。
  • 对于从内部网络经 WireGuard 接口发往另一站点的流量,不要进行 masquerade 或 NAT。这些流量应当只进行路由。
  • 网关通常无需修改路由,因为 wg-quick 会添加远端站点路由,但仍应查看路由表是否合理。可以从 ip route 和 ip route | grep wg 开始。
  • 如果需要限制 alpha 与 beta 网络间的流量,可能需要增加防火墙规则。

例如,要禁止站点之间使用 SSH,可以在 alpha 添加:

$ sudo iptables -A FORWARD -i wgA -p tcp --dport 22 -j REJECT

beta 上相应添加:

$ sudo iptables -A FORWARD -i wgB -p tcp --dport 22 -j REJECT

可以把这些命令加入 WireGuard 接口配置的 PostUp 操作。别忘了在对应 PreDown 钩子中删除规则,否则会积累多条重复规则。


原文:WireGuard VPN site-to-site。作者/维护方:Ubuntu Server 文档维护者。本文为中文翻译,代码及命令保留原文。

原站版权声明:Copyright © 2026。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容