WireGuard 搭建教程


12/3 更新

试用了几天感觉 WireGuard 用起来比 v2ray/ss 舒服,延迟好G像低一些,不知道是不是错觉,也许应该测一测,用数据说话。

当然,WireGuard 属于 VPN,与 v2ray 等代理软件还是有很大的区别的,改天也写一写。


12/2 更新

配置了几台不同的机器,遇到了一些问题,都与 ipv6 有关,调试起来很吃力,要不停的尝试。遇到问题可以试一试去掉 ipv6 的配置。我在一台机器上完全能用的配置,拿到另一台甲骨文机器上,ipv6 就不能用了:开启了 ipv6 转发机器本身就连不上 ipv6 的网络。


第三次想试一试 wireguard,前两次都因为“看起来太麻烦”而放弃了。


#安装

Debian 11:

sudo apt install wireguard wireguard-tools

Arch:

sudo pacman -S wiregiard-tools

验证安装,下面这条命令应该打印出 wiregurad 的信息

/sbin/modinfo wireguard

Wireguard 的文档太烂了,不知道是不是因为代码很短,大家都看代码学习。先按照他们的视频,把两台机器连通。

#手动配置连通

这一步内容是理解 WireGuard 用的,不感兴趣可以直接转到使用配置文件

视频来自 https://www.wireguard.com/quickstart/

文字描述:

#第一步,在每台机器上添加一块 wireguard 虚拟网卡,用于组网通信。

第一台,机器 A

umask 077; wg genkey > private # 在 owner 读写权限下,生成私钥
sudo ip link add wg0 type wireguard # 添加一块叫 wg0 的虚拟 wireguard 网卡
sudo ip addr add 10.0.3.1/24 dev wg0 # 给 wg0 网卡添加 ip 地址 10.0.3.1,子网掩码 255.255.255.0
sudo wg set wg0 private-key ./private # wireguard 设置密钥
sudo ip link set wg0 up # 启用刚刚添加的网卡

第二台,机器 B

配置过程与第一台一模一样,记得分配的 ip 地址在同一个网段里,如果子网掩码 255.255.255.0, 就只能最后一个数不同。

wg genkey > private
sudo ip link add wg0 type wireguard
sudo ip addr add 10.0.3.3/24 dev wg0
sudo wg set wg0 private-key ./private
sudo ip link set wg0 up

可以添加其他机器,用法相同,机器要在同一网段里,拥有不同的 ip 地址。

#第二步,给每台机器添加其他机器的公钥,允许他们通信

使用sudo wg或者wg pubkey < private查看刚刚生成的私钥所对应的公钥,然后在其他机器上添加这台机器的公钥,与允许的 ip 地址,接入点是网络中通信的实际网卡地址,可以是域名或者 ip。

机器 A

sudo wg set wg0 peer /A1wM9pyTmiTOsqOPbcQTXK3VIjBdud8EjDE9mtNyVA= allowed-ips 10.0.3.3/32 endpoint 10.0.0.195:36714

机器 B

sudo wg set wg0 peer z3vaO82NLB6uif6wGXxpIyr9L1462JEzguwedH8jDSI= allowed-ips 10.0.3.1/32 endpoint 107.174.70.179:35406

此时,两台机器可以通过设置的内网地址互相通信了,就像他们在同一个网段一样。

这已经组成了一个 VPN (虚拟专用网),但是中文语义下,VPN 一般指有虚拟专用网后,一个节点的流量全部由另一个节点转发,这就要其他的步骤,包括转发本机的全部流量到另一台机器,以及另一台机器允许转发流量。比如使用 iptables,将所有流量通过特定网卡出去。我们在下面使用配置文件的部分,再深入介绍。

上面的实验,把两台机器通过 WireGuard 连通,通过上面的过程,理解 WireGuard 的基本工作方式。上面的配置的虚拟网卡,重启后就会消失的无影无踪,接下来我们要把一台机器的流量全部转发到另一台,配置持久话,写入配置文件,方便启动与关闭。

#使用配置文件

把一群机器连在一个私有网络中,至少有一台电脑需要连接外网,其他机器都将发往外网的的流量发到这台机器,完成互联网通信。为了称呼方便,我们把这台机器叫做 server,但是要明白,这台机器和其他机器的唯一区别,就是去外网的流量由他最终发出。一个网络中可以有多台连接外网的机器,只要指定路由即可。

作为 server 的机器,需要开启 ip 转发,才能转发其他机器的流量。

#开启 ip 转发

我觉得看这篇文章的人,对 VPN,流量转发一类的事情,多有涉及,ip-forwarding 都是打开的。

参考 ArchWiki,在 /etc/sysctl.d 文件夹下建立配置转发文件,避免直接修改/etc/sysctl.conf,以后更新 sysctl 可能导致的配置文件被覆盖清除。

sudo nano /etc/sysctl.d/49-ip-forward.conf

写入下面两行文件

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

保存,退出,应用修改

sudo sysctl --system

#WireGuard 配置文件

#客户端

此客户端配置不能用于 VPS,点此查看 VPS 作为客户端的配置

[Interface]
PrivateKey = z3vaO811111uif6wGXxpIyr9L11111EzguwedH8jDSI=
Address = 10.9.7.132/24, 2604:6400:30:ee1b::2/64
DNS = 8.8.8.8, 2001:4860:4860::8888
MTU = 1280
[Peer]
PublicKey = /A1wM9py222222qOPbcQT1111IjBdud8EjDE9mtNyVA=
AllowedIPs = 0.0.0.0/0
AllowedIPs = ::/0
Endpoint = yourdomain.com:12345
#服务端
[Interface]
# Name = Lux
Address = 10.9.7.7/24, 2604:6400:30:ee1b::1/64
ListenPort = 12345
PrivateKey = qFiAzWGgwDKG5Rf9Gwoan3hK9vDVCAngoGo/RFvM51o=
DNS = 8.8.8.8, 2001:4860:4860::8888
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostUp = ip6tables -A FORWARD -i %i -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
PostDown = ip6tables -D FORWARD -i %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
# Name = NJ
PublicKey = z3vaO8283847uif6wG231Iyr9L1462JEz11111H8jDSI=
AllowedIPs = 10.9.7.132/32, 2604:6400:30:ee1b::2/128

如果保存在非默认路径:

sudo wg-quick up /home/acytoo/wg0.conf # 开启 wireguard vpn
sudo wg-quick down /home/acytoo/wg0.conf # 关闭 wireguard vpn

如果保存在 /etc/wireguard 里,则不需要文件后缀名,wg-quick 在处理参数时,如果文件名带有后缀名,则认为是完整路径的配置文件,如果没有后缀名,则默认是 Interface 名,在 /etc/wireguard/ 路径下。

上面的调用方法适合临时使用,wg-quick 同时提供 service,如果使用 wireguard 作为 service,需要把配置文件存入 /etc/wireguard/,然后使用

sudo systemctl start [email protected] # 开启 /etc/wireguard/cf.conf 指定的配置
sudo systemctl stop [email protected] # 关闭 /etc/wireguard/cf.conf 指定的配置
sudo systemctl enable [email protected] --now # 开启 /etc/wireguard/cf.conf 指定的配置,并设置开机自启
sudo systemctl disable [email protected] --now # 关闭 /etc/wireguard/cf.conf 指定的配置,并取消开机自启

配置文件选项解释:

[Interface]

  • PrivateKey: 本地私钥
  • Address: 本地 ip 地址
  • DNS: 指定的 dns,在 Debian 上需要安装 openresolv
  • MTU: 包大小
  • Table: 路由表规则,默认 auto
  • PreUp, PostUp, PreDown, PostDown: bash 命令,在开启的前,后;关闭的前,后执行,可以把对 iptables 的操作放在这里

[Peer]

  • PublicKey: 此节点的私钥对应的公钥
  • AllowedIPs: 允许的 ip 地址。只有在这里写的 ip, 才会经过相对应的 peer 发出,因此这里可以设置分流
  • Endpoint: 此节点的公网接口,可以是 ip ,可以是域名,加上端口。如果在另一个内网中,也可以用内网地址 + 端口。
  • PersistentKeepalive: 保持连接,间隔设置的时间沟通一次,保持服务端可以主动向客户端发送信息。

一些值得注意地方:

  1. [Interface]中的 Address 的掩码是 /24,包含了网段信息。在[peer]中,服务端的 AllowedIPs 只有相对应的 peer 一个,所以掩码是 /32,客户端中,我们相转发所有的流量,所以是 0.0.0.0/0 包括所有的地址。

  2. 服务端中在 PostUP, PostDown 中设置了两条 iptables 命令,第一句表示接受来自 wireguard 网卡的所有流量,第二句表示把这些流量通过你指定的网卡发送出去。这里一定要改成自己连接外网的网卡名。

  3. 如果想添加节点,只需要修改客户端的 ip 地址,并且在服务端添加性对应的[Peer] 即可。

  4. wg-quick 命令是 wireguard 的简单操作脚本,处理它能理解的配置字段,他不理解的配置,统统交给 wg 处理,建议看看 manpage,理解 wg-quick

#VPS 上的配置

上面的配置是本地的配置,不能用在 VPS 上,为什么?

因为上面的配置里,客户端把所有的流量都转发了,这样我们就没法从外部连接他(不能 ssh ),所以为了在 VPS 上使用双栈 WireGurad,需要客户端有特别的配置: 在 [Interface] 里加入

PostUp = ip -4 rule add from <Your IPv4> lookup main
PostDown = ip -4 rule delete from <Your IPv4> lookup main
PostUp = ip -6 rule add from <Your IPv6> lookup main
PostDown = ip -6 rule delete from <Your IPv6> lookup main

上面的命令,把外部连接到本地的连接不再转发,这样就能 ssh 了。

VPS 上的配置(客户端)是

[Interface]
PrivateKey = z3vaO811111uif6wGXxpIyr9L11111EzguwedH8jDSI=
Address = 10.9.7.132/24, 2604:6400:30:ee1b::2/64
DNS = 8.8.8.8, 2001:4860:4860::8888
MTU = 1280
PostUp = ip -4 rule add from <Your IPv4> lookup main
PostDown = ip -4 rule delete from <Your IPv4> lookup main
PostUp = ip -6 rule add from <Your IPv6> lookup main
PostDown = ip -6 rule delete from <Your IPv6> lookup main
[Peer]
PublicKey = /A1wM9py222222qOPbcQT1111IjBdud8EjDE9mtNyVA=
AllowedIPs = 0.0.0.0/0
AllowedIPs = ::/0
Endpoint = yourdomain.com:12345

VPS 双栈 WireGuard,发出的流量全部走 WireGuard 服务器,但是主动连接进入的流量,还是走原来的 IP。


如果使用 wgcf 生成配置,会有几个小时左右的时间无法连通,这不是配置的问题。大概是 CloudFlare 不给连,我试了几台机器都这样,一般第二天睡醒了就可以连接了。