Nova Kwok's Awesome Blog

在 Ubuntu 18.04 上建立 WireGuard 隧道组建 VPS 大内网

其实感觉非常矛盾,本身对于 WireGuard 隧道的建立不是一键非常复杂的事情,本来本文应该丢到自己的 Ignorance Notebook 上的,不过搜了一下中文的圈子基本上都是一键安装脚本之类的,遂还是打算放在自己的博客上了。

Current Problem

由于需要对自己的各个服务器进行监控,最近实践了一下 Grafana + InfluxDB + Telegraf 的栈,但是遇到了一个问题,即我的 Telegraf 需要安装在远程的主机上并向自己的 Master 节点返回数据,大致架构如下:

这样就带来了一个访问控制的问题,由于 Slave 和 Master 多不在一个机房当中,所以没法享受内网数据传输,遂决定利用 VPN 的方式自建一个内网起来,保证数据的传输安全性,我知道我知道,如果要保护数据安全的话其实有很多的方式比如:

但是由于懒,加上希望有一个比较无缝的实现,且可以对上层其他的应用加以保护(比如 MySQL 的主从热备),所以便考虑了 VPN 的方式组网。同样,VPN 的选择也是多种多样,PPTP 由于感觉安全性不够最先被排除,OpenVPN 由于感觉配置过于复杂也被排除(而且据 Morgan Wu 讲这样的 VPN 有比较大的 Overhead),最后考虑了一个比较新兴且大家普遍比较喜欢的 WireGuard。

WireGuard Introduction

关于 WireGuard,有一下特点(来自 WireGuard 官网):

在一个官方的测试中,WireGuard 吞吐效率和其他同级别 VPN 对比图:

总的来说,由于集成在内核中且使用了对于移动设备友好的加密和 Hash 算法,吞吐效率较高。公私钥对的验证方式,部署方便,Overhead 较小。

Deploy WireGuard

虽然网上有许多的一键安装脚本,这里还是提及一下一个常规的安装方式,使用的服务器系统是 Ubuntu 18.04(Bionic)。

首先两边的服务器(假设称为 Server 和 Client 嘛)都需要安装 WireGuard:

$ sudo apt-get update
$ sudo apt-get install wireguard

2022/05/08 更新:移除了 add-apt-repository ppa:wireguard/wireguard 步骤

原因:在 https://launchpad.net/%7Ewireguard 上:This formerly was responsible for producing a PPA for WireGuard on Ubuntu. That functionality has now been folded into Ubuntu itself, so our old PPA has been removed. Simply run apt install wireguard on all Ubuntus ≥ 16.04.

Server 和 Client 上进入 /etc/wireguard/ 目录,然后生成自己机器的公私钥对:

$ wg genkey | tee privatekey | wg pubkey > publickey

这样在每台主机上都会有两个文件:privatekeypublickey

WireGuard 是通过创建一个虚拟接口的方式来转发流量的,这里我们暂时停一下来明确一下我们的网络规划。

Hostwg0 Address(WireGuard 内部使用)eth0 Address(服务商给的公网 IP)
Server192.168.1.1/241.1.1.1
Client192.168.1.2/242.2.2.2

Server 上开放 51820 端口(切记是 UDP)用于 Client 连接,在每台机器上 /etc/WireGuard/ 目录下创建一个名为 wg0.conf 的文件,内容分别如下:

在 Server 上的 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

在 Client 上的 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

此时隧道已经建立,双方主机已经可以通过内网 IP (这里的例子中是 192.168.1.1192.168.1.2 进行加密地通讯了,无论是 MySQL 热备还是 Nginx 反向代理都可以爽快地使用内网地址跑起来啦~

References

1.WireGuard: fast, modern, secure VPN tunnel

#Chinese #WireGuard