使用 WireGuard 配置虚拟局域网

今天突然对内网穿透有兴趣,去在自己的云服务器上部署了 WireGuard,记录一下过程。但我其实也没想好拿这玩意儿究竟用来干啥。

这里只讨论使用 WireGuard 来建立虚拟局域网的用法,不讨论让所有流量都走 WireGuard 服务端即 VPN 那种用法。

啥是 WireGuard

WireGuard 是一种 VPN 协议——一台公网服务器作为服务端,其他设备作为客户端。服务端和客户端将处在一个虚拟局域网中并均有自己的虚拟 IP 供互相访问。

WireGuard 的实现简单——所有流量均通过服务端进行加密后的中转。也就是说在这个虚拟局域网中的互相访问的流量会加密后经过互联网。因为这里被加密了,所以使用 HTTP 这样的明文协议交互是可行的(当然,只是说“明文”这部分不需要担心)。但安全问题这里就不谈了,毕竟是个人使用,能出啥事。

WireGuard 的流量均通过服务端,没有 P2P,所以带宽和流量需要注意。

WireGuard 的配置非常容易——没有任何认证啥的幺蛾子,服务端和客户端均使用公钥相互验证。当然这也带来不便——服务端需要手动配置所有客户端的信息,如果新增客户端的话服务端需要手动编辑并重启

安装和配置过程

安装服务端

我用的是京东云,命令是:

1
apt install wireguard

生成服务端的密钥,创建配置文件

进入/etc/wireguard,执行下面的命令创建服务端的公私钥:

1
wg genkey | tee server_private.key | wg pubkey > server_public.key

然后创建文件 /etc/wireguard/wg0.conf,编辑它:

1
2
3
4
5
6
7
8
9
10
11
[Interface]
PrivateKey = <上面生成的私钥>
# 这个地址表示服务端的虚拟 IP 是 10.0.0.1
#(我不知道为啥需要配置这个莫名其妙的子网掩码,但既然示例里写了我就也写)
Address = 10.0.0.1/24
ListenPort = 51820
SaveConfig = true

# 这里的 eth0 可能需要替换成实际的网卡名,执行 ip addr show 去找到实际的网卡
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

这里的使用的网段只要是局域网的应该都行,如10.0.0.0/8下的。我后来换成腾讯云发现10.0.0.0/24被用了,换成了其他的。

安装和配置客户端

https://www.wireguard.com/install/下载各平台的客户端。(这里虽然说是客户端,但它们其实也可以当服务端,但不提这个)

图形客户端一般会自动创建自己的密钥,这里贴上参考的客户端的配置(客户端的 IP 要手动指定,下面的 IP 配置为10.0.0.2

注意AllowedIPs的配置很重要——它决定对哪些 IP 要去走 WireGuard 的线路,如果配置成10.0.0.0/24表示只需虚拟局域网内部访问。

1
2
3
4
5
6
7
8
9
10
11
12
13
[Interface]
PrivateKey = <客户端的私钥(一般是自动生成)的>
# 可以改为其他 IP,但要在 10.0.0.0/24 子网下
Address = 10.0.0.2/24
DNS = 8.8.8.8

[Peer]
PublicKey = <服务端的公钥>
# 10.0.0.0/24 表示只需虚拟局域网内部访问
# 0.0.0.0/0 表示所有流量均走服务端(即当成 VPN 去使用)
AllowedIPs = 10.0.0.0/24
Endpoint = <服务端的公网 IP>:51820
PersistentKeepalive = 25

让服务端知晓客户端

在服务端中增加客户端的信息(我把整个内容都贴上来):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[Interface]
PrivateKey = <上面生成的私钥>
# 这个地址表示服务端的虚拟 IP 是 10.0.0.1
#(我不知道为啥需要配置这个莫名其妙的子网掩码,但既然示例里写了我就也写)
Address = 10.0.0.1/24
ListenPort = 51820
SaveConfig = true

# 这里的 eth0 可能需要替换成实际的网卡名,执行 ip addr show 去找到实际的网卡
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
# 第一个客户端
PublicKey = <第一个客户端的公钥>
# 第一个客户端的虚拟 IP
AllowedIPs = 10.0.0.2/32

[Peer]
# 第二个客户端
PublicKey = <第二个客户端的公钥>
# 第二个客户端的虚拟 IP
AllowedIPs = 10.0.0.3/32

启动服务端

服务端还需要开启内核转发:

1
2
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p

然后,enable 相应 service 并启动:

1
systemctl enable --now wg-quick@wg0

启动客户端

这个就在 GUI 中直接操作。

Bonus:Windows 下 KDE Connect 无法使用的问题

KDE Connect 有入站规则限制——只有在专用网络下才能有 TCP/UDP 流量,而观察 WireGuard 客户端创建的虚拟网卡,它是公用,结果 kdeconnect 的流量会被拦截掉……我 tm debug 半天。

解决方法是编辑这个入站规则——

  1. Win+R,输入wf.msc回车
  2. 入站规则中,输入 k,会找到 4 条 kdeconnectd 的规则
  3. 禁用下面的两条阻止的规则
  4. 编辑上面两条规则,在高级选项卡中的配置文件部分勾选所有这 3 个复选框专用公用

这个也是记给自己看的……

Bonus:Windows 的 WireGuard 客户端配置开机自动连接

参照 https://serverfault.com/questions/1096001/how-to-start-wireguard-client-on-windows-in-the-background

这客户端就非常奇怪——没有开机自启动和自动连接的配置选项,而且找不到文档。

但实际上有方法:

  1. 先把配置文件的内容拷出来到一个特定的文件中,比如fun.conf(这个fun将成为配置名称)
  2. 使用管理员运行 CMD 或 PowerShell(我试了发现 git bash 似乎不行?),执行:
  3. "C:\Program Files\WireGuard\wireguard.exe" /installtunnelservice C:\绝对路径\到\fun.conf(注意——这个要是绝对路径!)

执行完上面的命令后,这个客户端会自动创建一个 Windows 服务并开机启动以自动进行连接。

检查服务定义,可以看到它实际上就是执行了:

1
"C:\Program Files\WireGuard\wireguard.exe" /tunnelservice C:\绝对路径\到\fun.conf

所以实际上也可以自己定一个快捷方式或脚本啥的去执行上面的命令而不用走 Windows 服务。


本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 协议 ,转载请注明出处!