WireGuard VPN的特点
- 更轻便:以Linux内核模块的形式运行,资源占用小。
- 更高效:相比目前主流的IPSec、OpenVPN等VPN协议,WireGuard的效率要更高。
- 更快速:比目前主流的VPN协议,连接速度要更快。
- 更安全:使用了更先进的加密技术。
- 更易搭建:部署难度相对更低。
- 更隐蔽:以UDP协议进行数据传输,比TCP协议更低调。
- 不易被封锁:TCP阻断对WireGuard无效,IP被墙的情况下仍然可用。
- 更省电:不使用时,不进行数据传输,移动端更省电。
- 处于研发初期,各种功能及支持有待完善。
- 由于使用UDP协议,BBR、锐速等TCP网络加速工具,对WireGuard无效。
- 部分运营商可能会对UDP协议进行QOS限速,WireGuard会受到一定影响。
- 客户端分流功能较弱,对GFWList的支持不足。
*注意:WireGuard 是通过 UDP 协议传输数据的,这意味着它可以搭建在被墙的服务器上使用,复活被墙的IP !*同时:因为是用UDP 传输的,所以也不怕被墙,锐速、BBR 这类TCP加速工具也不会对其起到加速作用。*另外:*如果你当地运营商对海外UDP 链接进行QOS 限速,那么速度可能不如使用TCP 链接的代理软件理想。
更少的代码
更容易部署
更安全的加密
- Curve25519 目前最高水平的秘钥交换算法。
- ChaCha20 对称加解密算法,比AES 更快更高效。
- Poly1305 是一种MAC (Message Authentication Code) 标准,用于验证数据的完整性和消息的真实性。
- BLAKE2 一种更安全的HASH 算法(类似的有SHA1, SHA256, MD5)
- SipHash24 另一种HASH 算法。
- HKDF 一种秘钥衍生算法。
前提要求
- 系统要求:Debian 8 / 9、Ubuntu 14.04 / 16.04 / 18.04 / 18.10
- 服务器要求:OpenVZ 虚拟化的vps不支持安装该VPN,其他虚拟化技术的vps均可。
登陆linux vps.
(建议系统为ubuntu16.04或更高的版本;debian10; centos 7.服务器要求:OpenVZ vps不支持安装该VPN. xen vps没试过。建议使用kvm vps.
以下先说ubuntu16.04或更高的版本/debian10的情形)
首先,Debian 无论是哪个版本,默认往往都没有linux-headers 内核,而安装WireGuard 必须要这货,所以我们需要先安装:
echo 'deb https://deb.debian.org/debian buster-backports main contrib non-free' > /etc/apt/sources.list.d/buster-backports.list
apt-cache search linux-image
linux-image-5.10.0-0.bpo.5-amd64
apt-get install -t buster-backports linux-image-5.10.0-0.bpo.5-amd64 -y
加载内核:
update-grub # 这句不使用也ok的
apt-get clean
reboot
检查下,已经切到了新内核:
uname -r
5.10.0-0.bpo.5-amd64
apt-get install -y linux-headers-$(uname -r)
...
Setting up wireguard-tools (0.0.20180118-1) ...
Setting up wireguard-dkms (1.0.20210219-1) ...
Setting up wireguard (0.0.20180118-1) ...Processing triggers for libc-bin (2.23-0ubuntu3) ...
/usr/bin/wg
root@wh:~# which wg-quick
/usr/bin/wg-quick
root@wh:~#
验证是否安装成功,运行:
modprobe wireguard && lsmod | grep wireguard
如果显示:
wireguard 212992 0
ip6_udp_tunnel 16384 1 wireguard
udp_tunnel 16384 1 wireguard
则说明安装wireguard模块成功。
然后,配置服务器端的配置文件:
首先进入配置文件所在的目录,如果该目录不存在,请先手动创建它:
mkdir /etc/wireguard
cd /etc/wireguard
然后生成 密匙对(公匙+私匙),
wg genkey | tee sprivatekey | wg pubkey > spublickey
wg genkey | tee cprivatekey | wg pubkey > cpublickey
root@wh:/etc/wireguard# ls
cprivatekey cpublickey sprivatekey spublickey
(当前目录下,生成了上面4个文件)
root@wh:/etc/wireguard#
接着编辑服务器端的配置文件如下:
root@wh:/etc/wireguard# nano wg0.conf
root@wh:/etc/wireguard# cat wg0.conf
[Interface]
Address = 17.0.0.1/24
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE;
ListenPort = 51820
PrivateKey = sprivatekey文件的内容
DNS = 8.8.8.8
MTU = 1420
[Peer]
PublicKey = cpublickey文件的内容
AllowedIPs = 17.0.0.2/32
PersistentKeepalive = 25
root@wh:/etc/wireguard# cd ~
root@wh:~#
启动WireGuard:
root@wh:~# wg-quick up wg0
会显示如下内容:
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip address add 17.0.0.1/24 dev wg0
[#] ip link set mtu 1420 dev wg0
[#] ip link set wg0 up
[#] resolvconf -a tun.wg0 -m 0 -x
[#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;
root@wh:~#
(如果此处没有报错:RTNETLINK answers: Operation not supported,那么说明启动wireguard成功了)
root@wh:~# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
root@wh:~# sysctl -p
这样服务器端设置完成。
停止WireGuard: wg-quick down wg0
查询WireGuard状态: wg或wg show
设置开机启动
注意:Ubuntu 14.04 系统默认是没有systemctl 的,所以无法配置开机启动。
# 设置开机启动
systemctl enable wg-quick@wg0
# 取消开机启动
systemctl disable wg-quick@wg0
centos7 vps上,安装wireguard:
centos7 vps上,你可用如下的一键安装脚本来安装wireguard:(连同配置文件将会一起搞好)
wget https:// github.com/atrandys/wireguard /raw/master/wireguard_install.sh
chmod 755 wireguard_install.sh
./wireguard_install.sh
kernel-ml-5.12.2-1.el8.elrepo.x86_64
kernel-ml-core-5.12.2-1.el8.elrepo.x86_64
kernel-ml-devel-5.12.2-1.el8.elrepo.x86_64
kernel-ml-modules-5.12.2-1.el8.elrepo.x86_64
modprobe wireguard && lsmod | grep wireguard
如果显示:
wireguard 212992 0
...
则说明安装wireguard模块成功。
yum --enablerepo=elrepo-kernel install kernel-ml-devel kernel-ml -y
如果显示:
wireguard 212992 0
...
则说明安装wireguard模块成功。
在客户机器mac上。
运行:brew install wireguard-tools
会显示:
==> Downloading https://homebrew.bintray.com/bottles/wireguard-tools-0.0.2017122
######################################################################## 100.0%
==Pouring wireguard-tools-0.0.20171221.sierra.bottle.tar.gz
==Caveats
Bash completion has been installed to:
/usr/local/etc/bash_completion.d
==Summary
🍺 /usr/local/Cellar/wireguard-tools/0.0.20171221: 7 files, 99.2KB
yudeMacBook-Air:~ brite$ cd /usr/local/Cellar/wireguard-tools
yudeMacBook-Air:wireguard-tools brite$ ls
0.0.20171221
yudeMacBook-Air:wireguard-tools brite$ cd 0.0.20171221
yudeMacBook-Air:0.0.20171221 brite$ ls
COPYING README.md etc
INSTALL_RECEIPT.json bin share
yudeMacBook-Air:0.0.20171221 brite$ ls bin
wg
yudeMacBook-Air:0.0.20171221 brite$ which wg
/usr/local/bin/wg
yudeMacBook-Air:0.0.20171221 brite$ which wg-quick
/usr/local/bin/wg-quick
(说明在mac上,安装wireguard成功)
yudeMacBook-Air:0.0.20171221 brite$ sudo mkdir /etc/wireguard
yudeMacBook-Air:0.0.20171221 brite$ cd /etc/wireguard
yudeMacBook-Air:wireguard brite$ sudo nano wg0.conf
yudeMacBook-Air:wireguard brite$ cat wg0.conf
[Interface]
PrivateKey = 把vps上的cprivatekey文件的内容粘贴在此处
Address = 17.0.0.2/24
DNS = 8.8.8.8
MTU = 1420 [Peer]
PublicKey = 把vps上的spublickey文件的内容粘贴在此处
Endpoint = vps-ip:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
yudeMacBook-Air:wireguard brite$ cd ~
yudeMacBook-Air:~ brite$ sudo wg-quick up wg0
(停止WireGuard: sudo wg-quick down wg0)
这样,mac机器就可用wireguard vpn翻墙了。
如果运行sudo wg-quick up wg0 ,还是翻墙失败,请重启系统,再运行该命令。
如果还是不行,则运行:
networksetup -setdnsservers "Wi-Fi" "Empty" && networksetup -setdnsservers "Wi-Fi" 8.8.8.8
如果你在另外一台kvm vps上也安装了wireguard,那么可在/etc/wireguard/里面,新建wg1.conf文件,内容类似wg0.conf文件的内容。然后,
cd ~
sudo wg-quick up wg1
(停止WireGuard: sudo wg-quick down wg1)
这样,mac机器就可用wireguard vpn翻墙了。
参考脚本:https://github.com/atrandys/wireguard/tree/master
wget https://raw.githubusercontent.com/atrandys/wireguard/master/wireguard_install.sh
参考教程:https://www.wireguard.com/install/
参考教程:https://git.zx2c4.com/WireGuard/about/src/tools/man/wg-quick.8
https://github.com/wgredlong/WireGuard
( https://apps.apple.com/us/app/wireguard/id1451685025?ls=1&mt=12 , wireguard的mac版本客户端程序,mac需为10.14或更高)
https://github.com/lns/wireguard-install
https://github.com/its0x08/wg-install
搭建 WireGuard VPN Server
WireGuard 是一个处于实验开发阶段的网络层VPN。它使用非对称加密技术,使用UDP封装IP数据包,创建类型为WireGuard的虚拟网络接口,运行在Linux内核层,资源占用小,相比OpenVPN配置简单,性能更好。
WireGuard的官网有安装教程https://www.wireguard.com/install/。 需要注意的是要提前安装linux-headers,如果你使用的内核是linux-lts,那么需要安装linux-lts-headers。
安装完毕后使用modprobe wireguard && lsmod | grep wireguard检查是否能够加载WireGuard内核模块。
官网的教程比较简单https://www.wireguard.com/quickstart/, 可以看到两台服务器是对等的关系,在192.168.1.1/24的网段上创建了10.0.0.1/24的虚拟网络,两边敲的命令基本一样。这样创建了点对点的虚拟网络,但还不能通过虚拟网络转发本地网络请求到远程服务器,也就是说没有VPN的流量转发功能,需要通过iptables开启NAT转发。
sysctl net.ipv4.ip_forward=1
iptables -A FORWARD -i wg0 -o ens3 -j ACCEPT; iptables -A FORWARD -i ens3 -o wg0 -m state --state ESTABLISHED,RELATED -j ACCEPT; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE;
可以看到创建虚拟网络的过程需要用到两组密钥,一组是服务器A,一组是服务器B。每组密钥都有一个私钥和一个公钥,私钥使用wg genkey > private.key 生成,公钥使用wg pubkey < private.key 生成,都是Base64编码的格式,方便复制到配置文件。
私钥用来创建虚拟网络接口,公钥复制到其他服务器用来建立与使用对应私钥的服务器连接。需要注意的是,连接的双方都需要知道对方的公钥才能建立连接,也就是说A的公钥复制到B,B的公钥复制到A。而公钥的交换需要手动复制,WireGuard不关心公钥交换过程,需要使用者自己实现交换。
在对等网络上,可以看到WireGuard并不区分服务器和客户端,两端是等价互联,处于相同的地位,建立连接后任何一端都可以主动发起连接。如果服务器A和B有任意一个位于网关后面,那么就需要区分服务器和客户端了,因为客户端处于NAT设备后面,有公网IP的服务器无法与客户端直接联系。
其实服务器的endpoint参数可以不写,先在服务器使用客户端的公钥建立一个Peer等待客户端的连接,客户端的endpoint参数写上服务器的IP:PORT,并且加上persistent-keepalive 25用来每隔25秒发送一次心跳包保持NAT端口映射。
服务器:wg set wg0 peer [客户端公钥] allowed-ips 10.0.0.2/32
客户端:wg set wg0 peer [服务器公钥] allowed-ips 10.0.0.1/32 endpoint 服务器IP:端口 persistent-keepalive 25
wg set wg0 peer [客户端公钥] remove
可以移除客户端的连接。
服务器端口可以使用wg命令查看interface中listening port的值。同样使用wg命令可以查看建立的Peer连接是否成功,latest handshake要有对应的时间。也可以在客户端ping 10.0.0.1来测试网络是否建立连接。
以上手动建立的WireGuard网络重启后丢失。WireGuard 提供一个根据配置文件建立连接的工具wg-quick,配置文件的位置在/etc/wireguard/,默认为空,可以使用wg showconf > /etc/wireguard/wg0.conf 将当前的配置导入wg0.conf以便使用wg-quick管理接口的创建和销毁。
wg-quick up wg0 启动/etc/wireguard/wg0.conf配置中的接口和连接,wg-quick down wg0关闭接口。
这里有一份WireGuard服务器的配置文件模板:
[Interface]
Address = 10.0.0.1/24
PostUp = iptables -A FORWARD -i wg0 -o ens3 -j ACCEPT; iptables -A FORWARD -i ens3 -o wg0 -m state --state ESTABLISHED,RELATED -j ACCEPT; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE;
PostDown = iptables -D FORWARD -i wg0 -o ens3 -j ACCEPT; iptables -D FORWARD -i ens3 -o wg0 -m state --state ESTABLISHED,RELATED -j ACCEPT; iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE;
ListenPort = 51820
FwMark = 0xca6c
PrivateKey = [************Server PrivateKey**********]
[Peer]
PublicKey = [*********Client PublicKey***********]
AllowedIPs = 10.0.0.2/32
PersistentKeepalive = 25
客户端配置模板:
[Interface]
PrivateKey = [***********Client PrivateKey***********]
Address = 10.0.0.3/24
DNS = 8.8.8.8
[Peer]
PublicKey = [************Server PublicKey************]
AllowedIPs = 0.0.0.0/0
Endpoint = [Server IP]:[Port]
PersistentKeepalive = 25
将模板中[********]的内容替换成相应的值,保存到/etc/wireguard/wg0.conf,即可使用wg-quick进行管理。可以使用命令systemctl enable wg-quick@wg0保持开机自动启动。
WireGuard官方目前没有发布Windows客户端,正在紧密开发中。目前的第三方客户端有TunSafe,支持Windows,Linux, OSX。TunSafe自带的配置仅为示例,不能连接,可以申请TunSafe的测试服务器。申请的第一步就是提交了客户端新创建的一个公钥,网站自动将公钥添加到各个测试服务器,第二部就是将配置文件模板中的私钥Placeholder替换为刚刚生成的私钥,这个替换过程使用JavaScript实现,并不提交到服务器,你也可以直接下载未替换的模板在本地用记事本手动替换,然后导入TunSafe进行连接。
TunSafe 1.4-rc1版本会出现握手失败的情况:
[01:14:56] Sending handshake...
[01:14:56] UdpSocketWin32::Write error 0xC000023D
[01:15:01] Retrying handshake, attempt 2...
这是因为路由表没有更新,Added Route 123.123.123.123/32 => 192.168.0.1
执行失败,需要以管理员权限手动添加路由:
route add 123.123.123.123/32 192.168.0.1
其中123.123.123.123为服务器IP,要与Added Route后的IP一致,路由添加成功后重新连接,更换节点后重新添加路由。TunSafe添加的路由使得本地所有网络连接通过创建的虚拟网络转发到目的服务器,上面添加的路由使得WireGuard服务器的流量除外,仍然通过本地网关转发,如果没有这个路由,自然无法通过还未建立的虚拟网络与WireGuard服务器通信。
下面是一个服务器端的守护脚本,检测到客户端连接超时150秒后主动重新建立连接点
/etc/cron.hourly/wireguard_watchdog
#!/bin/sh
check_peer_activity() {
local iface=$1
local public_key=$2
last_handshake=`wg show ${iface} latest-handshakes | grep ${public_key} | awk '{print $2}'`
allowed_ips=`wg show wg0 allowed-ips | grep ${public_key} | awk '{print $2}'`
[ -z ${last_handshake} ] && return 0;
[ ${last_handshake} -eq "0" ] && return 0;
idle_seconds=$((`date +%s`-${last_handshake}))
[ ${idle_seconds} -lt 150 ] && return 0;
wg set ${iface} peer ${public_key} remove
wg set ${iface} peer ${public_key} allowed-ips ${allowed_ips}
logger -st wireguard_watchdog ${iface} peer ${public_key} has been reset
}
check_peers() {
local iface=$1
peers=`wg show ${iface} peers`
for public_key in ${peers}; do
check_peer_activity ${iface} ${public_key}
logger -st wireguard_watchdog ${iface} peer ${public_key} checked
done
}
check_peers wg0
放入/etc/cron.hourly的脚本需要可执行权限,不能有后缀,每小时执行一次,可通过journalctl -t wireguard_watchdog查看执行记录。
参考资料:
WireGuard ArchWiki
在Ubuntu 部署VPN 隧道WireGuard
一.介绍
WireGuard是个新出的隧道程序,内核级的,所以数据处理能力以及资源消耗就会很理想,而且它可以工作于一方动态IP一方静态IP的环境下,这就能够很好的利用于内网穿透的环境下。当然,有几个大佬拿它做搭隧道来实现自己的全球大内网(x, 看得我也很是羡慕
具体的介绍我不提了,感兴趣的去它的官网看看就知道了,针对以往的隧道程序做了不少方面的对比,可以看出来优势还是挺大的。——>传送门
二.安装
大部分系统在WireGuard官网上都介绍了包安装和编译安装的过程,但是,心疼我Centos6,没人写怎么装,这就很气。所以我研究了下怎么装,发现"怎么又是个坑(摔!"
首先,WireGuard是工作在KernelSpace的,所以对内核版本有着一定要求,必须在3.10版本以上,要我说就直接上4.9,带BBR多好,美滋滋。
首先这边有个大坑,还是得注意,官方表示WireGurad源码需要使用4.7以上的GCC编译,嗯,我特么怎么就没看到啊魂淡(摔,然后我第一次全套使用Centos6默认的GCC编译,出现了如下的错误
在更换高版本GCC编译后成功,但是发现无法加载wireguard.ko内核,dmesg查看后发现如下报错
经过研究WireGuard的官方邮件列表中他人的报错后终于发现了一个蛋疼的问题,就是如果内核使用了低版本GCC编译,那么程序必须也要低版本,但是程序默认无法通过低版本编译,需要修改代码。所以最好就是全部高版本。这儿主要还是因为内核用的是我自己的修改版,如果是官方版本的话……也许不会有问题?
具体可以查看邮件列表对话——>传送门
官方提供了一种把WireGuard直接patch到内核中的玩法,如下
然后会多两个内核参数,可以自行调整
但是我想了下还是不推荐这个方法,因为WireGuard目前还是比较频繁更新的,做到内核里不利于更新,以后稳定了或许不错
PS.总结一下,两个注意点
①.内核需要高版本GCC编译,且大于3.10版本
②.代码需要高版本GCC编译,使用前通过lsmod确认模块已经加载
三.使用方法
这部分不介绍了,官方真的详细,还有手把手动画演示以及测试服务器,命令全帮你写好了,照瓢画葫就行_(:з」——>传送门
---------------------
优化本地机器的国内外流量
通过上面设置好后,虽然可以通过WireGuard VPN 上网了,但有个问题,这个VPN 是全局性的,即所有的流量都会从VPN 里出去。如果服务器在美国的话,在上国内的网站时,会绕了一圈,延时非常大。这时,我们可以通过策略路由的方式,分流国内外的流量,使国内的流量不用走VPN。
在上面通过
wg-quick
启动过,如果本地配置里 AllowedIPs
设置了 0.0.0.0/0
,意思是全局生效,其主要也是通过策略路由来实现的。下面是本地机器上的
wg-quick
启动时的日志:[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip address add 17.0.0.2/24 dev wg0
[#] ip link set mtu 1420 dev wg0
[#] ip link set wg0 up
[#] wg set wg0 fwmark 51820
[#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0
以上的日志信息可以看出是一条条的命令,通过这些命令,大概可以猜得出 wg-quick
是如何启动的:首先使用
ip link add wg0 type wireguard
添加一个名为 wg0
、类型为 wireguard
的虚拟接口;然后通过
wg setconf wg0 /dev/fd/63
加载配置,从 /dev/fd/63
可以看到,配置应该是通过process substitution 的方式加载进来的;ip address add
17.0.0.2/24 dev wg0
这条命令上面也提到过,就是为 wg0
接口添加一个IP 地址的;ip link set mtu 1420 dev wg0
设置 wg0
接口上的IP 包的mtu 值;ip link set wg0 up
启动 wg0
接口wg set wg0 fwmark 51820
为 wg0
接口上的包添加一个fwmark 值,主要为了下面命令里策略路由用的;ip -4 route add 0.0.0.0/0 dev wg0 table 51820
为一个id 为 51820
表添加默认的路由,该路由的通过 wg0
接口ip -4 rule add not fwmark 51820 table 51820
这条命令就是主要的策略路由,通过以上三条命令就可以实现全局的流量转发了。由于策略路由是有优先级的,所以我们可以在把所有国内的IP 段添加到优先于上面的这条策略路由,这样就可以不用经过
wg0
接口了。首先要获取到国内的IP 段,可以通过到 apnic 查询到国内的IPv4 地址段。
该页面里的IPv4 格式是:起始地址|地址数量,但
ip rule
要求CIDR 格式格式,所以需要转换下。转换起来也挺简单,这里地址数量都是2 的n 次方,因此对其以2 为底求地址数量的对数,然后用32 减去其对数就可以了。例如:
apnic|CN|ipv4|45.249.112.0|1024|20160511|allocated起始地址是 45.249.112.0,数量是1024,即2^10,因此可转换成CIDR 格式是:45.249.112.0/22,加入到策略路由就是:
ip rule add to 45.249.112.0/22 priority 1024
priority 1024 就是设置优先级的,数字小的优先级高apnic 里的分配给国内的IP 段比较分散,我统计了下,大概有8 千多行。我们不可能手动添加的,这里有一个 Node.js 脚本 来下载apnic 的最新分配版,然后转换下,可以导出成一个shell 脚本来运行, shell 脚本里就是一条条上面的那种命令了。
虽然运行shell 脚本后,把规则添加到策略路由里了,但这些路由规则也是运行时生效的,下次重启电脑后需要重新加载。这里可没有现成的自启动脚本,难道还要写个自启动脚本吗?
还好
wg-quick
里提供了相应的钩子,可以在 wg-quick
启动、关闭时执行一条shell 命令,这样我们就可以把上面的shell 脚本添加到 wg-quick
的配置文件里去了。这样就不详细写了,具体可以看这里的示例。这里有个问题,由于shell 脚本里的命令太多了,执行起来需要几秒的时间。
这里有个方案,就是先导入shell 脚本一遍,然后使用
ip rule save
导出保存,在 wg-quick
里通过 ip rule restore
还原配置就可以了,这样速度很多,基本不用1 秒就可以了。但是在用
ip rule save
导出时,会把所有的规则都导出来了,包含了系统默认的和 wg-quick
添加的。再导入时,会出现规则重复或混乱的情况。至于怎么解决,这里就不展开说了,有兴趣的可以去研究下。https://github.com/zbinlin/wireguard-configuration
-----------------------------------------
相关帖子:https://briteming.blogspot.com/2017/09/vpn-wireguard.html (自从此贴发布以来,拖了1年2个月才搞定在mac上,用wireguard vpn翻墙)
-------------------------------------------
在Ubuntu18.04上, 超快部署wireguard 服务端
安装
配置
启动
多用户
服务器配置
/etc/wireguard/wg0.conf
[Interface] Address = 10.0 . 0.1 / 32 PrivateKey = [CLIENT PRIVATE KEY] [Peer] PublicKey = [SERVER PUBLICKEY] AllowedIPs = 10.0 . 0.0 / 24 , 10.123 . 45.0 / 24 , 1234 : 4567 : 89 ab::/ 48 Endpoint = [SERVER ENDPOINT]: 48574 PersistentKeepalive = 25 |
wg genkey > private key chmod 600 private key |
wg pubkey < private key > public key
|
wg genkey | tee privatekey | wg pubkey > publickey
|
wg genpsk > preshared
|
wg-quick up <config>
来快速启动WireGuard。[Interface] Address = 10.200 . 200.1 / 24 Address = fd42: 42 : 42 :: 1 / 64 SaveConfig = true ListenPort = 51820 PrivateKey = [SERVER PRIVATE KEY] # note - substitute eth0 in the following lines to match the Internet-facing interface PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE [Peer] # client foo PublicKey = [FOO 's PUBLIC KEY] PresharedKey = [PRE-SHARED KEY] AllowedIPs = 10.200.200.2/32, fd42:42:42::2/128 [Peer] # client bar PublicKey = [BAR' s PUBLIC KEY] AllowedIPs = 10.200 . 200.3 / 32 , fd42: 42 : 42 :: 3 / 128 |
Allowed IPs
不可overlap 否则会造成包转发错误。客户端
[Interface] Address = 10.200.200.2 / 24 Address = fd42: 42 : 42 :: 2 / 64 PrivateKey = [FOO's PRIVATE KEY] DNS = 1.1.1.1 [Peer] PublicKey = [SERVER PUBLICKEY] PresharedKey = [PRE-SHARED KEY] AllowedIPs = 0.0.0.0/0, ::/0 Endpoint = [SERVER PUBLIC IP ADDRESS]:51820 |
AllowedIPs
如果使用 catch-all 0.0.0.0/0, ::/0
也就会默认转发所有的流量到服务器。该选项实际作用是路由表,控制哪些流量需要经由服务器转发。wg-quick up <config>
启动 WireGuard。如果一切顺利,通过路由追踪应该可以看到流量已经交由服务器转发。总结
WIREGUARD搭建和使用折腾小记
在 Ubuntu 18.04 vps上建立 WireGuard vpn
WireGuard Introduction
- WireGuard securely encapsulates IP packets over UDP.(WireGuard 走的 UDP 协议,防火墙放行的时候别搞错了)
- WireGuard aims to be as easy to configure and deploy as SSH.
- A combination of extremely high-speed cryptographic primitives and the fact that WireGuard lives inside the Linux kernel means that secure networking can be very high-speed.
- 加密方式是 ChaCha20-Poly 1305,Hash 算法是 BLAKE2s.
Deploy WireGuard
$ sudo add-apt-repository ppa:WireGuard/WireGuard $ sudo apt-get update $ sudo apt-get install WireGuard |
/etc/WireGuard/
目录,然后生成自己机器的公私钥对:$ wg genkey | tee privatekey | wg pubkey > publickey
|
privatekey
和 publickey
。Host | wg0 Address(WireGuard 内部使用) | eth0 Address(服务商给的公网 IP) |
---|---|---|
Server | 192.168.1.1/24 | 1.1.1.1 |
Client | 192.168.1.2/24 | 2.2.2.2 |
/etc/WireGuard/
目录下创建一个名为 wg0.conf
的文件,内容分别如下:wg0.conf
:[Interface] Address = 192.168.1.1/24 SaveConfig = true ListenPort = 51820 PrivateKey = < 这里填写 Server 上 privatekey 的内容 > # Client [Peer] PublicKey = < 这里填写 Client 上 publickey 的内容 > AllowedIPs = 192.168.1.1/24 |
wg0.conf
:[Interface] PrivateKey = < 这里填写 Client 上 privatekey 的内容 > Address = 192.168.1.2/24 # Server [Peer] PublicKey = < 这里填写 Server 上 publickey 的内容 > Endpoint = 1.1.1.1:51820 AllowedIPs = 192.168.1.1/24 |
wg-quick up wg0
即可。wg
指令即可查看目前接口使用情况,比如从我的 Client 上:interface: wg0 public key: < Client 上的 publickey > private key: (hidden) listening port: 49992 peer: < Server 上的 publickey > endpoint: 1.1.1.1:51820 allowed ips: 192.168.1.0/24 latest handshake: 1 minute, 46 seconds ago transfer: 7.02 MiB received, 172.99 MiB sent |
192.168.1.1
和 192.168.1.2
进行加密地通讯了.前言
1、官方提供的Android 客户端软件,下载软件后,再下载配置信息,打开手机软件,选择导入即可。
2、这个客户端是独立存在的,不需要我们手动配置参数,直接导入下载的配置,使用就行。
安装
- sudo apt-get install libmnl-dev libelf-dev linux-headers-$(uname -r) build-essential pkg-config
直接下载
- wget https://git.zx2c4.com/WireGuard/snapshot/WireGuard-0.0.20181218.tar.xz
- git clone https://git.zx2c4.com/WireGuard
- cd WireGuard/src
- make
- make install
服务端配置
- cd ~
- mkdir wg
- cd wg
- wg genkey | tee private | wg pubkey > public
- cat private
- cat public
在
/etc/wireguard
目录下新建wg0.conf
配置文件,内容如下:
- [Interface]
- PrivateKey = 你的私钥
- Address = 10.10.10.1/24
- ListenPort = 54321
- 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
- [Peer]
- PublicKey = 客户端公钥
- AllowedIPs = 10.10.10.2/32
ifconfig
查看你实际使用的接口。wg-quick up wg0
根据配置文件快速创建 wg0
虚拟网卡并执行 PostUp
指定操作;使用 wg-quick down wg0
删除虚拟网卡并执行 PostDown
指定操作;使用 wg
查看各个节点的状态。因为WireGuard需要使用iptables的nat转发,所以在内核里面开启nat转发。
在
/etc/sysctl.conf
里面添加
- net.ipv4.ip_forward = 1
sysctl -p
使其生效。自启动,使
wireguard
开机自动启动。
- sudo systemctl enable wg-quick@wg0
wg0
即可。VPN 新宠 WireGuard 搭建
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.
网络拓扑
安装
Ubuntu 安装
$ sudo add-apt-repository ppa:wireguard/wireguard
$ sudo apt-get update
$ sudo apt-get install wireguard
iOS 安装
密钥生成
wg
命令可用于生成密钥:$ umask 077
$ wg genkey | tee private | wg pubkey > public
private
中,并从私钥派生出公钥保存在文件 public
中。- VPS (10.10.10.1):
- Private: EFkHNqKrLjjnVqeUfLd70extGCPHj7bsET1LNYjm51I=
- Public: pJyCyGG5NAyqQte62JZ2d4tUDy1B06Y4kloQetAP/T0=
- iPhone (10.10.10.2):
- Private: qAsWByso80UOTNU0ZO37Gt7uIkwbStTCus/CjEZFcV4=
- Public: 6ASrcQzy+hWVm1JEC/mz0AlyF2uASRE+SknTFqa4s1g=
- Laptop (10.10.10.3):
- Private: QJAWG0EVyt7DXfzK49KBniRm2XS698ptNr9wLfX4qG8=
- Public: QEKrMGYh7VdGeuhdDR0VvSy2Gy+GESq1Y9SOXG2jShg=
节点配置
VPS 配置
/etc/wireguard
目录下新建 wg0.conf
配置文件,内容如下:[Interface]
PrivateKey = EFkHNqKrLjjnVqeUfLd70extGCPHj7bsET1LNYjm51I=
Address = 10.10.10.1
ListenPort = 54321
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE
[Peer]
PublicKey = 6ASrcQzy+hWVm1JEC/mz0AlyF2uASRE+SknTFqa4s1g=
AllowedIPs = 10.10.10.2/32
[Peer]
PublicKey = QEKrMGYh7VdGeuhdDR0VvSy2Gy+GESq1Y9SOXG2jShg=
AllowedIPs = 10.10.10.3/32
/etc/wireguard
目录下配置文件的名称将作为生成的虚拟网卡的名称,此处命名为wg0
。- 每个节点的配置文件都必须有
[Interface]
部分,配置本节点的 IP 地址、私钥等属性。 - 每个
[Peer]
对应一个对端节点,包括节点的公钥和允许的 IP 段,此处添加 iPhone 和笔记本电脑两个节点。AllowedIPs
属性对于出口流量来说是路由表,对于入口流量来说则是访问控制列表,参考 Cryptokey Routing。 - VPS 作为被动节点,需要配置
ListenPort
,此处设置为54321
。 PostUp
和PostDown
配置用于在节点创建和删除之后执行的操作,对于 WireGuard 协议本身非必需。此处用于实现流量转发的 iptables 添加和删除,对于代理服务器来说至关重要。
wg-quick up wg0
根据配置文件快速创建 wg0
虚拟网卡并执行 PostUp
指定操作;使用 wg-quick down wg0
删除虚拟网卡并执行 PostDown
指定操作;使用 wg
查看各个节点的状态。Laptop 配置
/etc/wireguard/wg0.conf
配置文件,内容如下:[Interface]
PrivateKey = QJAWG0EVyt7DXfzK49KBniRm2XS698ptNr9wLfX4qG8=
Address = 10.10.10.3
DNS = 8.8.8.8
[Peer]
PublicKey = pJyCyGG5NAyqQte62JZ2d4tUDy1B06Y4kloQetAP/T0=
Endpoint = 149.28.171.194:54321
AllowedIPs = 0.0.0.0/0
[Interface]
部分配置了 Google DNS,用于防止域名污染。- 仅有一个
[Peer]
即对应 VPS,且需要配置Endpoint
为 VPS 公网 IP 和对应的ListenPort
即54321
。 AllowedIPs
配置为0.0.0.0/0
用于将所有流量都路由到 VPS,相当于全局代理。
wg-quick
和 wg
命令的使用与 VPS 相同,不再赘述。iPhone 配置
AllowedIPs
配置为 0.0.0.0/0
相当于全局代理,可添加具体的允许 IP 网段,例如把 AllowedIPs
设置为 Telegram 的全部网段:149.154.160.0/20, 149.154.164.0/22, 149.154.168.0/22, 149.154.172.0/22, 91.108.4.0/22, 91.108.8.0/22, 91.108.12.0/22, 91.108.16.0/22, 91.108.56.0/22
Set Up WireGuard VPN on Ubuntu
wg0
and wg1
), which behave much like the commonly found eth0
interface. This makes it possible to configure and manage WireGuard interfaces using standard tools such as ifconfig
and ip
.Caution
Do not use WireGuard for critical applications. The project is still undergoing security testing and is likely to receive frequent critical updates in the future.
Before You Begin
- You will need root access to your Linode, or a user account with
sudo
privilege. - Set your system’s hostname.
Install WireGuard
- Add the Wireguard repository to your sources list. Apt will then automatically update the package cache.
sudo add-apt-repository ppa:wireguard/wireguard
- Install Wireguard. The
wireguard
package will install all necessary dependencies.sudo apt install wireguard
DKMS will then build the Wireguard kernel module. If successful, you’ll see the following output:wireguard: Running module version sanity check. - Original module - No original module exists within this kernel - Installation - Installing to /lib/modules/4.15.0-43-generic/updates/dkms/ depmod................... DKMS: install completed. Setting up wireguard (0.0.20181218-wg1~bionic) ... Processing triggers for libc-bin (2.27-3ubuntu1) ...
Note
If the installation completes but the output does not appear, your kernel is most likely not configured correctly. To double check, issue thelsmod | grep wireguard
command. Its output should not be blank. Refer to the previous section to troubleshoot.
Configure WireGuard Server
- Generate a private and public key pair for the WireGuard server:
umask 077 wg genkey | tee privatekey | wg pubkey > publickey
This will save both the private and public keys to your home directory; they can be viewed withcat privatekey
andcat publickey
respectively. - Create the file
/etc/wireguard/wg0.conf
and add the contents indicated below. You’ll need to enter your server’s private key in thePrivateKey
field, and its IP addresses in theAddress
field.- /etc/wireguard/wg0.conf
1 2 3 4 5 6 7
[Interface] PrivateKey = <Private Key> Address = 203.0.113.5/24, fd86:ea04:1115::1/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
- Address defines the private IPv4 and IPv6 addresses for the WireGuard server. Each peer in the VPN network should have a unique value for this field.
- ListenPort specifies which port WireGuard will use for incoming connections.
- PostUp and PostDown defines steps to be run after the interface is turned on or off, respectively. In this case,
iptables
is used to set Linux IP masquerade rules to allow all the clients to share the server’s IPv4 and IPv6 address. The rules will then be cleared once the tunnel is down. - SaveConfig tells the configuration file to automatically update whenever a new peer is added while the service is running.
Set Up Firewall Rules
- Allow SSH connections and WireGuard’s VPN port:
sudo ufw allow 22/tcp sudo ufw allow 51820/udp sudo ufw enable
- Verify the settings:
sudo ufw status verbose
Start the Wireguard Service
- Start Wireguard:
wg-quick up wg0
Note
wg-quick
is a convenient wrapper for many of the common functions inwg
. You can turn off the wg0 interface withwg-quick down wg0
- Enable the Wireguard service to automatically restart on boot:
sudo systemctl enable wg-quick@wg0
- Check if the VPN tunnel is running with the following two commands:
sudo wg show
You should see a similar output:user@ubuntu:~$ sudo wg show interface: wg0 public key: vD2blmqeKsV0OU0GCsGk7NmVth/+FLhLD1xdMX5Yu0I= private key: (hidden) listening port: 51820
ifconfig wg0
Your output should resemble the following:user@ubuntu:~$ ifconfig wg0 wg0: flags=209
mtu 1420 inet 203.0.113.5 netmask 255.255.255.0 destination 203.0.113.5 inet6 fd86:ea04:1115::1 prefixlen 64 scopeid 0x0 unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 1000 (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
Wireguard Client
- Generate a key pair for the client if you have not already:
umask 077 wg genkey | tee privatekey | wg pubkey > publickey
- The main difference between the client and the server’s configuration file,
wg0.conf
, is it must contain its own IP addresses and does not contain theListenPort
,PostUP
,PostDown
, andSaveConfig
values.- /etc/wireguard/wg0.conf
Connect the Client and Server
- The first method is to directly edit the client’s
wg0.conf
file with the server’s public key, public IP address, and port:- /etc/wireguard/wg0.conf
- Enable the
wg
service:wg-quick up wg0 systemctl enable wg-quick@wg0
- The second way of adding peer information is using the command line. This information will be added to the config file automatically because of the
SaveConfig
option specified in the Wireguard server’s configuration file.Run the following command from the server. Replace the example IP addresses with those of the client:sudo wg set wg0 peer <Client Public Key> endpoint <Client IP address>:51820 allowed-ips 203.0.123.12/24,fd86:ea04:1115::5/64
- Verify the connection. This command can be run from the client or the server:
sudo wg
Regardless of which method you choose to add peer information to WireGuard, there should be a Peer section in the output of thesudo wg
command if the setup was successful.user@localhost:~$ sudo wg interface: wg0 public key: vD2blmqeKsV0OU0GCsGk7NmVth/+FLhLD1xdMX5Yu0I= private key: (hidden) listening port: 51820 peer: iMT0RTu77sDVrX4RbXUgUBjaOqVeLYuQhwDSU+UI3G4= endpoint: 203.0.123.12:51820 allowed ips: 203.0.123.12/24, fd86:ea04:1115::/64
This Peer section will be automatically added towg0.conf
when the service is restarted. If you would like to add this information immediately to the config file, you can run:wg-quick save wg0
Additional clients can be added using the same procedure.
Test the Connection
- Return to the client and ping the server:
ping 192.168.2.1 sudo wg
The last two lines of the output from running thewg
command should be similar to:latest handshake: 1 minute, 17 seconds ago transfer: 98.86 KiB received, 43.08 KiB sent
This indicates that you now have a private connection between the server and client. You can also ping the client from the server to verify that the connection works both ways.
Next steps
-------------
Send all traffic from macOS through Wireguard running on a Linux VM.
Wireguard, macOS, and Linux Virtual Machines
- Introduction
- Prerequisites
- Wireguard Configuration
- Routing and Traffic Filtering
- Shutting Down Wireguard
- License
- Contact
Introduction
Prerequisites
- An Ubuntu Linux VM is running under Parallels on a Mac laptop. Wireguard will run from this VM, and will constitute the "client" side of the VPN.
- The Mac laptop will be connected wirelessly to the network at the local coffee shop, and have an IP assigned via DHCP as usual.
- The "server" side of the Wireguard VPN is an Ubuntu system running on a major cloud provider with an Internet-facing IP address.
- Wireguard has been installed on both Ubuntu VM's, and key pairs have been generated and shared.
- Wireguard client - Mac laptop hostname and IP addresses:
- Mac laptop hostname:
maclaptop
- Mac laptop wireless IP on the coffee shop network:
192.168.0.54
, interface:en0
- Mac laptop virtual NIC IP (under Parallels):
10.211.44.2
, interface:vnic0
- Mac laptop Ubuntu VM Wireguard hostname:
wgclientvm
, IP:10.211.44.31
- Mac laptop Ubuntu VM Wireguard IP:
10.33.33.2
, interface:wg0
- Mac laptop hostname:
- Wireguard server - Ubuntu system hostname and IP addresses:
- Hostname:
wgserver
- IP:
1.1.1.1
, interface:eth0
- Wireguard IP:
10.33.33.1
, interface:wg0
- Hostname:
Wireguard Configuration
wgserver
, we have only one peer to worry about (wgclientvm
), but this could be expanded to arbitrarily many peers if necessary in order to support lots of VPN clients for more complex scenarios. For now, we just have one peer, and the configuration is shown below. Note the cryptographic keys below are obviously for testing purposes only - you will need to generate your own keys per the prerequisites above. See the Wireguard Quickstart page for detailed instructions. The main command to get things going is:$ wg genkey | tee wg0.privkey | wg pubkey > wg0.pubkey
wgserver
configuration:[wgserver]# cat /etc/wireguard/wg0.conf
[Interface]
Address = 10.33.33.1/32
ListenPort = 30003
PrivateKey = WD5wagqwC3o/JO6TVLov/jdoxu+Z1leiyuIlnQqbT3M=
[Peer]
PublicKey = 3LD8h3Cq7PgmCPyFaqOzEjF59UJFbtgR0TPAM86iYzg=
AllowedIps = 10.33.33.2/32
wgclientvm
we have:[wgclientvm]# cat /etc/wireguard/wg0.conf
[Interface]
Address = 10.33.33.2/32
PostUp = iptables -I FORWARD 1 -i %i -j ACCEPT && iptables -I FORWARD 1 -o %i -j ACCEPT && iptables -t nat -I POSTROUTING 1 -s 10.211.44.2 -j SNAT --to 10.33.33.2 && echo 1 > /proc/sys/net/ipv4/ip_forward
PostDown = iptables -D FORWARD -i %i -j ACCEPT && iptables -D FORWARD -o %i -j ACCEPT && iptables -t nat -D POSTROUTING -s 10.211.44.2 -j SNAT --to 10.33.33.2
ListenPort = 30003
PrivateKey = AEXOcHOMZkn2B5lOElBTMqLsB5P8oIbYSVYGa6ku6Hc=
[Peer]
PublicKey = yKRBaa9yLKlxLmIiPQKaKj9TD0u1+BfDCUHk0tF6rG4=
AllowedIps = 0.0.0.0/0, ::0/0
Endpoint = 1.1.1.1:30003
AllowedIps
line in the client configuration allows all IPv4 and IPv6 addresses. This is so that connections to any systems around the Internet worldwide will be allowed to transit the Wireguard VPN. The server side does not need the same AllowedIPs
line because the source address of all traffic from the server's perspective will be the client IP of 10.33.33.2
.PostUp
line sets up the necessary iptables
NAT configuration and IP forwarding to translate all incoming traffic from the Mac laptop to the source IP of the Wireguard tunnel. The PostDown
line removes the iptables rules added by the PostUp
line.[wgserver]# wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip address add 10.33.33.1/32 dev wg0
[#] ip link set mtu 1420 dev wg0
[#] ip link set wg0 up
[#] ip route add 10.33.33.2/32 dev wg0
[wgclientvm]# wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip address add 10.33.33.2/32 dev wg0
[#] ip link set mtu 1420 dev wg0
[#] ip link set wg0 up
[#] ip -6 route add ::/0 dev wg0 table 51820
[#] ip -6 rule add not fwmark 51820 table 51820
[#] ip -6 rule add table main suppress_prefixlength 0
[#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0
[#] iptables -I FORWARD 1 -i wg0 -j ACCEPT && iptables -I FORWARD 1 -o wg0 -j ACCEPT && iptables -t nat -I POSTROUTING 1 -s 10.211.55.2 -j SNAT --to 10.44.44.2 && echo 1 > /proc/sys/net/ipv4/ip_forward
[wgclientvm]# wg
interface: wg0
public key: 3LD8h3Cq7PgmCPyFaqOzEjF59UJFbtgR0TPAM86iYzg=
private key: (hidden)
listening port: 30003
fwmark: 0xca6c
peer: yKRBaa9yLKlxLmIiPQKaKj9TD0u1+BfDCUHk0tF6rG4=
endpoint: 1.1.1.1:30003
allowed ips: 0.0.0.0/0, ::/0
latest handshake: 2 seconds ago
transfer: 384.27 KiB received, 62.09 KiB sent
[wgclientvm]# ping -c 3 10.33.33.1
PING 10.33.33.1 (10.33.33.1) 56(84) bytes of data.
64 bytes from 10.33.33.1: icmp_seq=1 ttl=64 time=2.39 ms
64 bytes from 10.33.33.1: icmp_seq=2 ttl=64 time=2.63 ms
64 bytes from 10.33.33.1: icmp_seq=3 ttl=64 time=2.33 ms
--- 10.33.33.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 2.336/2.454/2.632/0.134 ms
wgclientvm
and, most importantly, to traffic coming from Mac laptop host maclaptop
itself. Achieving this is the subject of the next section.Routing and Traffic Filtering
en0
that is connected to the local wireless network. Basic routing through the default gateway of this network needs to remain intact, but we also need to first send everything down to the wgclientvm
system for routing over the established VPN tunnel.wg-routes.py
is included for this task. This script is meant to be executed on the Mac laptop and it adds three new routes to the routing table on the Mac. Although the existing default route is not changed, it is overridden with two more specific routes - each for half of the entire IPv4 address space with a gateway of the wgclientvm
IP. The final route is for the Wireguard server out of the gateway originally assigned to the default route. The original default route can optionally be deleted after these routes are established and everything is sent over the VPN.wg-routes.py
script has a setup mode that generates a config file from the specified Wireguard endpoints along with PF config and anchor files, and an operational mode that adds, deletes, or checks the status of Wireguard routes and PF policy rules. We start with the setup phase:[maclaptop]# ./wg-routes.py --setup --wg-client 10.211.44.31 --wg-server 1.1.1.1 --wg-port 30003
Configs written to '/var/root/.wg-routes.conf', '/var/root/.wg-pf.conf',
and '/var/root/.wg-pf.rules'. Now 'up|down|status' cmds can be used.
[maclaptop]# ./wg-routes.py up
Running cmd: 'route add 0.0.0.0/1 10.211.44.31'
Running cmd: 'route add 128.0.0.0/1 10.211.44.31'
Running cmd: 'route add 1.1.1.1 192.168.0.1'
Implementing default-drop PF policy via command: 'pfctl -f /var/root/.wg-pf.conf'
[maclaptop]# ./wg-routes.py status
Wireguard client route active: '0/1 10.211.44.31 UGSc 50 0 vnic0'
Wireguard client route active: '128.0/1 10.211.44.31 UGSc 1 0 vnic0'
Wireguard server route active: '1.1.1.1 192.168.0.1 UGHS 0 0 en0'
Wireguard PF 'wg-pf.rules' anchor rule active: 'block drop in log on en0 all'
Wireguard PF 'wg-pf.rules' anchor rule active: 'block drop out log on en0 all'
Wireguard PF 'wg-pf.rules' anchor rule active: 'pass quick on en0 inet proto tcp from any port 67:68 to any port 67:68 flags S/SA keep state'
Wireguard PF 'wg-pf.rules' anchor rule active: 'pass quick on en0 inet proto udp from any port 67:68 to any port 67:68 keep state'
Wireguard PF 'wg-pf.rules' anchor rule active: 'pass out quick on en0 inet proto udp from any to 1.1.1.1 port = 30003 keep state'
192.168.0.1
on the wireless network since wg-routes.py
automatically parses it out of the routing table. Further, wg-routes.py
builds a default-drop PF policy against all communications on en0
except for Wireguard UDP traffic and for DHCP requests/responses.maclaptop
and the wgclientvm
systems through Wireguard to the wgserver
system and then out to the broader Internet. In addition, the PF firewall on the Mac laptop drops all non-DHCP and non-Wireguard communications on en0
. Note that the wg-quick
tool that instantiated the Wireguard instance on wgclientvm
also sets up routing such that everything is sent over Wireguard too.Verifying Traffic Routing
maclaptop
to send everything over the VPN, let's verify that IP traffic is indeed sent via Wireguard. For this, we'll use tcpdump
on the en0
interface and then ping 8.8.8.8
. Because the Wireguard configuration in the previous section set ListenPort = 30003
, the only traffic we should see on en0
should be UDP traffic on port 30003. Simultaneously, if we sniff the wg0
interface on wgclientvm
, we should only ICMP traffic to and from 8.8.8.8
. All of this is displayed below, with the understanding that the ping
command is run after both tcpdump
commands have been started so we see everything:[maclaptop]$ ping -c 3 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: icmp_seq=0 ttl=119 time=16.503 ms
64 bytes from 8.8.8.8: icmp_seq=1 ttl=119 time=14.590 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=119 time=15.574 ms
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 14.590/15.556/16.503/0.781 ms
[maclaptop]# tcpdump -i en0 -l -nn host 8.8.8.8 or udp port 30003
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en0, link-type EN10MB (Ethernet), capture size 262144 bytes
08:04:04.331354 IP 192.168.0.54.59689 > 1.1.1.1.30003: UDP, length 128
08:04:04.354699 IP 1.1.1.1.30003 > 192.168.0.54.59689: UDP, length 128
08:04:05.366354 IP 192.168.0.54.59689 > 1.1.1.1.30003: UDP, length 128
08:04:05.380174 IP 1.1.1.1.30003 > 192.168.0.54.59689: UDP, length 128
08:04:06.367378 IP 192.168.0.54.59689 > 1.1.1.1.30003: UDP, length 128
08:04:06.381984 IP 1.1.1.1.30003 > 192.168.0.54.59689: UDP, length 128
[wgclientvm]# tcpdump -i wg0 -l -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wg0, link-type RAW (Raw IP), capture size 262144 bytes
08:04:04.342244 IP 10.33.33.2 > 8.8.8.8: ICMP echo request, id 41318, seq 0, length 64
08:04:04.356653 IP 8.8.8.8 > 10.33.33.2: ICMP echo reply, id 41318, seq 0, length 64
08:04:05.367577 IP 10.33.33.2 > 8.8.8.8: ICMP echo request, id 41318, seq 1, length 64
08:04:05.382197 IP 8.8.8.8 > 10.33.33.2: ICMP echo reply, id 41318, seq 1, length 64
08:04:06.368739 IP 10.33.33.2 > 8.8.8.8: ICMP echo request, id 41318, seq 2, length 64
08:04:06.383300 IP 8.8.8.8 > 10.33.33.2: ICMP echo reply, id 41318, seq 2, length 64
Shutting Down Wireguard
[maclaptop]# ./wg-routes.py down
Running cmd: 'route delete 0.0.0.0/1 10.211.44.31'
Running cmd: 'route delete 128.0.0.0/1 10.211.44.31'
Running cmd: 'route delete 1.1.1.1 192.168.0.1'
Restoring original PF rules via command: 'pfctl -f /etc/pf.conf'
wgclientvm
. If not, the command wg-quick down wg0
will shut it down as well.----------------------------------------------------------------------------------------------------------------
Setting up a WireGuard server on OpenWRT
$ opkg update
$ opkg install kmod-wireguard luci-app-wireguard luci-proto-wireguard wireguard wireguard-tools
$ mkdir -p /etc/wireguard
$ wg genkey | tee /etc/wireguard/server-privatekey | wg pubkey > /etc/wireguard/server-publickey
$ wg genkey | tee client-privatekey | wg pubkey > client-publickey
/etc/wireguard/server-privatekey
into Private Key. You can change Listen Port to any unused port you like. In IP Addresses, choose a subnet IP CIDR, for example 10.200.200.1/24
. This will be the subnet of the VPN./etc/wireguard/client-publickey
. In Allowed IPs, enter a random IP address in the subnet you previously chose, for example 10.200.200.2/24
. This will be the client’s internal IP address.25
into Persistent Keep Alive.99999
to your previously chosen port for WireGuard interface.uci add firewall rule
uci set firewall.@rule[-1].src="*"
uci set firewall.@rule[-1].target="ACCEPT"
uci set firewall.@rule[-1].proto="udp"
uci set firewall.@rule[-1].dest_port="99999"
uci set firewall.@rule[-1].name="Allow-Wireguard-Inbound"
uci commit firewall
/etc/init.d/firewall restart
10.200.200.2/24
. In DNS servers, put the router’s LAN IP address in. Don’t touch Listen port and MTU unless you know what you’re doing.:port
. For example vpn.foobar.dev:1234
. Put 0.0.0.0/0
into Allowed IPs . Leave the rest default and hit save. Connect to the server and you should be able to access your home's internal network on the public Internet.