本文最后更新于:2024年7月24日 晚上
系列文章前情提要:
WireGuard 系列文章(一):什么是 VPN
WireGuard 系列文章(二):WireGuard 简介 - 快速、现代、安全的 VPN 隧道
WireGuard 系列文章(三):WireGuard 安装
WireGuard 系列文章(四):WireGuard 快速上手
WireGuard 系列文章(五):Netmaker 简介 - 创建和管理 WireGuard 网络的平台
WireGuard 系列文章(六):Netmaker 安装
终于来到一个重要里程碑了,通过 WireGuard + Netmaker 创建 Full Mesh 网络。实现:
多云服务器内网互联
家庭网络路由器内网互联
Full Mesh 网络 Node 通过路由器访问其他家庭设备(如电脑、NAS)
办公设备内网互联
手机内网互联
具体的架构图如下图所示:
开始配置!
创建 Full Mesh 网络
首先通过 Netmaker Dashboard 创建网络,配置如下:
网络名:按需填写(可自动生成)
IPv4 地址范围:按需填写(可自动生成)
启用:UDP 打洞(方便需要 NAT 的设备接入 Full Mesh 网络)
关闭:Is Local Network(如果所有设备不是本地网络互联,就关闭)
关闭:双栈(推荐关闭,减少复杂度)
创建后可以再点击 Network Details 编辑细节,如下图:
包括:
IPv6 地址范围
网络接口名称
监听端口
Postup
Postdown
Keepalive
默认外部 DNS
MTU
是否允许没有访问密钥的节点注册(出于安全原因,建议关闭)
查看 Netmaker 所在节点状态
创建网络之后,Netmaker 所在节点会自动作为客户端加入,可以在 Nodes 页面查看其状态和信息,如下:
可以在 DNS 页面查看其 DNS 记录,如下:(我实际配置的网络名为:private)
创建访问密钥
在 Home / Access Keys 页面,创建指定客户端数量(如 10 个,那么这个 key 用 10 次后就自动失效,其他客户端无法再用这个 key 加入网络),如下图:
创建后会弹出加入网络的具体命令,如下:
具体命令如下:
Linux:
1 curl -sfL https://raw.githubusercontent.com/gravitl/netmaker/master/scripts/netclient-install.sh | VERSION=v0.9.1 KEY=$NETMAKER_TOKEN sh -
Docker:
1 docker run -d --network host --privileged -e TOKEN=$NETMAKER_TOKEN -v /etc/netclient:/etc/netclient --name netclient gravitl/netclient:v0.9.1
Windows (PowerShell Admin):
1 . { iwr -useb https://raw.githubusercontent.com/gravitl/netmaker/master/scripts/netclient-install .ps1 } | iex ; Netclient-Install -version "v0.9.1" -token "$NETMAKER_TOKEN "
手动安装:
1 ./netclient join -t $NETMAKER_TOKEN
通过 Netclient 加入网络
按照上面的架构图,需要加入的节点梳理如下:
Linux: 华为、天翼、腾讯、阿里、百度云服务器,通过 Linux 、Docker 或手动安装方式加入。
Windows:办公电脑(按照架构图,家庭电脑和 NAS 直接通过家里路由器路由过去,无需安装 netclient 及 wireguard),通过 Windows 或手动安装方式加入。
OpenWrt: 家庭路由器,通过手动安装方式加入。
Android:手机,暂无法安装 netclient,通过 外部客户端 方式加入。
Linux 和 Windows 不用多说,直接加入即可。
Linux
Linux 执行命令后,会提示加入成功,同时
一方面将 netclient 移动到 /etc/netclient/
并从 Netmaker pull 配置文件,具体如下:
1 2 3 4 5 6 7 8 9 . ├── config │ ├── backup.netconfig-private │ ├── netconfig-private │ ├── nettoken-private │ ├── secret-private │ └── wgkey-private └── netclient
另一方面将 netclient 配置为 systemd 服务,并启动,每 15s 定时去 Netmaker 那 check in。具体如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 -rw-r--r-- 1 root root 166 Dec 7 02:04 netclient.service -rw-r--r-- 1 root root 172 Dec 7 02:04 netclient.timer [Unit] Description=Network Check Wants=netclient.timer [Service] Type=simple ExecStart=/etc/netclient/netclient checkin -n all [Install] WantedBy=multi-user.target [Unit] Description=Calls the Netmaker Mesh Client Service Requires=netclient.service [Timer] Unit=netclient.service OnCalendar=*:*:0/15 [Install] WantedBy=timers.target
check in 成功的日志如下:
1 2 3 4 2021/12/12 23:10:10 [netclient] running checkin for all networks 2021/12/12 23:10:11 [netclient] checked in successfully for private 2021/12/12 23:10:12 [netclient] checked in successfully for private
Windows
Windows 操作也类似,目录在:C:\ProgramData\Netclient
,系统服务如下:
⚠️ 注意 :
我的电脑无论有没有配置代理,在执行 powershell 脚本下载 winsw.exe
过程中始终无法完整下载,出现这种情况,补救措施如下。
下载 WinSW-x64.exe:https://github.com/winsw/winsw/releases/download/v2.11.0/WinSW-x64.exe
并重命名为 winsw.exe
拷贝该文件到:C:\ProgramData\Netclient
目录 用管理员运行 PowerShell,运行:C:\ProgramData\Netclient\winsw.exe install
安装为 windows 服务 接着运行:C:\ProgramData\Netclient\winsw.exe start
来启动。 在 Windows 服务中验证是否已安装好并启动:
OpenWrt
对于路由器 openwrt,可以自行编译可以运行的 netclient,然后手动运行即可加入成功。
加入成功后,为了定期运行,可以在 crontab 中添加如下以定期 checkin:
1 2 * * * * * /etc/netclient/netclient checkin --network all &> /dev/null * * * * * sleep 15; /etc/netclient/netclient checkin --network all &> /dev/null
这两个计划任务变相实现了 每隔 15 秒执行一次 check in 的目的。
小结
至此,除了家庭网络的家庭电脑和 NAS 设备,以及手机之外,其他已经加入了 Full Mesh 网络,可以相互 ping 通。wg show
也能看到 peers 的信息。如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 PING 10.88.60.1 (10.88.60.1) 56(84) bytes of data. 64 bytes from 10.88.60.1: icmp_seq=1 ttl=64 time=46.1 ms 64 bytes from 10.88.60.1: icmp_seq=2 ttl=64 time=46.0 ms 64 bytes from 10.88.60.1: icmp_seq=3 ttl=64 time=46.1 ms 64 bytes from 10.88.60.1: icmp_seq=4 ttl=64 time=46.0 ms ^C --- 10.88.60.1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3003ms rtt min/avg/max/mdev = 45.963/46.034/46.073/0.044 ms interface: nm-private public key: <hidden> private key: (hidden) listening port: 51821 fwmark: 0x221b peer: kXmPHKYv6L5c<hidden>nIex7Yd5JFyq6NZB6dFE= endpoint: <hidden>:51821 allowed ips: 10.88.60.8/32 latest handshake: 25 seconds ago transfer: 1.74 MiB received, 618.27 KiB sent persistent keepalive: every 20 seconds peer: OK7B2QzY8r<hidden>SfIr/tqinSGBd55gjsmgjo= endpoint: <hidden>:51821 allowed ips: 10.88.60.3/32 latest handshake: 29 seconds ago transfer: 1.25 MiB received, 316.43 KiB sent persistent keepalive: every 20 seconds peer: +SMVJLu<hidden>KkUVSk2aKPdTJ9rd+lK1C4= endpoint: <hidden>:51822 allowed ips: 10.88.60.6/32 latest handshake: 52 seconds ago transfer: 316.42 KiB received, 1.25 MiB sent persistent keepalive: every 20 seconds peer: U73tngxoP<hidden>YzAhIS8hTfO3Chno3U04= endpoint: <hidden>:51821 allowed ips: 10.88.60.7/32 latest handshake: 56 seconds ago transfer: 316.65 KiB received, 1.25 MiB sent persistent keepalive: every 20 seconds peer: 5lnsgrK3b<hidden>9x7bdM2nsqqC2CYUY= endpoint: <hidden>:51821 allowed ips: 10.88.60.1/32 latest handshake: 1 minute, 9 seconds ago transfer: 443.09 KiB received, 1.16 MiB sent persistent keepalive: every 20 seconds peer: 6d9cRCdKcb<hidden>QvfM6AwqoNRADC4VM= endpoint: <hidden>:51821 allowed ips: 10.88.60.4/32 latest handshake: 1 minute, 36 seconds ago transfer: 1.25 MiB received, 316.25 KiB sent persistent keepalive: every 20 seconds peer: SiNrI37GI<hidden>+G9h0H6IuZJ2iTtGWo= endpoint: <hidden>:61401 allowed ips: 10.88.60.9/32 latest handshake: 3 days, 1 hour, 47 minutes, 21 seconds ago transfer: 3.22 MiB received, 9.55 MiB sent persistent keepalive: every 20 seconds
通过外部客户端加入网络
对于手机,目前是要通过外部客户端的方式加入网络。具体步骤如下:
选定一台 ** 有公网静态 IP ** 的 Node 作为 Ingress Gateway (可以理解为 WireGuard 的中继服务器),用于接收来自手机的流量并转发,配置也很简单,在 Nodes 页面,点击如下即可将某一 Node 配置:
手机(安卓设备)下载并安装 WireGuard 原生客户端;
创建一个 External Client,它会生成一个 WireGuard 配置文件,WireGuard 客户端可以下载该配置文件或者扫描二维码进行连接。如下图:
Node 通过路由器访问家庭内部局域网
这里家庭内网的电脑和 NAS 并没有直接加入 Full Mesh 网络(直接加入也可以,步骤同上文),而是通过路由器访问 Full Mesh 网络。
到目前为止我们只是打造了一个点对点的 Mesh 网络,各个节点之间都可以通过 WireGuard 的私有网络 IP 进行直连。但我们可以更大胆一点,让每个节点都能访问家庭网络的局域网 IP。以 OpenWrt 为例,假设 OpenWrt 跑在家中,家中的局域网 IP 为 192.168.2.0/24
,如何让其他所有节点都能访问这个局域网呢?
其实也很简单,可以将某个节点设置为 Egress Gateway(出口网关),允许将 内部 网络的流量转发到 外部 指定的 IP 范围。这里的 内部 指的是 WireGuard 私有网络,本文中就是 10.88.60.0/24
;外部 网络指的是家庭局域网网段。
操作步骤如下图:
填写局域网的网段(如:192.168.2.0/24
)和出口网卡(如:eth0)。如下图:
配置完成后,就会在 OpenWrt 节点配置的 Postup 和 Postdown 中添加相关的 iptables 规则。如下图:
wg show
查看如下:
1 2 3 4 5 6 peer : kXmPHKYv6L5cX<hidden>d5JFyq6NZB6dFE= endpoint : <hidden>:51821 allowed ips: 10.88.60.8 /32 , 192.168.2.0 /24 latest handshake: 25 seconds ago transfer : 1 .74 MiB received, 618 .27 KiB sent persistent keepalive: every 20 seconds
具体的规则为:
1 2 3 4 5 iptables -A FORWARD -i nm-private -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE iptables -D FORWARD -i nm-private -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
除此之外还会在其他所有节点中添加相关路由表:
1 2 $ ip route|grep "192.168.2.0/24" 192.168.2.0/24 dev nm-private scope link
最终所有的节点都可以访问 OpenWrt 的局域网 IP 了。
总结
至此,我们终于完成了 WireGuard 的系列的一个重要里程碑:通过 WireGuard + Netmaker 配置 Full Mesh 网络,并打通家庭局域网。🎉🎉🎉