终于来到一个重要里程碑了,通过 WireGuard + Netmaker 创建 Full Mesh 网络。实现:
- 多云服务器内网互联
- 家庭网络路由器内网互联
- Full Mesh 网络 Node 通过路由器访问其他家庭设备(如电脑、NAS)
- 办公设备内网互联
- 手机内网互联
具体的架构图如下图所示:
我的 WireGuard 网络架构概述
开始配置!
创建 Full Mesh 网络
首先通过 Netmaker Dashboard 创建网络,配置如下:
Netmaker 创建网络
- 网络名:按需填写(可自动生成)
- IPv4 地址范围:按需填写(可自动生成)
- 启用:UDP 打洞(方便需要 NAT 的设备接入 Full Mesh 网络)
- 关闭:Is Local Network(如果所有设备不是本地网络互联,就关闭)
- 关闭:双栈(推荐关闭,减少复杂度)
创建后可以再点击 Network Details 编辑细节,如下图:
包括:
- IPv6 地址范围
- 网络接口名称
- 监听端口
- Postup
- Postdown
- Keepalive
- 默认外部 DNS
- MTU
- 是否允许没有访问密钥的节点注册(出于安全原因,建议关闭)
查看 Netmaker 所在节点状态
创建网络之后,Netmaker 所在节点会自动作为客户端加入,可以在 Nodes 页面查看其状态和信息,如下:
Netmaker Node 状态
Netmaker Node 详细信息
可以在 DNS 页面查看其 DNS 记录,如下:(我实际配置的网络名为:private)
Netmaker DNS 记录
创建访问密钥
在 Home / Access Keys 页面,创建指定客户端数量(如 10 个,那么这个 key 用 10 次后就自动失效,其他客户端无法再用这个 key 加入网络),如下图:
Netmaker 创建访问密钥
创建后会弹出加入网络的具体命令,如下:
Netclient 加入网络的命令
具体命令如下:
Linux:
curl -sfL https://raw.githubusercontent.com/gravitl/netmaker/master/scripts/netclient-install.sh | VERSION=v0.9.1 KEY=$NETMAKER_TOKEN sh - BASH |
Docker:
docker run -d --network host --privileged -e TOKEN=$NETMAKER_TOKEN -v /etc/netclient:/etc/netclient --name netclient gravitl/netclient:v0.9.1 BASH |
Windows (PowerShell Admin):
. { iwr -useb https://raw.githubusercontent.com/gravitl/netmaker/master/scripts/netclient-install.ps1 } | iex; Netclient-Install -version "v0.9.1" -token "$NETMAKER_TOKEN" POWERSHELL |
手动安装:
./netclient join -t $NETMAKER_TOKEN BASH |
通过 Netclient 加入网络
按照上面的架构图,需要加入的节点梳理如下:
- Linux: 华为、天翼、腾讯、阿里、百度云服务器,通过 Linux 、Docker 或手动安装方式加入。
- Windows:办公电脑(按照架构图,家庭电脑和 NAS 直接通过家里路由器路由过去,无需安装 netclient 及 wireguard),通过 Windows 或手动安装方式加入。
- OpenWrt: 家庭路由器,通过手动安装方式加入。
- Android:手机,暂无法安装 netclient,通过 外部客户端 方式加入。
Linux 和 Windows 不用多说,直接加入即可。
Linux
Linux 执行命令后,会提示加入成功,同时
一方面将 netclient 移动到 /etc/netclient/
并从 Netmaker pull 配置文件,具体如下:
# tree . . ├── config │ ├── backup.netconfig-private │ ├── netconfig-private │ ├── nettoken-private │ ├── secret-private │ └── wgkey-private └── netclient BASH |
另一方面将 netclient 配置为 systemd 服务,并启动,每 15s 定时去 Netmaker 那 check in。具体如下:
# ls -l *netclient* -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 # cat netclient.service [Unit] Description=Network Check Wants=netclient.timer [Service] Type=simple ExecStart=/etc/netclient/netclient checkin -n all [Install] WantedBy=multi-user.target # cat netclient.timer [Unit] Description=Calls the Netmaker Mesh Client Service Requires=netclient.service [Timer] Unit=netclient.service OnCalendar=*:*:0/15 [Install] WantedBy=timers.target BASH |
check in 成功的日志如下:
# ./netclient checkin -n all 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 BASH |
Windows
Windows 操作也类似,目录在:C:\ProgramData\Netclient
,系统服务如下:
Netclient Windows 服务
⚠️ 注意 :
我的电脑无论有没有配置代理,在执行 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:
* * * * * /etc/netclient/netclient checkin --network all &> /dev/null * * * * * sleep 15; /etc/netclient/netclient checkin --network all &> /dev/null CRON |
这两个计划任务变相实现了 每隔 15 秒执行一次 check in 的目的。
小结
至此,除了家庭网络的家庭电脑和 NAS 设备,以及手机之外,其他已经加入了 Full Mesh 网络,可以相互 ping 通。wg show
也能看到 peers 的信息。如下:
# ping 10.88.60.1 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 # wg show 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 BASH |
通过外部客户端加入网络
对于手机,目前是要通过外部客户端的方式加入网络。具体步骤如下:
- 选定一台 ** 有公网静态 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
;外部 网络指的是家庭局域网网段。
操作步骤如下图:
Netmaker 创建 Egress Gateway
填写局域网的网段(如:192.168.2.0/24
)和出口网卡(如:eth0)。如下图:
Netmaker 创建 Egress Gateway - 2
配置完成后,就会在 OpenWrt 节点配置的 Postup 和 Postdown 中添加相关的 iptables 规则。如下图:
Egress Gateway 自动配置路由规则
wg show
查看如下:
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 APACHE |
具体的规则为:
# Postup iptables -A FORWARD -i nm-private -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE # Postdown iptables -D FORWARD -i nm-private -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE BASH |
除此之外还会在其他所有节点中添加相关路由表:
$ ip route|grep "192.168.2.0/24" 192.168.2.0/24 dev nm-private scope link BASH |
最终所有的节点都可以访问 OpenWrt 的局域网 IP 了。
总结
至此,我们终于完成了 WireGuard 的系列的一个重要里程碑:通过 WireGuard + Netmaker 配置 Full Mesh 网络,并打通家庭局域网。🎉🎉🎉