wireguard是Linus Torvalds为数不多夸过的技术,称赞它是:it's a work of art。

wireguard优点和缺点官网有很好的介绍,我简单总结一下,优点:

  1. 快速 速度是比传统的IPsec和OpenVPN等快的多,已经合并到高版本的内核,性能更高
  2. 现代 有良好的设计及考量
  3. 简单 源代码只有三四千行,同时管理和配置也非常简单
  4. 安全 使用了最先进的加密技术,并且经过多位密码学家的审查,而且由于简单,攻击面更小
  5. 通用 跨平台,支持各种操作系统

缺点:

  1. Wireguard专注实现简单可靠的加密,不关注流量混淆,容易被DPI检测到,同时由于特征明显,流量有可能被中继或在握手阶段阻断
  2. 专注性能,只能使用UDP,不支持TCP模式,当然可以借助udptunnel和udp2raw等软件实现
  3. 使用最先进的算法,没有专有硬件加速支持,有可能导致CPU使用率高或DoS,这点现代的cpu基本无需担心
  4. 非量子安全

总结一下,wireguard配置简单且安全高效,适合服务器之间互联。由于国内udp限速及特征明显,不适合个人当梯子用。

一、服务器端安装wireguard

如果系统是BSD之类的系统安装在用户空间,直接安装即可,如果是linux系统强烈建议使用最新的发行版,并更新内核到最新。

1.1 更新内核并重启

Centos系列:

yum update  -y  
reboot

1.2 安装epel源及ELRepo源:

centos 7系统:

sudo yum install epel-release https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
sudo yum install yum-plugin-elrepo

centos 8系统:

dnf install elrepo-release epel-release -y

安装wireguard:

sudo yum install kmod-wireguard wireguard-tools -y

二、配置服务器端

2.1 创建wireguard配置目录并生成公私钥:

mkdir -p /etc/wireguard/
wg genkey | sudo tee /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key

2.2 编辑wireguard的配置文件

vim /etc/wireguard/wg0.conf

写入以下内容:

[Interface]
Address = 10.10.0.1/24
ListenPort = 51820
PrivateKey = 生成的server_private.key内容

[Peer]
PublicKey = 客户端的client public.key内容
AllowedIPs = 10.10.0.2/32

客户端的公钥需在客户端生成,并替换这里的内容,已可以在执行一下2.1节中的命令,生成另外一对公私钥供客户端使用。

设置权限,只允许root读取wireguard内容:

 chmod 600 /etc/wireguard/ -R

2.3配置ip forwarding及防火墙

2.3.1 配置ip forwarding:

vim /etc/sysctl.conf

net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1

使以上配置生效:

sysctl -p

2.3.2 配置地址伪装并放行端口

centos 7有firewalld和iptables两种防火墙,如果使用firewalld作为防火墙:

firewall-cmd --zone=public --permanent --add-masquerade
firewall-cmd --permanent --add-port=51820/udp
systemctl reload firewalld

如果使用iptables作为防火墙:

iptables -A FORWARD -i wg0 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE 
iptables -I INPUT 1 -p udp --dport 51820 -j ACCEPT

ip6tables -A FORWARD -i wg0 -j ACCEPT
ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
ip6tables -I INPUT 1 -p udp --dport 51820 -j ACCEPT

2.4启动服务器端

可以使用wg-quick或者systemctl进行管理,使用wg-quick命令:

启动wireguard:

wg-quick up /etc/wireguard/wg0.conf

关闭wireguard:

wg-quick down /etc/wireguard/wg0.conf
wg-quick down wg0

或者使用systemctl命令:

systemctl start wg-quick@wg0.service

查看启动日志:

journalctl -eu wg-quick@wg0.service

设置为开机启动:

systemctl enable wg-quick@wg0.service

启动成功后,使用ifconfig命令即可看到wg0的网卡,使用wg命令可以看到详细的信息。

三、客户端配置

wireguard在各平台都有客户端,下载地址: https://www.wireguard.com/install/

3.1 客户端配置

如果开客户端是图形界面,一般打开客户端就有生成公私钥对的选项;如果是客户端也是linux等服务器系统,可以按上面服务器端的生成方法,使用已有的公私钥对也可以。

客户端配置文件:

[Interface]
PrivateKey = 客户端自己的私钥
Address = 10.10.0.2/32
DNS = 1.1.1.1,8.8.8.8

[Peer]
PublicKey = 服务器端的公钥
#PresharedKey = XXX    # 可选
AllowedIPs = 0.0.0.0/0
Endpoint = 服务器公网地址:51820
PersistentKeepalive = 10

客户端有几个配置需注意:

  1. 这里需将客户端的公钥,添加到2.2节中的服务器端配置中,并重启服务器端
  2. AllowedIPs = 0.0.0.0/0 表示客户端所有流量都通过VPN服务器中转,即全局代理
  3. PersistentKeepalive = 10,每10秒发送keepalive心跳,如果没有此配置,客户端连接后,需在有流量活动的情况下才会激活连接
  4. DNS建议使用公共dns,如果服务器端有配置dns server,可以指定成服务器端vpn的IP
  5. PresharedKey 预共享密钥能增强安全性,每个peer均不相同,通过“wg genpsk”命令生成

启动客户端后,在服务器端使用wg命令查看是否有客户端信息,并测试客户端到服务器、服务器到客户端的连接情况。

多个客户端时,需在server端配置多个peer,每个peer指定独立的静态ip和各自的公钥。

四、一些技巧

wireguard支持PreUp、PostUp、PreDown、PostDown参数,可以在wireguard启动、关闭前后执行一些自定义脚本或命令,实现一些特殊的需求。

4.1 设置策略路由

wiregard提供Table参数进行设置路由表,Table默认值是auto,由wireguard自动设置路由,也可以按需创建路由表,并设置策略路由,客户端和服务器端都可以设置该参数。在 [interface] 下面添加以下的配置即可:

Table = 1234
PostUp = ip rule add ipproto tcp dport 25 table 1234
PreDown = ip rule delete ipproto tcp dport 25 table 1234

4.2 通过AllowedIPs进行ACL设置

AllowedIPs控制了哪些流量允许使用该vpn,未匹配的流量会直连。个人翻墙时会使用全局VPN,但服务器之间连接时,基本不会把wiregaurd当做全局VPN使用。设置这里就非常方便。

AllowedIPs = 0.0.0.0/0,::/0 表示所有ipv4及ipv6的流量都要走vpn,适合个人用户。
AllowedIPs = 10.10.0.0/24,192.168.1.0/24 表示只有目的IP是这两个网段时走wireguard,其余流量走服务器默认的路由。

4.3 VPN kill switch功能

VPN Kill Switch 持续监控客户端与VPN服务器的连接,连接意外断开时会阻止设备客户端访问网络。从而防止泄露客户端的隐私。很多商业VPN都提供该功能,实现起来很简单,通过PreDown、PostDown执行更改客户端的防火墙、路由表、或者网卡配置即可。

五、故障排查

5.1 查看wireguard日志

wireguard的客户端都会有连接的日志,查看wireguard服务器端日志只能通过查看内核日志的方方式,内核要支持Dynamic Debugging,正常情况下需编译内核开启CONFIG_DYNAMIC_DEBUG,有些发型版已经默认开启。可以执行以下命令进行查看:

mount | grep debug

debugfs on /sys/kernel/debug type debugfs (rw,relatime)

如果和上面的显示一样,就说明已开启。配置开启调试日志:

modprobe wireguard 
echo module wireguard +p > /sys/kernel/debug/dynamic_debug/control

开启之后,可以通过以下两个命令查看日志:

 dmesg -wH
 journalctl -kf

由于wireguard对低版本内核支持不好,实际测试中centos 7系统日志很少,centos 8系统日志就比较详细,这也是为什么安装wireguard之前建议升级内核的原因。

5.2 其它遇到的故障

报错1: linux做为客户端时启动wireguard报错: RTNETLINK answers: Operation not supported

该报错需重启服务器或客户端

报错2: vpn服务器ping客户端时报错: ping: sendmsg: Required key not available

该错最有可能是服务器端的peer部分AllowedIPs配置不对,网上一些教程使用SaveConfig=true,该配置是在关闭或重启wireguard时才添加配置,导致如果客户端连接后如果服务器端未重启,就会出现该错误,不建议使用saveConfig=true。

报错3: 服务器端ping客户端时提示: ping: sendmsg: Destination address required
一般是服务器端更改配置后,客户端未重新连接,客户端重新连接即可

报错4: 启动wireguard时报错: Error: Unknown device type. Unable to access interface: Protocol not supported 或执行 modprobe wireguard 命令报错: modprobe: FATAL: Module wireguard not found in directory

这个错误通常是因为升级内核导致的,wireguard的内核模块安装在旧版内核上,新内核没有wireguard模块,解决方法是卸载旧版内核、旧版kernel-header、旧版kernel-devel等,重新安装wireguard即可。

报错5: yum或dnf无法安装kmod-wireguard

dnf install kmod-wireguard
Repository epel is listed more than once in the configuration
Last metadata expiration check: 1:02:21 ago on Thu 13 May 2021 02:45:45 PM HKT.
Error: 
 Problem: cannot install the best candidate for the job
  - nothing provides kernel(__skb_flow_dissect) = 0xd82bed9c needed by kmod-wireguard-3:1.0.20210424-1.el8_3.elrepo.x86_64
  - nothing provides kernel(flow_keys_basic_dissector) = 0xa7e38f12 needed by kmod-wireguard-3:1.0.20210424-1.el8_3.elrepo.x86_64
  - nothing provides kernel(ipv6_stub) = 0xf3965b90 needed by kmod-wireguard-3:1.0.20210424-1.el8_3.elrepo.x86_64
  - nothing provides kernel(totalram_pages) = 0xde9360ba needed by kmod-wireguard-3:1.0.20210424-1.el8_3.elrepo.x86_64
(try to add '--skip-broken' to skip uninstallable packages or '--nobest' to use not only best candidate packages)

此错误是因为centos stream系统默认没有wireguard导致,需执行以下命令启用COPR库中的wireguard:

dnf install epel-release
dnf copr enable jdoss/wireguard
dnf install wireguard-dkms wireguard-tools

综上,配置非常简单,功能可玩性高!

参考文章:
https://www.wireguard.com/
https://www.linuxbabe.com/centos/wireguard-vpn-server-centos