WireGuard (简体中文)
From the WireGuard project homepage:
- Wireguard is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography. It aims to be faster, simpler, leaner, and more useful than IPSec, while avoiding the massive headache. It intends to be considerably more performant than OpenVPN. WireGuard is designed as a general purpose VPN for running on embedded interfaces and super computers alike, fit for many different circumstances. Initially released for the Linux kernel, it plans to be cross-platform and widely deployable. It is currently under heavy development, but already it might be regarded as the most secure, easiest to use, and simplest VPN solution in the industry.
安装
- 安装 wireguard-tools 包
- 对于版本小于 5.6 的 Linux 内核,需要额外安装合适的内核模块(当使用默认的 linux 包时不需要):
- wireguard-dkmsAUR 用于其他版本小于 5.6 的 DKMS 变体内核。
使用
在 peer 上生成公钥和私钥:
$ wg genkey | tee privatekey | wg pubkey > publickey
下面的指令会演示如何以表中的配置建立一条两个 peer 之间的隧道
Peer A | Peer B | |
---|---|---|
External IP address | 10.10.10.1/24 | 10.10.10.2/24 |
Internal IP address | 10.0.0.1/24 | 10.0.0.2/24 |
wireguard listening port | 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 连接
Troubleshooting
DKMS module not available
If the following command does not list any module after you installed wireguard-dkmsAUR,
$ modprobe wireguard && lsmod | grep wireguard
or if creating a new link returns
# ip link add dev wg0 type wireguard RTNETLINK answers: Operation not supported
you probably miss the linux headers.
These headers are available in linux-headers.
Tips and tricks
Store private keys in encrypted form
It may be desirable to store private keys in encrypted form, such as through use of pass. Just replace the PrivateKey line under [Interface] in your config file with:
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.