esp-idf: WireGuard

WireGuard

WireGuard是什么?

WireGuard是由 Jason A. Donenfeld 开发的自由及 开源加密VPN程序及协议,旨在获得比 IPsec 和 OpenVPN 更好的性能,后两者都是常见的隧道协议。WireGuard协议的流量经由 UDP 传输,端口号默认使用 51820

WireGuard 被设计为通用 VPN,可在嵌入式接口和超级计算机上运行,适用于许多不同情况。它最初是为 Linux 内核发布的,现在已跨平台(Windows、macOS、BSD、iOS、Android)并可广泛部署。

WireGuard组网:

img

WireGuard服务器(具备公网IP)形成了虚拟局域网那个的网关,位于不同地域的WireGuard客户端可以连接到WireGuard服务,客户端就成了虚拟局域网中的一台主机。

例如:上图中,Ubuntu客户端、windows客户端、Android/iOS客户端可以通过WireGuard服务间隔访问NAS,逻辑上形成了一条虚拟通道。

工作原理

在WireGuard中的实体主机都是同级的,互称为对等方(peer)。WireGuard 在网络层上运行。因此,无法使用 DHCP,且必须为服务器(WireGuard主机)和客户端(WireGuard主机)上的隧道设备分配静态 IP 地址或 IPv6 本地链接地址。

WireGuard处理数据:发送流程和接收流程

当 WireGuard 将网络数据包发送到对等点时(主机A –> 主机B):

  1. WireGuard 从数据包读取目标 IP,并将其与本地配置中允许的 IP 地址列表(即wg0.conf文件中peer配置项)进行比较。如果未找到 peer,WireGuard 会丢弃数据包。
  2. 如果 peer 有效,WireGuard 使用对等方A的公钥对数据包进行加密。
  3. 发送主机查找主机的最新互联网 IP 地址,并将加密数据包发送到此地址。

当 WireGuard 接收数据包时(主机A <– 主机B):

  1. WireGuard 使用主机A的私钥解密数据包。
  2. WireGuard 从数据包读取内部源地址,并在本地主机上对等点的设置中查询 IP 地址是否配置。如果源 IP 位于允许列表中,WireGuard 会接受数据包。如果 IP 地址不在列表中,WireGuard 会丢弃数据包。

应用部署

在Ubuntu 22.04 上安装 WireGuard:

1
2
sudo apt update
sudo apt install wireguard resolvconf

注意:

1、Linux内核版本要大于或等于 V5.6

2、由于 wireguard 会用到DNS,所以需要下载 resolvconf

在Ubuntu 22.04 上创建WireGuard公钥和私钥:

1
2
3
4
5
cd /etc/wireguard
# 私钥
wg genkey > server_privatekey
# 公钥
wg pubkey < server_privatekey > server_publickey

开启内核IPv4转发:

  1. 打开 /etc/sysctl.conf 文件,找到 net.ipv4.ip_forward = 1,若被注释,则取消注释
  2. 重载 /etc/sysctl.conf 文件,执行 sysctl -p /etc/sysctl.conf

配置WireGuard文件,创建文件 /etc/wireguard/wg0.conf,并编辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
[Interface]
# 本机wg密钥
PrivateKey = ECdmz74q1jX1VYweAvFSfhOERDfVPVTXdehEN9o4LGE=
# 本机wg地址
Address = 192.168.4.253/32
# 监听端口
ListenPort = 51820

# 在WireGuard服务启动或停止前后,执行命令
# 添加 iptables 规则,允许本机的 NAT 转换
# wlp1s0需要依据需要的网卡替换,当前使用的无线网卡
PreUp = echo WireGuard PreUp
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o wlp1s0 -j MASQUERADE

PreDown = echo WireGuard PreDown
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o wlp1s0 -j MASQUERADE


# 可选配置项
#DNS = 1.1.1.1, 8.8.8.8
#MTU = 1420

# 对等方配置
[Peer]
PublicKey = q55Vuknq7WEA/m4aJ2gD1ZxlgE2kymKT6PaLyCXgllg=
AllowedIPs = 192.168.4.58/32

#[Peer]
#PublicKey = Client2公钥,在客户端可看到
#AllowedIPs = 192.168.1.12/32


设置 WireGuard 开机启动、状态、启动、停止、关闭开机启动:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 直接控制
cd /etc/wireguard
## 启动
sudo wg-quick up wg0
## 停止
sudo wg-quick down wg0
## 查看
sudo wg show wg0

# systemctl 控制
sudo systemctl enable wg-quick@wg0.service
sudo systemctl status wg-quick@wg0.service
sudo systemctl start wg-quick@wg0.service
sudo systemctl stop wg-quick@wg0.service
sudo systemctl disable wg-quick@wg0.service

查看 WireGuard 信息:

1
2
3
4
5
6
7
8
9
10
11
12
pi@pi-desktop:/etc/wireguard$ sudo wg
interface: wg0
public key: r0VIDOSXDd+/xvvNc7PYprYfcMBiqft54FmoiFiEjAo=
private key: (hidden)
listening port: 51820

peer: q55Vuknq7WEA/m4aJ2gD1ZxlgE2kymKT6PaLyCXgllg=
endpoint: 192.168.5.197:51820
allowed ips: 192.168.4.0/24
latest handshake: 1 minute, 55 seconds ago
transfer: 163.88 KiB received, 162.79 KiB sent

抓包分析

树莓派4B部署WireGuard服务,WireGuard分配wg0的IP地址是:192.168.4.254/24,WireGuard服务的端口号是:58120,本地局域网eth0的IP地址是:192.168.5.196/24

ESP32部署WireGuard服务,WireGuard分配IP地址是:192.168.4.48/24,WireGuard服务的端口号是:58120,本地局域网的IP地址是:192.168.5.197/24

现在,ESP32通过WireGuard服务给的IP地址去 ping 树莓派4B的IP地址(即 192.168.4.48 ping 192.168.4.254)。通过ESP32的串口日志,发现可以ping通。

在树莓派4B上使用 tcpdump 命令抓eth0 的数据包:

1
sudo tcpdump -i eth0 -w wg_capture.pcap

image-20241226151652849

然后,在树莓派4B上使用 tcpdump 命令抓wg0 的数据包:

1
sudo tcpdump -i eth0 -w wg_capture2.pcap

image-20241226152115669

VPN

VPN是什么?

虚拟专用网(英语:Virtual Private Network,缩写:VPN)将专用网络延伸到公共网络上,使用户能够在共享或公共网络上发送和接收数据,就像他们的计算设备直接连接到专用网络上一样。

VPN 用于通过 公有网络 安全且匿名地传输数据。它们的原理是通过掩蔽用户 IP 地址并加密数据,使未获得接收信息授权的人无法读取。

VPN的按照使用场景类型:

  • 服务器–站点(远程访问VPN)

    image-20241225151625332

  • 站点–站点VPN

    image-20241225151733026

VPN按照网络层次模型分类:

  • 二层VPN(即数据链路层):L2TP VPN
  • 三层VPN(即网络层):GRE VPN 和 IPsec VPN
  • 七层VPN(即应用层):SSL VPN

参考来源

通过 WireGuard 与 IPv6 异地组网 实现远程访问局域网

实践]wireguard安装和配置

使用Wireguard搭建全流量代理

WireGuard 配置备忘录