WireGuard 初体验
1 概要
本文主要介绍 WireGuard(以下简称 WG)的基本配置方法,并记录一下配置过程中踩到的坑和相应的解决办法。
2 环境
服务器是 Bandwagon 的 VPS 主机,安装的操作系统是 CentOS 7。
客户端操作系统是 macOS 和 Android,后面会尝试在 Linux/Windows 上折腾,但是理论上没太大区别。
3 服务端设置
本章节的大部分操作都需要在 root 身份下运行,请先切换到 root 用户,或在每个命令前加上
sudo
。
3.1 安装
在 CentOS 上,主要使用 yum
作软件包管理。
WG 的软件包是 wireguard-dkms
和 wireguard-tools
。由于 WG 使用了 Linux 的 DKMS 框架,而 CentOS 7 默认是不提供的,因此还需要安装 dkms
。
首先添加软件源:
1 | # 添加epel软件源,dkms需要从这个软件源安装 |
注意:这里有个坑,Bandwagon 提供的 CentOS 7 系统,第一次添加 epel 软件源可能不会生效。如果出现这种情况,请执行命令:
1 | # 删除垃圾文件 |
软件源添加完成后,安装必要的软件包:
1 | # 安装wireguard软件包,dkms作为依赖会自动安装 |
安装成功后,需要重启服务器,让 dkms 生效。
3.2 WG 配置
3.2.1 生成密钥
WG 使用非对称加密算法来保护信道,因此首先要生成一对密钥:
1 | # 生成公私密钥 |
3.2.2 编写配置文件
这里假定使用
51802
作为 VPN 服务的端口,192.168.99.0/24
作为 VPN 内网的 IP 段,VPN 服务器的内网 IP 为192.168.99.1
。注意:VPN 内网的 IP 段,不能与客户端所在的内网 IP 段冲突。
创建文件 /etc/wireguard/wg0.conf
,添加如下内容:
1 | [Interface] |
基于安全考虑,请将上一步生成的私钥文件删除,并修改配置文件的权限:
1 | # 修改配置文件权限 |
3.2.3 启动服务
启动 WG:
1 | wg-quick up wg0 |
查看状态:
1 | wg show |
这里配置的 WG 还不会随开机自动启动,考虑到服务器很少有重启的情况,就没有深入研究。以后有时间会研究自启动方案。
3.3 系统配置
3.3.1 启用数据转发
1 | echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/10-ipforward.conf |
3.3.2 开启数据包伪装
注意:如果你使用了防火墙工具包(如 firewalld/ufw),那么 iptables 里面的规则都是由该工具包维护的,请使用工具包对应的指令添加,而不要直接修改 iptables。
我的服务器用的是 firewalld,需要通过以下命令开启数据包伪装:
1 | firewall-cmd --add-masquerade |
ufw 等其他防火墙工具包,请参照对应的文档。
直接配置 iptables(适用于没有使用任何防火墙工具包的场景):
1 | iptables -A FORWARD -i wg0 -j ACCEPT |
注意:直接添加的 iptables 规则会在重启后丢失,如需持久化,请使用 iptables-save
。
3.3.3 开放服务端口
如果你使用了防火墙,那么需要在防火墙中开放 WG 的服务端口。
WG 使用的是 UDP 协议,本文中使用的服务端口为 51802
,执行命令:
1 | # 动态添加规则 |
ufw 等其他防火墙工具包,请参照对应的文档。
4 客户端配置
4.1 编写配置文件
不管何种客户端,都是基于 WG 的内核,因此配置文件都是相同的。
配置客户端的第一步,也是生成一对密钥。大部分客户端直接提供了生成密钥的功能,此外也可以使用服务器端的 wg
命令来生成。
不同于大部分 VPN 服务,WG 目前不提供自动分配 IP 的功能。因此在配置客户端时,需要手工指定一个 IP,这个 IP 应该属于前面规划的 VPN 子网 IP 段中。当配置多个客户端时,要确保它们的 IP 互相不冲突。
这里假定为客户端分配的 IP 为
192.168.99.2
。
客户端配置文件的格式如下:
1 | [Interface] |
之后将这个配置文件,导入到对应的客户端中即可。
4.2 注册到服务端
只配置客户端还是不够的,还需要将客户端的公钥注册到 WG 的服务端,服务端才会允许该客户端连接。
在服务器端,通过 wg
命令,可以动态添加客户端:
1 | wg set wg0 peer <客户端公钥> allowed-ips "192.168.99.2/32" |
注意:在这条命令中,子网掩码必须使用 /32
。
当然,
wg
也同样提供了动态删除客户端的命令:
1 wg set wg0 peer <客户端公钥> remove
至此,全部配置完成,只需在客户端启动 VPN 连接即可。
Enjoy It!
5 总结
正如你看到的那样,WG 在实际使用中还不是那么方便。比如:不能自动分配 IP,每次增 / 减客户端都需要去服务端配置。
作者创建了 wg-dynamic 项目,计划解决其中的一些问题,不过目前还是 WIP 状态。
VPN 还有一点麻烦的地方是,它会将客户端的所有流量都路由到 VPN,不像 socks5/http 代理那样可以配合 PAC 使用。(当然这也可以通过设置复杂的路由规则解决,不过都是基于 IP 的,而不是域名)。
另外据说 WG 更容易遭到识别,不过以我家的宽带来看,两个主流的科学上网协议都撞了墙,只有 WG 还生龙活虎。
单就个人感受来说,WG 使用起来利大于弊。