WireGuard (简体中文)
引用自 WireGuard 项目主页:
WireGuard 是一种极其简单但快速且现代的 VPN,它利用了最先进的加密技术。它的目标是比 IPsec 更快、更简单、更精简和更有用,同时避免令人头疼的问题。旨在提供比 OpenVPN 更高的性能。WireGuard 被设计为在嵌入式接口和超级计算机等上运行的通用 VPN,适用于许多不同的环境。最初仅支持 Linux 平台,现在可以进行跨平台(Windows、macOS、BSD、iOS、Android)的广泛部署。目前仍然在大力开发中,但已经被认为是业内最安全、最容易使用和最简单的 VPN 解决方案。
安装
- 安装 wireguard-tools 包
- 对于版本小于 5.6 的 Linux 内核,需要额外安装合适的内核模块(当使用默认的 linux 包时不需要):
- wireguard-dkmsAUR 用于其他版本小于 5.6 的 DKMS 变体内核。
使用
在 peer 上生成公钥和私钥:
$ wg genkey | tee privatekey | wg pubkey > publickey
下面的指令会演示如何以表中的配置建立一条两个 peer 之间的隧道
Peer A | Peer B | |
---|---|---|
公网地址 | 10.10.10.1/24 | 10.10.10.2/24 |
内网地址 | 10.0.0.1/24 | 10.0.0.2/24 |
wireguard 监听端口 | UDP/4857 | UDP/3981 |
Peer 应当已经拥有公网地址。例如,peer A 应当能够通过 ping 10.10.10.2
ping 通 peer B,反之亦然。内部地址是由下文 ip
命令创建的新地址,并且将在 WireGuard 网络中共享。IP地址中 /24
的含义详见 CIDR
Peer A 配置
这个 peer 将监听 UDP 端口 48574,通过将 peer B 的公钥与其内部和外部 IP 地址关联,接受来自 peer B 的连接。
# ip link add dev wg0 type wireguard # ip link set dev wg0 mtu 1420 # ip addr add 10.0.0.1/24 dev wg0 # wg set wg0 listen-port 4857 private-key ./privatekey # wg set wg0 peer [Peer B public key] persistent-keepalive 25 allowed-ips 10.0.0.2/32 endpoint 10.10.10.2:3981 # ip link set wg0 up
[Peer B public key]
的格式应当如同 EsnHH9m6RthHSs+sd9uM6eCHe/mMVFaRh93GYadDDnM=
。allowed-ips
是 peer A 能够向之发送流量的地址列表。allowed-ips 0.0.0.0/0
将允许向任意地址发送流量。
Peer B 配置
如同 Peer A,只不过 wireguard 守护监听 UDP 端口 39814 并且只接受 peer A 的连接
# ip link add dev wg0 type wireguard # ip link set dev wg0 mtu 1420 # ip addr add 10.0.0.2/24 dev wg0 # wg set wg0 listen-port 3981 private-key ./privatekey # wg set wg0 peer [Peer A public key] persistent-keepalive 25 allowed-ips 10.0.0.1/32 endpoint 10.10.10.1:4857 # ip link set wg0 up
基本检查
不带任何参数使用 wg 命令可以快速查看当前的配置。
例如,当 peer A 配置好之后,我们可以看见它的身份和与之关联的 peers。
peer-a$ wg interface: wg0 public key: UguPyBThx/+xMXeTbRYkKlP0Wh/QZT3vTLPOVaaXTD8= private key: (hidden) listening port: 4857 peer: 9jalV3EEBnVXahro0pRMQ+cHlmjE33Slo9tddzCVtCw= endpoint: 10.10.10.2:3981 allowed ips: 10.0.0.2/32
此时我们可以 ping 通隧道的另一端:
peer-a$ ping 10.0.0.2
配置持久化
配置可以通过 showconf
来保存
# wg showconf wg0 > /etc/wireguard/wg0.conf # wg setconf wg0 /etc/wireguard/wg0.conf
示例 peer 配置
/etc/wireguard/wg0.conf
[Interface] PrivateKey = [CLIENT PRIVATE KEY] MTU = 1420 [Peer] PublicKey = [SERVER PUBLICKEY] AllowedIPs = 10.0.0.0/24, 10.123.45.0/24, 1234:4567:89ab::/48 Endpoint = [SERVER ENDPOINT]:5182 PersistentKeepalive = 25
配置一个 VPN 服务器
WireGuard 自带一个快速创建和销毁 VPN 服务器的工具,wg-quick
。注意这里使用的配置文件不是一个能被 wg setconf
有效的配置文件,并且你可能至少要把 eth0
改成你实际使用的。
服务器
/etc/wireguard/wg0server.conf
[Interface] Address = 10.0.0.1/24 # This is the virtual IP address, with the subnet mask we will use for the VPN PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE ListenPort = 5182 PrivateKey = [SERVER PRIVATE KEY] MTU = 1420 [Peer] PublicKey = [CLIENT PUBLIC KEY] AllowedIPs = 10.0.0.2/32 # 这表示客户端只有一个 IP。
要使 iptables 规则生效,启用 IPv4 转发:
# sysctl net.ipv4.ip_forward=1
永久保留这项改变,向 /etc/sysctl.d/99-sysctl.conf
添加 net.ipv4.ip_forward = 1
。
使用 wg-quick up wg0server
启用 Interface,wg-quick down wg0server
用以关闭
客户端 (转发所有流量)
/etc/wireguard/wg0.conf
[Interface] Address = 10.0.0.2/24 # The client IP from wg0server.conf with the same subnet mask PrivateKey = [CLIENT PRIVATE KEY] DNS = 10.0.0.1 MTU = 1420 [Peer] PublicKey = [SERVER PUBLICKEY] AllowedIPs = 0.0.0.0/0, ::0/0 Endpoint = [SERVER ENDPOINT]:5182 PersistentKeepalive = 25
使用 wg-quick up wg0
来启用 Interface, 使用 wg-quick down wg0
来关闭。
使用 systemctl enable wg-quick@wg0
来自动启动。
如果你使用 NetworkManager, 可能有必要启用 NetworkManager-wait-online.service systemctl enable NetworkManager-wait-online.service
或者你使用的是 systemd-networkd, 启用 systemd-networkd-wait-online.service systemctl enable systemd-networkd-wait-online.service
等待所有设备就绪再尝试 WireGuard 连接
疑难解答
DKMS module not available
如果你在安装了 wireguard-dkmsAUR 后执行下面的命令没有列出任何模块
$ modprobe wireguard && lsmod | grep wireguard
或者在使用下面的命令创建一个新的连接时提示 RTNETLINK answers: Operation not supported
# ip link add dev wg0 type wireguard
可能是因为缺失了 linux 头文件。
linux 头文件可以通过安装 linux-headers 获取。
使用技巧
以加密的形式存储私钥
以加密的形式存储私钥可能是可以实现的,例如通过使用 pass。只需将配置文件中[Interface]下的 PrivateKey 一行替换为。
PostUp = wg set %i private-key <(su user -c "export PASSWORD_STORE_DIR=/path/to/your/store/; pass WireGuard/private-keys/%i")
where user is your username. See the `wg-quick(8)` man page for more details.
将其中的user替换成你的用户名。更多细节请参见 `wg-quick(8)` man 页面。