12/3 更新
试用了几天感觉 WireGuard 用起来比 v2ray/ss 舒服,延迟低一些,不知道是不是错觉,也许应该测一测,用数据说话。
当然,WireGuard 属于 VPN,与 v2ray 等代理软件还是有很大的区别的,改天也写一写。
12/2 更新
配置了几台不同的机器,遇到了一些问题,都与 ipv6 有关,调试起来很吃力,要不停的尝试。遇到问题可以试一试去掉 ipv6 的配置。我在一台机器上完全能用的配置,拿到另一台甲骨文机器上,ipv6 就不能用了:开启了 ipv6 转发机器本身就连不上 ipv6 的网络。
第三次想试一试 wireguard,前两次都因为“看起来太麻烦”而放弃了。
#安装
Debian 11:
sudo apt install wireguard wireguard-tools resolvconf
Arch:
sudo pacman -S wiregiard-tools
验证安装,下面这条命令应该打印出 wiregurad 的信息
/sbin/modinfo wireguard
Wireguard 的文档太烂了,不知道是不是因为代码很短,大家都看代码学习。先按照他们的视频,把两台机器连通。
#手动配置连通
这一步内容是理解 WireGuard 用的,不感兴趣可以直接转到使用配置文件
文字描述:
#第一步,在每台机器上添加一块 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, 就只能最后一个数不同。
umask 077; 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
如果有多台客户端组网,只需重复添加 [peer]
段。
如果保存在非默认路径:
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 wg-quick@cf # 开启 /etc/wireguard/cf.conf 指定的配置
sudo systemctl stop wg-quick@cf # 关闭 /etc/wireguard/cf.conf 指定的配置
sudo systemctl enable wg-quick@cf --now # 开启 /etc/wireguard/cf.conf 指定的配置,并设置开机自启
sudo systemctl disable wg-quick@cf --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: 保持连接,间隔设置的时间沟通一次,保持服务端可以主动向客户端发送信息。
一些值得注意地方:
-
在
[Interface]
中的Address
的掩码是/24
,包含了网段信息。在[peer]
中,服务端的AllowedIPs
只有相对应的 peer 一个,所以掩码是/32
,客户端中,我们相转发所有的流量,所以是0.0.0.0/0
包括所有的地址。 -
服务端中在 PostUP, PostDown 中设置了两条 iptables 命令,第一句表示接受来自 wireguard 网卡的所有流量,第二句表示把这些流量通过你指定的网卡发送出去。这里一定要改成自己连接外网的网卡名。
-
如果想添加节点,只需要修改客户端的
ip
地址,并且在服务端添加性对应的[Peer]
即可。 -
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 不给连,我试了几台机器都这样,一般第二天睡醒了就可以连接了。