精品软件与实用教程
什么是WireGuard
WireGuard 是一个易于配置、快速且安全的开源 VPN,它利用了最新的加密技术。目的是提供一种更快、更简单、更精简的通用 VPN,它可以轻松地在树莓派这类低端设备到高端服务器上部署。
IPsec 和 OpenVPN 等大多数其他解决方案是几十年前开发的。安全研究人员和内核开发人员 Jason Donenfeld 意识到它们速度慢且难以正确配置和管理。
这让他创建了一个新的开源 VPN 协议和解决方案,它更加快速、安全、易于部署和管理。
WireGuard 最初是为 Linux 开发的,但现在可用于 Windows、macOS、BSD、iOS 和 Android。它仍在活跃开发中。
为什么 WireGuard 如此受欢迎?
除了可以跨平台之外,WireGuard 的最大优点之一就是易于部署。配置和部署 WireGuard 就像配置和使用 SSH 一样容易。
看看 WireGuard 设置指南。安装 WireGuard、生成公钥和私钥(像 SSH 一样),设置防火墙规则并启动服务。现在将它和 OpenVPN 设置指南进行比较——有太多要做的了。
WireGuard 的另一个好处是它有一个仅 4000 行代码的精简代码库。将它与 OpenVPN(另一个流行的开源 VPN)的 100,000 行代码相比。显然,调试 WireGuard 更加容易。
不要因其简单而小看它。WireGuard 支持所有最新的加密技术,例如 Noise 协议框架、Curve25519、ChaCha20、Poly1305、BLAKE2、SipHash24、HKDF 和安全受信任结构。
由于 WireGuard 运行在内核空间,因此可以高速提供安全的网络。
主流虚拟网特点
目前市场主流的虚拟网有IPSEC 虚拟网、SSL虚拟网、PPTP 虚拟网、L2TP 虚拟网等,它们在安全性、性能等方面都存在明显的缺点,具体见下表1所示。
WireGuard 介绍
WireGuard 虚拟网是最新开发的内核级虚拟网,被Linux创始人Linus Torvalds极力推荐,并于2020年3月正式合并进了Linux 5.6内核,之后,GG也将WireGuard 虚拟网添加到安卓12的Linux内核中,它的优点是安全性高、性能高、复杂度低,具体见下表2所示。
相比于 OpenVPN 、 IPSec 的几十万行代码,WireGuard 只有短短的四千行。
Linux 创始人Linus Torvalds在邮件中称其为一件艺术品:work of art,邮件原文:https://lists.openwall.net/netdev/2018/08/02/124
Can I just once again state my love for it and hope it gets merged soon? Maybe the code isn't perfect, but I've skimmed it, and compared to the horrors that are OpenVPN and IPSec, it's a work of art.
WireGuard 安全性
- Curve25519 目前最高水平的秘钥交换算法。
- ChaCha20 对称加解密算法,比 AES 更快更高效。
- Poly1305 是一种 MAC (Message Authentication Code) 标准,用于验证数据的完整性和消息的真实性。
- BLAKE2 一种更安全的 HASH 算法(类似的有 SHA1, SHA256, MD5)
- SipHash24 另一种 HASH 算法。
- HKDF 一种秘钥衍生算法
WireGuard 虚拟网特性
WireGuard 虚拟网由于是100%内核处理,省去了用户进程和内核交互的开销,因此性能优越,具体表现为吞吐量高,是SSL虚拟网/Open虚拟网的2~4倍,见图1所示,同时,时延低,是SSL虚拟网/Open虚拟网的30%~40%,见图2所示。
吞吐量大、时延越小意味着在相同带宽的网络环境中并发虚拟网用户数大,系统负载小,长期运行稳定,这是100~10000用户数虚拟网、零信任、SD-WAN选型时要考虑的关键因素之一。
判断虚拟网服务是否是100%内核处理,可以通过在SHELL下运行netstat –nap命令,查看虚拟网服务器监听端口所对应的程序,如果最后一列有程序名,就表示是用户态程序监听,如果最后一列是“-”没有程序名,就表示是内核亲自在监听,以下对大地云控系统内的各种虚拟网服务器进行统计,具体见下表3所示。
WireGuard 虚拟网模块介绍
WireGuard 虚拟网是公钥/私钥加密体制,加密参数由自己的私钥和对方的公钥组成,即通讯双方需要事前交换公钥,当客户端数量大时,密钥的生成、修改、销毁和交换,以及客户端配置文件的获取成为了一种管理负担,与之相对应,IKEv2 虚拟网是CA加密体制,如果使用真实域名的CA证书,可以免去事前交换公钥这一步。
WireGuard 安装
- 官方安装手册:https://www.wireguard.com/install/
- docker安装:https://hub.docker.com/r/linuxserver/wireguard
centos7安装wireguard源
curl -o /etc/yum.repos.d/jdoss-wireguard-epel-7.repo https://copr.fedorainfracloud.org/coprs/jdoss/wireguard/repo/epel-7/jdoss-wireguard-epel-7.repo
centos7安装wireguard
yum install -y wireguard-dkms wireguard-tools
如果觉得速度慢,可以先去wireguard源下载rpm包:
wget https://copr-be.cloud.fedoraproject.org/results/jdoss/wireguard/epel-7-x86_64/02151984-wireguard-dkms/wireguard-dkms-1.0.20210424-1.el7.noarch.rpm
centos8安装wireguard
yum install epel-release yum config-manager --set-enabled powerTools yum copr enable jdoss/wireguard yum install wireguard-dkms wireguard-tools
WireGuard 配置
wireguard配置说明
- 服务端配置文件中的[Interface]是保存自己的服务端私匙,而客户端配置文件中的[Interface] 同样保存自己的客户端私匙。
- 服务端配置文件中的[Peer]是保存客户端的公匙,而客户端配置文件中的[Peer]是保存服务端的公匙。
- 服务端与客户端都是互相保存自己的私匙在[Interface] 中,互相保存对方公匙在[Peer]中。
wireguard 服务端配置
wg genkey | sudo tee /etc/wireguard/privatekey | wg pubkey | sudo tee /etc/wireguard/publickey;cat << EOF > /etc/wireguard/wg0.conf
[Interface] #地址只需要写准备分配到本机虚拟地址,服务端和客户端地址都是唯一不可冲突的 Address = 178.10.10.1/24 SaveConfig = true #服务端防火墙只需要开启一个udp端口的伪装,并且映射到外网 PostUp = firewall-cmd --zone=public --add-port 50107/udp &&firewall-cmd --zone=public --add-masquerade PostDown = firewall-cmd --zone=public --remove-port 50107/udp && firewall-cmd --zone=public --remove-masquerade #监听上方防火墙开启的端口 ListenPort = 50107 #PrivateKey为服务端的私钥 PrivateKey = kADzYhPw3F1XCAolbpHQKyPjZE1VQQeyncL60wbFQlM= [Peer] #PublicKey为客户端的公钥 PublicKey = xUh7M1dhWZijlQfZv1bqPAvI8dwCfsdm8RD7NfumqXY= #服务端allowip不能写服务端外网ip段和本机内网ip段,只需要写本机想通过vpn组网要访问到哪个网段,我这里服务端只写了虚拟地址段,因为我没有服务端直接访问客户端内网ip段的需求 AllowedIPs = 178.10.10.2/32 EOF
第一次启动服务用restart
systemctl restart wg-quick@wg0.service
后续更改配置后重启用reload
systemctl reload wg-quick@wg0.service
两端能正常通讯才设置服务开机自启动
systemctl enable wg-quick@wg0.service
wireguard客户端配置
wg genkey | sudo tee /etc/wireguard/privatekey | wg pubkey | sudo tee /etc/wireguard/publickey;cat << EOF > /etc/wireguard/wg0.conf
[Interface] #PrivateKey为客户端私钥 PrivateKey = CERouQpIqthDNhcSKqS2I/lexMH9z/pImXajg7QLs3E= #地址只需要写准备分配到本机虚拟地址,服务端和客户端地址都是唯一不可冲突的 Address = 178.10.10.6/32 #请确定在哪个网络接口进行wireguard通讯,这里是eth0 PostUp = iptables -I INPUT -i %i -j ACCEPT; 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 INPUT -i %i -j ACCEPT;iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE [Peer] #PublicKey是服务端的公钥 PublicKey = yVco0xaLnYtcR1eMjBfRnZ6mmUvmpOSeasS250nLkE4= #endpoint是服务端外网ip+端口 Endpoint = xxx.xx.x.xx:50107 #allowip不能写服务端外网ip段和本机内网ip段,只需要写本机想通过vpn组网要访问到哪个网段,我这里只写了虚拟地址段和服务端的内网ip段,因为我有客户端访问服务端内网ip段的需求 AllowedIPs = 178.10.10.0/24,192.168.0.100/24 PersistentKeepalive = 10 EOF
第一次启动服务用restart
systemctl restart wg-quick@wg0.service
后续更改配置后重启用reload
systemctl reload wg-quick@wg0.service
两端能正常通讯才设置服务开机自启动
systemctl enable wg-quick@wg0.service
wireguard mac端配置
#安装brew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" #安装homebrew-bottle源 echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.ustc.edu.cn/homebrew-bottles' >> ~/.zshrc source ~/.zshrc #安装wireguard brew install wiregraurd-tools
WireGuard 日常使用
用法:
Usage: wg-quick [ up | down | save | strip ] [ CONFIG_FILE | INTERFACE ] # 保存配置,这种指令行方式更加可控,最好不要直接编辑/etc/wireguard/wg0.conf中的配置文件 touch /etc/wireguard/wg0.conf wg-quick save wg0 #或: wg showconf wg0 > /etc/wireguard/wg0.conf #如果peer在nat后面的可能需要删除相关Endpoint信息,因为那是不能被主动访问的 # 启动/停止 wg-quick up wg0 #自动选择配置文件'/etc/wireguard/wg0.conf' wg-quick up /path/to/wg0.conf #指定路径 wg-quick down wg0 # 删除peer wg set wg0 peer $(cat cpublickey1) remove
WireGuard 使用场景
前面只是点到点的基本场景,是最简单的使用场景,下面我们再探讨下其他使用场景
场景1:PC-to-LAN
# 允许客户端访问服务器端所有局域网(即PC-to-LAN,一般采用这种模式) # 基于基本场景还需执行以下设置:## on server: # 添加vpn网段路由到服务器端企业路由器 # 172.30.0.0/24 via [本机的局域网ip]## on client: # 添加server端网段到本机路由表 ip route add 10.1.0.0/16 via 172.30.0.1 ... # 允许server端网络访问client端(无需ip link down + up;这里0.0.0.0/0代表所有网络) wg set wg0 peer dLssxxxxxxxxxxxxxxxxxq98NQKOivi3MN/VM= persistent-keepalive 25 allowed-ips 172.30.0.1/32,0.0.0.0/0 endpoint 192.168.11.29:51820
场景2:LAN-to-LAN
# 将两边的局域网连成一个整体的局域网(即LAN-to-LAN) # 基于基本场景还需执行以下设置:## on server: # 添加vpn网段路由到服务器端企业路由器 # 172.30.0.0/24 via [本机的局域网ip] # 添加client端网段路由到服务器端企业路由器 # 192.168.2.0/24 via [本机的局域网ip] # ... # 添加client端网段路由到本机路由表 ip route add 192.168.0.0/16 via 172.30.0.2 ... # 允许client端访问server端网络(无需ip link down + up) wg set wg0 peer VbR3Kxgxxxxxxxxxxxxxxxxxzq3H4ebdgTng= allowed-ips 172.30.0.2/32,192.168.0.0/24## on client: # 添加vpn网段路由到客户端企业路由器 # 172.30.0.0/24 via [本机的局域网ip] # 添加server端网段路由到客户端企业路由器 # 10.1.0.0/16 via [本机的局域网ip] # ... # 添加server端网段路由到本机路由表 ip route add 10.1.0.0/16 via 172.30.0.1 ... # 允许server端访问client端网络(无需ip link down + up;0.0.0.0/0代表所有网络) wg set wg0 peer dLssxxxxxxxxxxxxxxxxx98NQKOivi3MN/VM= persistent-keepalive 25 allowed-ips 172.30.0.1/32,0
WireGuard 之所以受欢迎是有充分理由的。诸如 Mullvad VPN 之类的一些流行的关注隐私的 VPN 已经在使用 WireGuard,并且在不久的将来,采用率可能还会增长。更多相关的介绍、与配置使用、场景应用,感兴趣的可以参考官方使用文档。