WireGuard 主要网络拓扑

WireGuard 基础拓扑结构说明(翻译)

WireGuard 网络连接两个端点时,主要有以下四种拓扑结构可供选择:

  • 点对点(Point to Point)
  • 星型(Hub and Spoke)
  • 点到站点(Point to Site)
  • 站点到站点(Site to Site)

这些拓扑结构都能满足常见的端点连接需求,例如:通过 SSH 进行通信、访问另一端的 HTTP 服务器、访问共享文件夹等。

与其他 VPN 技术不同,WireGuard 没有严格的"客户端"或"服务器"角色之分。所有 WireGuard 节点都具有同等的能力,可以执行传统意义上的"客户端"或"服务器"角色。

为了简化说明,本文将统一使用以下示例:

  • “端点 A"代表"客户端”(如用户的平板电脑)
  • “端点 B"代表"服务器端”(如运行 Web 应用的服务器)
  • 端口使用约定:
    • 51821:代表"客户端"侧的 WireGuard 节点
    • 51822:代表"服务器"侧的 WireGuard 节点
    • 51823:用于两者之间的中间 WireGuard 节点(如果存在)

WireGuard点对点拓扑

点对点是最简单的拓扑结构 —— 就是运行 WireGuard 的一个端点直接连接到另一个运行 WireGuard 的端点。这也是唯一能实现端到端(E2E)加密的拓扑结构。其他所有拓扑结构都涉及 WireGuard 数据包在端点之间的某个中间节点被解密。

要实现点对点连接,两个端点之间的所有防火墙必须允许其中一个端点的 WireGuard 端口接受新连接。

在最简单的点对点场景中,两个端点位于同一个局域网(LAN)内,它们之间的防火墙配置为允许任一端点连接到对方的 WireGuard 端口。在这种情况下,任何一个端点都可以随时发起与对方的连接。

图1.1:端点A到端点B的简单点对点连接

在更复杂但常见的场景中,两个端点都位于防火墙和 NAT(网络地址转换)后面,中间通过互联网连接:

  • 端点 A 前面的防火墙只允许已建立的连接通过
  • 端点 B 前面的防火墙允许新连接通过 51822 端口
  • 端点 B 前面的 NAT 将 51822 端口转发到端点 B

图1.2:防火墙和NAT后的端点A到端点B的点对点连接

在这种场景下:

  • 端点 A 可以随时向端点 B 发起新连接
  • 由于端点 A 位于只允许已建立连接的防火墙后面,如果要使端点 B 能够向端点 A 发起连接,必须在端点 A 上配置 PersistentKeepalive 设置(设置为 25,即每 25 秒发送一个保活数据包,这个值适用于大多数情况)

网状拓扑实际上就是一组端点之间的多个点对点连接的组合。

详细的配置示例请参考WireGuard 点对点配置

WireGuard星型拓扑

星型拓扑(也称为星形拓扑)是下一个基本拓扑结构,其中两个运行 WireGuard 的端点通过第三台同样运行 WireGuard 的主机连接。这第三台主机作为连接到它的 WireGuard 端点之间的路由器,将从一个端点通过 WireGuard 隧道收到的数据包通过另一个 WireGuard 隧道转发给第二个端点。

这种拓扑通常用于连接多于两个的端点 —— 这是实现远程访问管理的好方法,可以管理多个远程端点;或者将多个分散的远程主机组成虚拟局域网,在一个中心位置(集线器)集中进行路由规则配置、访问控制和流量检查。

星型拓扑也可以用作连接两个都位于不允许新入站连接的防火墙后面的端点,或者位于不允许端口转发的 NAT 后面的端点(这时集线器充当"跳板服务器")。

在最简单的星型场景中,所有主机都在同一个本地网络中:

  • “分支"端点(端点 A 和端点 B)与"集线器"主机(主机 C)之间的防火墙配置为允许分支连接到集线器的 WireGuard 端口(51823)
  • 同样允许集线器连接到各个分支的 WireGuard 端口(端点 A 的 51821 和端点 B 的 51822)

一旦端点 A 与主机 C 之间的 WireGuard 隧道建立,以及端点 B 与主机 C 之间的单独 WireGuard 隧道建立,主机 C 就可以在端点 A 和端点 B 之间路由数据包。

图2.1:通过主机C连接端点A到端点B的简单星型拓扑

在更复杂的场景中,集线器和分支都位于防火墙和 NAT 后面,中间通过互联网连接:

  • 端点 A 和端点 B 前面的防火墙只允许已建立的连接通过
  • 主机 C 前面的防火墙允许新连接通过 51823 端口
  • 主机 C 前面的 NAT 将 51823 端口转发到主机 C

图2.2:防火墙和NAT后通过主机C连接端点A到端点B的星型拓扑

在这种场景下:

  • 端点 A 和端点 B 都可以独立地与主机 C 建立新连接
  • 由于端点 A 和 B 的防火墙规则,主机 C 无法与它们建立新连接
  • 要使端点 A 能够通过 WireGuard 向端点 B 发起连接,必须在端点 B 上配置 PersistentKeepalive
  • 如果还要允许端点 B 通过 WireGuard 向端点 A 发起连接,则必须在端点 A 上配置 PersistentKeepalive

详细的配置示例请参考《WireGuard 星型拓扑配置》文章。

WireGuard点到站点拓扑

在点到站点拓扑中,远程端点通过 WireGuard 连接到另一个网络中的主机,该主机可以将远程端点的数据包路由到其网络内的各个本地端点。点到站点类似于星型拓扑,但区别在于一些分支(与集线器位于同一局域网的端点)不使用 WireGuard 隧道。

点到站点适用于多种场景,当您想要允许远程端点访问同一局域网上的多个服务器,而不需要在每个服务器上单独设置和管理 WireGuard 时特别有用。常见场景包括:

  • 远程 PC 连接到办公室局域网的各个服务器(又称"Road Warrior”)
  • 办公室局域网中的工作站连接到云网络中的多个服务器(又称"Point to Cloud")
  • 云虚拟机连接到您办公室局域网的各个服务器
  • 云服务器连接到另一个云网络中的其他服务器

在最简单的点到站点场景中:

  • 一个运行 WireGuard 的端点(“远程端点”,端点 A)直接连接到另一个运行 WireGuard 的主机(主机 β)
  • 主机 β 可以作为路由器连接到本地站点(站点 B)内的其他端点,包括端点 B(“本地"端点)

图3.1:从端点A到站点B中端点B的简单点到站点连接

在这种场景中,端点 A 和站点 B 之间的防火墙配置为允许端点 A 与主机 β 相互连接。这使得远程端点(端点 A)可以发起与任何本地端点的连接,任何本地端点(如端点 B)也可以发起与远程端点的连接。

在更复杂(也更常见)的场景中:

  • 远程端点(端点 A)和本地站点(站点 B)都位于防火墙和 NAT 后面,中间通过互联网连接
  • 端点 A 前面的防火墙只允许已建立的连接通过
  • 站点 B 前面的防火墙允许新连接通过 51822 端口
  • 运行 WireGuard 的主机(主机 β)在 51822 端口接受 WireGuard 连接,并将授权流量从其 WireGuard 隧道路由到站点内的端点(如端点 B)

图3.2:防火墙和NAT后从端点A到站点B中端点B的点到站点连接

本地站点(站点 B)内的流量不通过 WireGuard 隧道,因此受制于其他本地流量所适用的任何防火墙或路由限制:

  • HTTP 请求从端点 A 到端点 B 的路径:先通过 WireGuard 隧道从端点 A 到站点 B,然后像任何其他本地流量一样从 WireGuard 隧道路由到端点 B
  • 要使 HTTP 流量从端点 A 完全通过到端点 B 的 80 端口,主机 β 和端点 B 之间的任何防火墙都需要允许来自主机 β 到端点 B 的 80 端口流量

与点对点场景类似:

  • 端点 A 可以随时向端点 B 发起新连接
  • 由于端点 A 位于只允许已建立连接的防火墙后面,如果要使端点 B 能够向端点 A 发起连接,必须在端点 A 上配置 PersistentKeepalive

详细的配置示例请参考《WireGuard 点到站点配置》文章。

WireGuard站点到站点拓扑

站点到站点拓扑类似于点到站点,但区别在于 WireGuard 隧道的两端都是完整的站点。这是构建虚拟局域网到局域网连接(或云到云、局域网到云等)的简便方法。

与点到站点类似,在一端有一台运行 WireGuard 的主机,该主机可以路由到其站点内的各个端点。在连接的另一端,在不同的站点中也有一台运行 WireGuard 的主机,这台主机同样可以路由到其站点内的端点。

在下面最简单的形式中,有两个相邻的子网(站点 A 和站点 B)通过 WireGuard 隧道连接。站点 A 中的流量(如来自端点 A)如果目的地是站点 B 中的端点(如端点 B),会首先路由到站点 A 中的 WireGuard 主机(主机 α),然后通过 WireGuard 隧道到达站点 B,最后从站点 B 中的 WireGuard 主机(主机 β)发送到站点 B 中的目标端点。

图4.1:从站点A中的端点A到站点B中的端点B的简单站点到站点连接

在这种场景中,站点 A 和站点 B 之间的任何防火墙都应配置为允许站点 A 连接到站点 B 的 WireGuard 端口,反之亦然。这使得站点 A 中的任何端点都可以发起与站点 B 中任何端点的连接,反之亦然。

在更复杂的场景中,两个站点都位于防火墙和 NAT 后面,中间通过互联网连接:

  • 站点 A 前面的防火墙允许新连接通过 51821 端口,主机 α 在该端口接受 WireGuard 连接,并将授权流量从其 WireGuard 隧道路由到站点内的端点
  • 类似地,站点 B 前面的防火墙允许新连接通过 51822 端口,主机 β 在该端口接受 WireGuard 流量,并将授权流量从其 WireGuard 隧道路由到站点 B 内的端点

在这种场景中,站点 A 和站点 B 的 WireGuard 主机都位于各自站点的 DMZ(隔离区)中,它们可以从互联网公开访问,同时也可以路由到其所在站点使用的私有地址空间(以及它们所属的 WireGuard 网络使用的私有地址空间)。

图4.2:防火墙和NAT后从站点A中的端点A到站点B中的端点B的站点到站点连接

在这种场景下,从端点 A 到端点 B 的流量首先路由到主机 α,然后通过站点 A 和站点 B 之间的 WireGuard 隧道,从主机 β 出来,最后到达端点 B:

  • 端点 A 和主机 α 之间的防火墙允许来自端点 A 的出站流量(以及已建立连接的回程流量)
  • 主机 β 到端点 B 之间的防火墙允许到端点 B 的 HTTP(80 端口)入站流量(以及相应的出站流量)

主机 α 和主机 β 之间的防火墙允许任一 WireGuard 主机向另一方发起连接。因此,通常通过使用 WireGuard 隧道,站点 A 中的任何端点都可以向站点 B 中的任何端点发起连接,反之亦然。但是,端点 A 和主机 α 之间的防火墙只允许已建立的连接进入端点 A,从而保护它免受来自站点 B 的新连接。

如果我们想允许站点 B 中的端点能够向端点 A 发起新连接,这不需要进行任何 WireGuard 特定的配置 —— 我们只需要更改端点 A 和主机 α 之间的防火墙规则,允许新连接进入(就像我们对端点 B 所做的那样,允许来自主机 β 的新 HTTP 连接通过 80 端口)。

详细的配置示例请参考WireGuard 站点到站点配置

基本上所有其他你会使用的 WireGuard 拓扑都可以通过组合这四种基本模式来构建。例如,对于由多个分散的远程端点(用于移动办公人员)连接到局域网(在你的办公总部)的 WireGuard 网络,你可以将星型拓扑与点到站点拓扑结合使用,其中远程端点作为星型拓扑的分支,而星型拓扑的集线器同时也是点到站点拓扑中的站点 WireGuard 主机。

另一个例子是,对于连接三个办公室局域网加上两个云站点的 WireGuard 网络,你可以在每个单独的站点之间使用站点到站点拓扑,从每个站点的 WireGuard 主机创建单独的 WireGuard 隧道到其他四个站点。或者你可能决定使用星型拓扑与站点到站点拓扑的组合,这允许你在一个地方集中管理站点间的路由和访问控制,并且每个站点的 WireGuard 主机只需要连接到一个所有其他站点也都连接的集线器主机。