最近因为想将自己写的音乐下载机器人部署到云上,于是开了一台 Hetnzer ,不得不说,质量是真好速度是真快呀!德意志战车!! ,突然心血来潮,准备配一个本机和 Hetnzer 的 WireGuard 连接。

学习和使用了 WireGuard 这么久,也没有自己正儿八经配一个。之前玩 DN42 的时候更多地是在抄作业,至于原理和细节,就根本没有去深究,不过也潜移默化了解了很多。

首先是服务端的配置(其实可能不太严谨,暂且称为服务端吧。)

还是以 Debian 为例

常规的安装:

1
sudo apt update && apt install wireguard

贴一个我这次使用的服务端的 wg0.conf

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
[Interface]
PrivateKey = <服务端私钥>
ListenPort = 520
Address = 10.0.0.1/24, fd00::1/64
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostUp = ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
PostDown = ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = <客户端公钥>
AllowedIPs = 10.0.0.2/32, fd00::2/128

[Peer]
PublicKey = <客户端公钥>
AllowedIPs = 10.0.0.3/32, fd00::3/128

我这个 Address 的选择其实并不好,但是一开始配置的时候并没有意识到,10 段和校园网内网的网段重合了,就,不太文明。 所以可以查询一下这个 Reserved_IP_addresses 看一下哪个段可以选用,我最终使用的是 100.64.0.1/24, fc00::1/64 这个两个段。

接着,开启对应的端口,允许流量通过,我这台机器上默认使用了 iptables

1
2
sudo iptables -A INPUT -p udp --dport 520 -j ACCEPT
sudo ip6tables -A INPUT -p udp --dport 520 -j ACCEPT

确认一下规则是否已经应用了:

1
2
sudo iptables -L INPUT -n
sudo ip6tables -L INPUT -n

正常的话,应该有以下输出:

1
2
3
4
5
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     0    --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     0    --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
ACCEPT     17   --  0.0.0.0/0            0.0.0.0/0            udp dpt:520
1
2
3
4
5
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     17   --  ::/0                 ::/0                 udp dpt:520
ACCEPT     17   --  ::/0                 ::/0                 udp dpt:520
ACCEPT     17   --  ::/0                 ::/0                 udp dpt:520

启用 IP 转发

确保在服务器上启用 IP 转发。这一步对允许通过 WireGuard 隧道转发流量是至关重要的。以下是启用 IP 转发的步骤:

临时启用 IP 转发

对于 IPv4:

1
sudo sysctl -w net.ipv4.ip_forward=1

对于 IPv6:

1
sudo sysctl -w net.ipv6.conf.all.forwarding=1

永久启用 IP 转发

编辑 /etc/sysctl.conf文件:

1
sudo vim /etc/sysctl.conf

确保以下行未被注释(去掉前面的 # 号):

对于 IPv4:

1
net.ipv4.ip_forward=1

对于 IPv6:

1
net.ipv6.conf.all.forwarding=1

保存文件并运行以下命令使更改生效:

1
sudo sysctl -p

启动 WireGuard 服务:

1
2
sudo wg-quick up wg0
sudo systemctl enable wg-quick@wg0

检查NAT规则:

验证 PostUp 和 PostDown 脚本是否正确添加和删除了NAT规则:

1
2
sudo iptables -t nat -L POSTROUTING
sudo ip6tables -t nat -L POSTROUTING

配置详解

  • [Interface] 部分
    • PrivateKey:这是服务端的私钥,用于加密通信。
    • ListenPort:WireGuard 将在这个端口上监听传入的连接。
    • Address:这是服务端在虚拟网络中的地址。在这个例子中,服务端的 IPv4 地址是 10.0.0.1,IPv6 地址是 fd00::1。这些地址是内部的 WireGuard 网络地址,不与物理接口直接关联。
    • PostUpPostDown:这些命令在接口启动和关闭时执行,用于设置和清除 NAT 规则,使得流量可以通过 eth0 接口访问外网。
  • [Peer] 部分
    • PublicKey:每个对等端的公钥,用于验证对等端的身份。
    • AllowedIPs:定义了哪些 IP 地址可以通过这个对等端进行路由。这里指定的 10.0.0.2/32fd00::2/128 是客户端的地址。

Address 的作用和关联

  • 服务端的 Address:定义服务端在 WireGuard 虚拟网络中的 IP 地址。这些地址用于服务端和客户端之间的通信,并且不与物理网络接口直接关联。
  • 客户端的 Address:同样地,定义客户端在 WireGuard 虚拟网络中的 IP 地址。这些地址在客户端的配置文件中指定,用于标识客户端在 WireGuard 网络中的位置。
  • 关联性:服务端和客户端的 Address 需要在相同的子网范围内,确保它们可以互相通信。比如,服务端的地址是 10.0.0.1/24,客户端可以是 10.0.0.2/24。IPv6 地址也遵循同样的原则。

客户端的配置

在本机(我的 Mac)上配置 WireGuard。首先,安装 WireGuard,直接在 Apple Store 搜索下载安装即可,也可以去官网下载安装。

然后,配置客户端的 wg0.conf 文件:

1
2
3
4
5
6
7
8
9
[Interface]
PrivateKey = <客户端私钥>
Address = 10.0.0.2/24, fd00::2/64
DNS = 8.8.8.8, 2001:4860:4860::8888

[Peer]
PublicKey = <服务端公钥>
Endpoint = <服务端IPv6地址>:520
AllowedIPs = 0.0.0.0/0, ::/0

这里的 Endpoint 参数指定了服务端的 IPv6 地址和端口号 520。AllowedIPs 参数设置为 0.0.0.0/0, ::/0,意味着所有的流量都将通过 WireGuard 隧道进行转发。

如果你有更多的网络设置需求,可以看一下这个:WireGuard AllowedIPs Calculator

测试连接

确保客户端和服务端之间的连接已经建立。可以使用 wg 命令查看 WireGuard 的状态:

1
sudo wg

如果一切正常,你应该能够看到客户端和服务端之间的连接已经建立,并且流量正在通过隧道传输。

排查问题

在配置过程中,我遇到了一些问题:客户端无法通过 VPS 的 IPv6 地址进行通信。以下是一些排查问题的步骤:

  1. 检查服务端的 IPv6 配置:确保 VPS 上已正确配置 IPv6 地址,并且可以访问外部 IPv6 地址。例如,使用 ping6 命令测试外部 IPv6 地址。

  2. 检查路由表:使用 ip -6 route 命令查看 VPS 的 IPv6 路由表,确保 IPv6 流量可以正确地路由到互联网。

  3. 防火墙设置:确保 VPS 上的防火墙配置没有阻止 IPv6 流量。使用以下命令允许 IPv6 流量通过 WireGuard 接口和 eth0 接口:

    1
    2
    
    sudo ip6tables -A INPUT -p udp --dport 520 -j ACCEPT
    sudo ip6tables -A FORWARD -i wg0 -j ACCEPT
    
  4. IPv6 DNS 服务器:如果使用 IPv6 地址作为出口,确保配置了正确的 IPv6 DNS 服务器,例如 2001:4860:4860::8888

2024年7月6日更新

前几天发现我的 WireGuard IPv4 回程被ban了,于是我就切换到了 IPv6 访问,一致在考虑怎么解决这个问题,毕竟很多时候的设备都是没有 IPv6 的,所以还是想尽快恢复 IPv4 的使用,然后和朋友聊天的时候,说起了这个事情,一下子想起来:有没有可能是我使用的端口有点奇怪了?疑似是什么奇怪的工具流量?然后我立刻换了一个端口的 Endpoint 立刻就好了。

看起来 GFW 有时候还是会有一些奇怪的规则限制的,不过我倒是一下子放宽心了:毕竟端口多的是,你随便 BAN ,我换一个就好了。

所以如果你发现你使用的 WireGuard IPv4 回程被ban了,可以尝试换一个端口的 Endpoint,然后再试一下。

总结

经过一晚上的瞎折腾,我 Hetzner VPS 和本地机器之间建立了 WireGuard 连接,并且可以通过 VPS 进行流量转发。这个过程让我更深入地理解了 WireGuard 的配置和工作原理,也为以后更复杂的网络配置打下了基础,还是菜啊。什么时候能不菜!!

参考链接:

WireGuard AllowedIPs Calculator