使用 WireGuard 异地组网

发布于 2023-09-21  97 次阅读


前言

用前忐忑,用后舒心~谁用谁知道!

网络拓扑

先来看下目前的网络环境,拓扑如下:

设备:

  • A:旁路由
  • B:NAS 虚拟机产生的旁路由
  • C:PC
  • D:手机

我想要达到的效果:

  • 接入的设备都可以访问 A / B 和它们所在的内网段
  • 接入的设备都可以访问 C

从 IPV4 角度来说,其实就是一个星型网络拓扑,A 在此中担任类似服务器的角色,其他都是客户端,所有流量都会经过 A 的转发;IPV6 角度看的话,C 设备是永远访问不了咯,剩下几个设备可以组成全互联模式)。

下面进行相关 WireGuard 配置,打算分配的各设备 IP 如下:

  • A:10.0.0.1,fd11::1
  • B:10.0.0.2,fd11::2
  • C:10.0.0.3,fd11::3
  • D:10.0.0.4,fd11::4
  • ...

服务端配置

WireGuard 不区分客户端和服务端,所以这个说法也仅对当前的网络而言,由于 A 是处于主路由后的旁路由网关,使用 OpenWrt,那么直接在这上面进行配置!

安装 WireGuard

系统 -> 软件包 中搜索 luci-proto-wireguard,进行安装!安装完成后重启下 OpenWrt!

配置网络

点击 网络 -> 接口,添加新接口,名字任意,协议选择 WireGuard VPN

点击创建接口到下一个界面,里面的 生成新的密钥对 按钮可以生成公钥和私钥,生成后分别记住!然后编辑下面的样例文件,改成你所适合的网络环境:

[Interface]
# Name = 设备 A
Address = 10.0.0.1/24, fd11::1/64
ListenPort = 11111
PrivateKey = <设备 A 的私钥>
DNS = 192.168.11.1
# Table = 12345
# MTU = 1500
# PreUp = /bin/example arg1 arg2 %i
# PostUp = /bin/example arg1 arg2 %i
# PreDown = /bin/example arg1 arg2 %i
# PostDown = /bin/example arg1 arg2 %i

[Peer]
# Name = 对端 B
PublicKey = <设备 B 的公钥>
PresharedKey = <预共享密钥>
AllowedIPs = 192.168.12.0/24, 10.0.0.2/32, fd11::2/128

[Peer]
# Name = 对端 C
PublicKey = <设备 C 的公钥>
PresharedKey = <预共享密钥>
AllowedIPs = 10.0.0.3/32, fd11::3/128

[Peer]
# Name = 对端 D
PublicKey = <设备 D 的公钥>
PresharedKey = <预共享密钥>
AllowedIPs = 10.0.0.4/32, fd11::4/128

简单说明下相关参数:

  • [Interface]
    • Address:设备的组网地址,记得带上掩码,如果作为服务器节点,则掩码可以为 /24
    • ListenPort:监听端口,服务器配置必填项,客户端选填
    • PrivateKey:当前设备私钥,直接用工具生成即可
    • DNS:指定 DNS 地址,可以配置多个,用 , 分隔
  • [Peer]
    • PublicKey:对端设备公钥,直接用工具生成即可
    • PresharedKey:预共享密钥,Base64 编码,本质是额外加密,如果不写,所有的对端 [Peer] 里面都不应写,如果需要写,所有的对端 [Peer] 里面都必须一样!
    • AllowedIPs:这个配置相当灵活,你可以先简单理解成需要让流量走 WireGuard 的地址段;当作为服务器端时,某个客户端发来的流量只可能经由它自身的 IP 地址到达,例,服务器 A 允许 B 访问时,A 中对 [Peer] B 的允许 IP 就是 10.0.0.2/32。当作为客户端时,需要访问对方网络的 IP 地址段,就需要把对方网络的 IP 段添加到这里,例,客户端 B 需要访问 A 的内网段时,B 中对 [Peer] A 的允许 IP 就是 10.0.0.0/24, 192.168.11.0/24 (因为 B 还允许其他设备经 A 访问它)!
更多详细注释项可以参考这里
对我来说,AllowedIPs 这个是整个配置文件中最难理解的参数,可能瞎吉儿乱搞一通也能通,但具体应该怎么填,可能是我对网络理解不深,始终有种雾里看花的朦胧感~见谅~

然后,在常规设置 的 导入配置文件 中,把上面改好的配置文件粘贴进去,点击 导入设置 即可!导入后,也可以对对端的相关设备补充下描述!这样服务器端的配置就导入完成了!

防火墙配置

点击 网络 -> 防火墙 ,在通讯规则,如下:

注意,我是旁路由,所以源区域选的 LAN,如果是主路由,源区域选择 WAN!当然,协议也可以只选 UDP~考虑到后面可能会有一些特殊情况,我就两者都选了~

端口映射

进入主路由,设置相关端口映射,由于每个主路由设置界面不同,这里只给参考:

到此,服务器端的设置就完成了~(如果先前没重启过 WireGuard 服务的,记得重启一次)!

客户端配置

客户端的配置基本与服务端相同,因为 WireGuard 不区分客户端还是服务器端,这里给出我方案里面的这些设备配置参考!

客户端 B - 虚拟软路由 OpenWrt

参考服务器端,配置参考如下:

[Interface]
PrivateKey = <设备 B 的私钥>
Address = 10.0.0.2/32, fd11::2/128
DNS = 192.168.12.1

[Peer]
PublicKey = <设备 A 的公钥>
PresharedKey = <预共享密钥>
AllowedIPs = 192.168.11.0/24, 10.0.0.0/24, fd11::/64
Endpoint = <设备 A 的公网 IP 地址>:11111
PersistentKeepalive = 25

客户端 C - Win10 PC

首先在官网下载 Windows 客户端安装!

安装后选择 新建隧道 -> 新建空隧道 ,然后修改下面的配置文件复制进去即可!

[Interface]
PrivateKey = <设备 C 的私钥>
Address = 10.0.0.3/32, fd11::3/128
DNS = 223.5.5.5, 119.29.29.29

[Peer]
PublicKey = <设备 A 的公钥>
PresharedKey = <预共享密钥>
AllowedIPs = 192.168.11.0/24, 192.168.12.0/24, 10.0.0.0/24, fd11::/64
Endpoint = <设备 A 的公网 IP 地址>:11111
PersistentKeepalive = 600

客户端 D - Android 手机

首先在官网下载 Android 客户端安装!

安装后可以扫描二维码(比如 OpenWrt 对端界面生成)或把如下配置修改后新建成 ini 后缀文件,再 zip 压缩后放入手机导入:

[Interface]
PrivateKey = <设备 D 的私钥>
Address = 10.0.0.4/32, fd11::4/128
DNS = 10.0.0.1

[Peer]
PublicKey = ItP79Y1uPt6Y464K24fEvgd24HEa0sQnrBRZwmJTE2A=
PresharedKey = kKQW1cuDKULw9yKXQI2RbY2Ur4MhQtMnnmQ/uwLSr40=
AllowedIPs = 192.168.0.0/16, 10.0.0.0/24, fd11::/64
Endpoint = <设备 A 的公网 IP 地址>:11111
PersistentKeepalive = 25

总结

经此,所有设备都已互联,可访问!

当然缺点也有:

  • 目前所有的对端 Endpoint 都是 IP 形式的,主路由一重启,地址可能会发生变化!(可以用 DDNS 等解决)
  • WireGuard 本身是基于 UDP 协议的,对于某些地区存在 UDP QoS 或干脆 UDP 阻断的,可能会造成干扰!(可以用 UDP2RAW 等魔法处理)

至于其他的,一旦搭建完,就感觉太好用了~先前由于 Tailscale 的 VPS 在境外,两端没有 ipv6 直连的话,几乎处于不能用的状态(绕日 DREP),而我使用频率最高的,就是 C -> B 。。。

感谢

https://iyzm.net/openwrt/1736.html

https://icloudnative.io/ (这位大佬写了好多关于 WireGuard 的文章,获益良多,都可以看看,主页输入 “WireGuard” 查找相关文章就行了)