本教程主要为从Linode文档Set Up WireGuard VPN on Debian处翻译搬运的版本,其中加入了一些个人的经验和见解和修改,如果您有任何疑惑,欢迎您随时与我们联系。
本实例使用的是 Debian GNU/Linux 9.13 (stretch) ,如果您使用的包管理软件并不相同,或是您的系统版本并不完全一致,则可能会有不一样的表现。
WireGuard 的网卡名未必必须为 wg0 的格式,您可以自行修改命名。只要记得同时调整相关的防火墙规则即可。客户端与服务器的网卡名也未必必须一致,您只要能确认分辨即可。
- 除非您知道您在做什么,否则不要轻易改动IPv4地址中关于 /24 和 /32 的掩码配置。特别地,根据我的无数次翻车测试,一般仅主服务器保留 /24 的地址分配、其他的请保留 /32 的配置,防止地址冲突找不到路由。原作者显然没有测试过多节点的情况,否则是绝对不可能用一套/24带走的。
- 除非您知道 WireGuard 服务端会对您的配置文件做什么,否则请删除
SaveConfig = true
这一行。已经被坑害过好多次了。 - 请尽量使用dkms来构建 WireGuard ,虽然需要保证内核头文件的正确安装在上古的 CentOS 系统上需要离谱的第三方本地安装,但这样一般能保证版本最新、bug最少。
- 此教程同样也适用于 Debian 10.
2021/02/20 修正一个说法问题:
WireGuard 是一个节点间相互对等的 P2P 的协议,没有客户端与服务器的区分,所有的节点之间通过彼此配置的 Peer
来建立连接。
由于没有中心,因而没法 DHCP ,所有的 IP 均为手动静态分配,如果出现路由异常的情况,您可以尝试分配给每个 IPv4 均为 /32 的地址(即完全锁定的无子网地址),我现在就是通过这种方式建立起无中心的点对点网络的。
WireGuard 是什么
WireGuard®是一个简单,快速且安全的,使用了最先进加密技术的 VPN (注:Virtual Private Network, 虚拟私有网络,不是翻墙使用的代理工具,概念不能混淆)。使用了短小精悍的源码脚本的它,致力于成为比其他 VPN 协议,例如 OpenVPN 或是 IPSec ,更加精简与快速。 WireGuard 目前仍处于开发阶段,但就连它的还未优化的状态,甚至都已经比主流的 OpenVPN 协议更加快速了。
WireGuard 会设置标准的网络接口(例如wg0或是wg1,用户可以自定义命名),所以它的表现更像是常见的 eth0 接口。这使它能通过一些标准工具,例如ifconfig
或是ip
提供了可能。目前,WireGuard已经能在所有的平台上使用。
配置WireGuard就如同配置SSH一样简单。一个连接通过服务器与客户端间交换公钥来确定,只有当一个客户端在它对应的服务器配置文件中包含了它的公钥时,它才会被允许进行连接。一份 WireGuard 服务器的配置文件会以类似如下的样式来呈现:
1 | [Interface] |
在这份教程中,您将会学到:
- 在一台 Debian 9 系统的 VPS 上配置 WireGuard 的服务端
- 在您的本地计算机,或是另一台 VPS 上配置 WireGuard 的客户端
- 在 WireGuard 的服务端与客户端间轻松地建立一个连接
请避免在关键的应用中使用WireGuard。这个项目目前还在进行严格性测试,并很有可能会在未来收到频繁的大升级。
在开始之前
- 寻找一台运行着 Debian 9 的服务器
- 寻找一位拥有 sudo 权限的用户(其实root就可以)
- 设置系统的主机名(hostname,但其实无所谓)
请注意,如果您以root
权限运行,那么是不需要执行sudo
操作的。并且 apt-get install 操作会被逐渐淘汰,因而建议您直接使用 apt install 进行方便简洁的管理。
这份教程需要配合使用了GRUB 2
内核的系统使用。默认情况下新开出来的机器应当都是启用了。但如果您运行的是一个旧的版本,您需要检查您运行的是哪个内核。如果可以的话,您也许需要升级内核,并在管理面板处设置使用GRUB 2
引导启动。
安装 WireGuard
将 WireGuard 的仓库加入到您的 apt 源列表中。apt 会自动更新包缓存。
1
2echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable-wireguard.list
printf 'Package: *\nPin: release a=unstable\nPin-Priority: 150\n' > /etc/apt/preferences.d/limit-unstable更新您的包,并且安装 WireGuard 和 WireGuard 相关的工具。 DKMS (Dynamic Kernel Module Support,动态内核模组支持)会构建 WireGuard 内核模组。
1
2apt update
apt install wireguard-dkms wireguard-tools
成功后,您将看到类似这样的输出:
1
2
3
4
5
6
7
8
9
10wireguard.ko:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/4.19.0-13-amd64/updates/dkms/
depmod....
DKMS: install completed.
配置 WireGuard 服务端
切换至
/etc/wireguard
目录,并为 WireGuard 服务器生成一对公私钥:1
2sudo umask 077
sudo wg genkey | tee privatekey | wg pubkey > publickey这将会同时保存公钥与私钥。它们可以通过
cat privatekey
和cat publickey
来分别查看。创建文件
/etc/wireguard/wg0.conf
并且添加如下的内容。您需要在PrivateKey
配置项处输入您服务器的私钥,并在Address
配置项处输入它的私有地址。您可以参阅配置样例下方的解释表来获取更多的细节。/etc/wireguard/wg0.conf 1
2
3
4
5
6
7[Interface]
PrivateKey = <Private Key>
Address = 10.0.0.1/24, fd86:ea04:1115::/64
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -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; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
SaveConfig = true- PrivateKey 之前生成的服务器的私钥
- Address 定义了WireGuard服务器的私有IPv4和IPv6地址。每一个VPN网络中的节点在这个设置项中都应当拥有一个独立的值。典型的值有
10.0.0.1/24
,192.168.1.1/24
,或是192.168.2.1/24
。这和您的私有IP地址应当不重复。特别的,请检查您的网卡与已经分配的IP地址,该子域不应当与任何子域重复。 - ListenPort 指定了WireGuard应当使用哪一个接口作为入站的连接。默认值为51820,您在此处设置的值会影响到之后您对应防火墙规则的设置。
- PostUp 和 PostDown 分别定义了开启或是关闭网关时需要执行的步骤。在本实例中,使用iptables用来设置 Linux IP 伪装规则,来允许客户端共享服务端的IPv4地址和IPv6地址。当通道关闭时,这些规则会被清理。
- SaveConfig 当服务正在运行时,新添加的节点会自动更新至配置文件中去。
配置防火墙规则
我们推荐使用iptables一套带走,但出于对于原文的尊重,我们将ufw的相关操作翻译并放置于此。
安装UFW
1
sudo apt-get install ufw
添加SSH连接和WireGuard的VPN端口(请注意根据您的具体情况进行调整)
1
2
3sudo ufw allow 22/tcp
sudo ufw allow 51820/udp
sudo ufw enable验证您的设置
1
sudo ufw status verbose
安装
ipset
,为 iptables 提供一个方便的批量地址管理工具1
apt install ipset
新建一个 ip 集合,添加会用到的客户端的公网 IP
1
2ipset create wgclients hash:ip
ipset add wgclients 1.2.3.4 # WireGuard的客户端公网IP编写 iptables 防火墙规则,仅允许可信客户端连接,丢弃所有非可信的数据包
1
2iptables -A INPUT -m set --match-set wgclients src -p udp --dport 51820 -j ACCEPT
iptables -A INPUT -p udp -m multiport --dport 51820 -j DROP保存防火墙规则
1
iptables-save
启动 WireGuard 服务
启动 WireGuard
1
sudo wg-quick up wg0
wg-quick
是wg
中许多常用功能的封装。您可以使用wg-quick down wg0
来关闭 wg0 接口。设置 WireGuard 服务为开机自启
1
sudo systemctl enable wg-quick@wg0
用下列两条指令来检查 VPN 隧道是否已经正确运行
1
sudo wg show
您应该会看到类似的输出:
1
2
3
4
5user@debian:/# wg show
interface: wg0
public key: Nrl2nVQxSwrKrvz6jQcrsziuVRPWT9N1Q8/yaQkAXUg=
private key: (hidden)
listening port: 51820您可能需要安装 net-tools 来运行
ifconfig
。如有必要的话,您可以使用sudo apt-get install net-tools
。或者我们推荐使用更强大的
ip
指令,后文会有补充提及。出于对原文的尊重,此处是 ifconfig 指令的翻译。1
sudo ifconfig wg0
您的输出应当看上去像这样:
1
2
3
4
5
6
7
8
9user@debian:/# ifconfig wg0
wg0: flags=209<UP,POINTOPOINT,RUNNING,NOARP> mtu 1420
inet 10.0.0.1 netmask 255.255.255.0 destination 10.0.0.1
inet6 fd86:ea04:1115::1 prefixlen 64 scopeid 0x0<global>
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 1 (UNSPEC)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
1 | ip addr show wg0 |
您的输出应当看上去像这样:
1 | user@debian:~# ip addr show wg0 |
配置 WireGuard 客户端
设置 WireGuard 客户端的过程与设置服务端的过程非常相似。当使用 Debian 作为您的客户端操作系统时,客户端与服务端间唯一的区别在于配置文件。在这个模块中,您将会了解到如何在 Debian 9 上配置一个 WireGuard 客户端。
您可以参阅 WireGuard 文档 以获取在其他平台上的安装指引。
参阅本教程中的
安装 WireGuard
段来完成安装工作。 WireGuard 的客户端与服务端是对等的。当您完成安装后,您可以参阅
配置 WireGuard 服务端
段来完成客户端的配置工作。只需要将样例的配置文件题欢成如下的样例即可。/etc/wireguard/wg0.conf 1
2
3[Interface]
PrivateKey = <Client Private Key>
Address = 10.0.0.2/32, fd86:ea04:1116::/64客户端与服务端的区别在于配置文件
wg0.conf
,该文件包含了本网卡自己的IP地址,并且不包含ListenPort
,PostUP
,PostDown
,或是SaveConfig
段的内容。在您的 WireGuard 客户端上
配置防火墙规则
。启动 WireGuard 服务
。
连接客户端与服务器
在服务器和客户端上使用
sudo wg-quick down wg0
来停止接口。编辑客户端上的
wg0.conf
文件,添加服务器的公钥、公网 IP 地址、端口和该段分配的 IP CIDR 地址块(修正了原文中不够优雅的的写法)/etc/wireguard/wg0.conf 1
2
3
4[Peer]
PublicKey = <Server Public key>
Endpoint = <Server Public IP>:51820
AllowedIPs = 10.0.0.1/32, fd86:ea04:1115::/64编辑服务器上的
wg0.conf
文件,添加客户端的公钥和该段分配的 IP CIDR 地址块/etc/wireguard/wg0.conf 1
2
3[Peer]
PublicKey = <Client Public Key>
AllowedIPs = 10.0.0.2/32, fd86:ea04:1116::/64在服务器和客户端上分别启动 WireGuard 服务
1
sudo wg-quick up wg0
您也可以使用命令行将节点加入至服务器。由于配置文件中开启了 SaveConfig 选项,这些信息会被自动加入到配置文件中。
在服务器运行以下指令,使用预计分配给客户端的 IP 地址来替换样例中的内容:
1
sudo wg set wg0 peer <Client Public Key> allowed-ips 10.0.0.2/32,fd86:ea04:1116::/64
验证连接。以下的指令在客户端和服务器上均可运行。
1
sudo wg
无论您使用哪种方式添加节点信息,当您运行
sudo wg
指令时, Peer 部分都应当会出现在输出中。1
2
3
4
5
6
7
8
9user@debian:/# sudo wg
interface: wg0
public key: vD2blmqeKsV0OU0GCsGk7NmVth/+FLhLD1xdMX5Yu0I=
private key: (hidden)
listening port: 51820
peer: iMT0RTu77sDVrX4RbXUgUBjaOqVeLYuQhwDSU+UI3G4=
endpoint: 10.0.0.2:51820
allowed ips: 10.0.0.2/32, fd86:ea04:1115::/64当服务进程重启时,这个节点会被自动添加到
wg0.conf
中。如果您希望立刻将这信息添加到配置文件,您可以运行以下指令:1
sudo wg-quick save wg0
额外的客户端可以被使用同样的过程来加入。
测试连接
回到客户端并使用 ping 来向服务器发起请求:
1 | ping 10.0.0.1 |
当您成功建立连接并从客户端访问到服务端时,您可以运行如下的命令:
1 | sudo wg |
wg
命令输出的最后两行应当看起来像这样:
1 | latest handshake: 1 minute, 17 seconds ago |
这证明了您已经建立了一条服务器与客户端的私密链接。如果您无法成功从客户端 ping 到服务端(前提是您的服务端允许 ping ),您将不会看到这些行。您也可以从服务端 ping 客户端,来证明这条连接在两边都能工作。
后续步骤
这篇教程中使用的步骤可以拓展,以便构建网络的拓补结构。如同上文提及的, WireGuard 是一种仍在发展中的技术。如果您使用 WireGuard, 您应当注意官方文档和计划清单,以便为关键的升级和新的特性做好准备。
WireGuard
是Jason A. Donenfeld的注册商标。
原文链接:Set Up WireGuard VPN on Debian | Linode,翻译时有补充修改内容,修复了一些写法上的错误。
可能遇到的问题
RTNETLINK answers: Permission denied
请检查您的内核是否关闭了 IPv6 的支持:
1
sysctl -a | grep disable_ipv6
如果看到有 = 1 的项,说明是存在禁用了 IPv6 的情况。
修改/etc/sysctl.conf
文件,将所有disable_ipv6
后 = 1 的全都改成 0 。RTNETLINK answers: Operation not supported
您的系统可能缺失必要的 Kernel Headers ,您可以使用apt补充安装:
1
apt install linux-headers-$(uname -r)