Wireguard 是一种点对点 VPN;它不使用客户端-服务器模型。根据其配置,对等点可以充当传统服务器或客户端。它的工作原理是在充当隧道的每个对等设备上创建一个网络接口。对等点通过交换和验证公钥来相互验证,模仿 SSH 模型。公钥映射到隧道中允许的 IP 地址列表。VPN 流量封装在 UDP 中。
下面演示如何在 Ubuntu 上设置用作 VPN 服务器的 WireGuard VPN(中继服务器:路由器/网关),同时也展示如何将 WireGuard 配置为客户端,客户端的流量将通过 Ubuntu 服务器进行路由。
此设置可用于防止中间人攻击、匿名上网、绕过受地理限制的内容或允许在家工作的员工安全地连接到公司网络
前置准备
查看系统内核版本,若低于5.6
版本则需要对内核进行升级:
安装
ubuntu
1
|
sudo apt install wireguard
|
配置
服务端
生成密钥对
WireGuard VPN 网络中的每个设备都需要有一个私钥和公钥
- 开启
ipv4
流量转发:允许系统在不同的网络接口之间转发数据包,必须启用 IP 转发才能使 NAT 工作
1
2
3
4
|
# 将 net.ipv4.ip_forward = 1 追加到 /etc/sysctl.conf 文件
sudo bash -c "echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf"
# 重新加载 /etc/sysctl.conf 配置文件
sudo sysctl -p
|
出于安全考虑,Linux系统默认是禁止数据包转发的。所谓转发即当主机拥有多于一块的网卡时,其中一块收到数据包,根据数据包的目的ip地址将数据包发往本机另一块网卡,该网卡根据路由表继续发送数据包。这通常是路由器所要实现的功能。
要让Linux系统具有路由转发功能,需要配置一个Linux的内核参数net.ipv4.ip_forward
。这个参数指定了Linux系统当前对路由转发功能的支持情况;其值为0时表示禁止进行IP转发;如果是1,则说明IP转发功能已经打开。
WireGuard 服务器将能够将来自 WireGuard Peer
的流量转发给服务器上的其他人,并且客户端的公共 IP 地址将被有效隐藏
- 在
/etc
下创建文件夹WireGuard
,用于存放配置文件
1
2
3
4
5
|
sudo mkdir -p /etc/wireguard && sudo chmod 0777 /etc/wireguard
cd /etc/wireguard
# 设置新创建文件或目录的默认权限
# 只能由拥有者读取和写入(但不能执行),组和其他用户没有权限
umask 077
|
- 生成两对密钥对,分别为服务器公私钥和客户端公私钥
1
2
|
wg genkey | tee server_privatekey | wg pubkey > server_publickey
wg genkey | tee client_privatekey | wg pubkey > client_publickey
|
tee
:将输出同时写入文件和标准输出(屏幕)
>
:将输出重定向到文件中
|
:管道,将前一个命令的输出传递给另一个命令作为输入
配置服务器
- 查看系统默认路由,默认路由通常用于指示网络流量的最终出口,通常是指向网关的路由,它是网络流量转发的“兜底”规则
如果名字不是ens33
,以下PostUp
和PostDown
处里面的ens33
替换成自己服务器显示的名字
- 生成服务端配置文件
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
|
echo "
[Interface]
# 将服务器的私钥 server_privatekey 填入配置文件
PrivateKey = $(cat server_privatekey)
# 服务器的 IP 地址,通常是 VPN 网络的网关地址
Address = 10.0.8.1/24
# 设置网络规则,确保 VPN 启动后允许数据转发和网络地址转换 (NAT),停止时删除这些规则
# PostUp 会在启动 WireGuard 后执行,允许通过 wg0 接口转发流量,并进行 NAT 处理
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens33 -j MASQUERADE
# PostDown 会在停止 WireGuard 后执行,删除之前添加的规则
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens33 -j MASQUERADE
# WireGuard 使用的 UDP 端口,确保这个端口没有被防火墙阻塞
ListenPort = 50814
# 设置 DNS 服务器,确保客户端连接时可以解析域名
DNS = 8.8.8.8
# 最大传输单元,单位是字节,指数据链路层的最大payload,由硬件网卡设置MTU,是一个硬性限制
# 以太网 - 1500,无线路由器 - 1492,蓝牙 - 672
MTU = 1420
# 确保当 WireGuard 接口关闭时,任何更改都将保存到配置文件中
# SaveConfig = true
# 也可以不写下面的配置,有连接来时会自动配置
[Peer]
# 填写客户端的公钥
PublicKey = $(cat client_publickey)
# 定义客户端允许访问的 IP 范围,这里是客户端的 IP 地址
AllowedIPs = 10.0.8.10/24 " > wg0.conf
|
iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
- 此规则配置伪装,并重写进入 wg0
VPN 接口的 IPv4 流量,使其看起来像是直接来自 WireGuard 服务器的公共 IPv4 地址
服务器需要一系列私有 IPv4 地址以用于客户端及其隧道接口。 可以从以下保留的地址块中选择任何范围的 IP 地址
10.0.0.0
到 10.255.255.255
(10/8 前缀)
172.16.0.0
到 172.31.255.255
(172.16/12 前缀)
192.168.0.0
到 192.168.255.255
(192.168/16 前缀)
这里使用 10.8.0.0/24
作为第一个保留 IP 范围中的 IP 地址块。 此范围将允许多达 255 个不同的对等连接,并且通常不应与其他私有 IP 范围有重叠或冲突的地址。
WireGuard 服务器将使用该范围内的单个 IP 地址作为其私有隧道 IPv4 地址。 这里使用 10.8.0.1/24
,也可以使用 10.8.0.1
到 10.8.0.255
范围内的任何地址
- 使用配置文件启动
该命令将隧道名称 wg0
映射到 /etc/wireguard/wg0.conf
配置文件。这种命名方法意味着可以使用服务器创建任意数量的单独 VPN 隧道。
例如,可以有一个隧道设备,名称为 prod
,其配置文件为/etc/wireguard/prod.conf
。 每个隧道配置可以包含不同的 IPv4、IPv6 和客户端防火墙设置。 通过这种方式,可以支持多个不同的对等连接,每个连接都有自己唯一的 IP 地址和路由规则
1
2
3
4
5
6
7
|
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
Warning: AllowedIP has nonzero host part: 10.0.8.10/24
[#] ip -4 address add 10.0.8.1/24 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] resolvconf -a wg0 -m 0 -x
[#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens33 -j MASQUERADE
|
- 若未启动成功,查看日志,若报错
/usr/bin/wg-quick: line 32: resolvconf: command not found
,执行命令
1
|
sudo apt install openresolv
|
- 设置开机自启
1
|
sudo systemctl enable wg-quick@wg0
|
wg-quick
脚本可以将 WireGuard 作为 systemd
服务运行
- 检查接口状态和配置:
1
2
3
4
5
6
7
|
interface: wg0
public key: d3TQiWAcLh8AFcWSKpikndHmcSDC1/hexq64JNhF3nA=
private key: (hidden)
listening port: 50814
peer: AjfIq7FBNAVO20gb1+T9freO2PL8gDsceXUdvzOMjUU=
allowed ips: 10.0.8.0/24
|
验证接口状态:
1
2
3
4
|
6: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
link/none
inet 10.0.8.1/24 scope global wg0
valid_lft forever preferred_lft forever
|
- 关闭
wg0
接口
客户端
- 客户端配置文件
client.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
[Interface]
PrivateKey = $(cat client_privatekey) # 填写本机的 privatekey 内容
Address = 10.0.8.10/24
DNS = 8.8.8.8
MTU = 1420
[Peer]
PublicKey = $(cat server_publickey) # 填写对端的 publickey 内容
# server公网的IP
Endpoint = 192.168.2.135:50814
# 接受对等服务器发送具有任何源 IP 的数据包
AllowedIPs = 0.0.0.0/0, ::0/0
# 维持长连接,让 NAT 记得对应的映射关系
PersistentKeepalive = 25
|
windows
在官网下载windows客户端,导入配置文件
ubuntu
设置 Linux 和 macOS 客户端的过程与设置服务器的过程几乎相同, 仅是配置文件有区别,配置文件用上面的client.conf
启动:/etc/wireguard/wg0.conf
检查连接:
1
2
3
4
5
6
7
8
9
10
11
12
|
wyatt@wg [~/Desktop] ➜ sudo wg
interface: wg0
public key: d3TQiWAcLh8AFcWSKpikndHmcSDC1/hexq64JNhF3nA=
private key: (hidden)
listening port: 50814
peer: AjfIq7FBNAVO20gb1+T9freO2PL8gDsceXUdvzOMjUU=
endpoint: 192.168.2.1:62980
allowed ips: 10.0.8.0/24
latest handshake: 9 seconds ago
transfer: 751.47 KiB received, 5.15 KiB sent
|
问题一:建立VPN后无法访问 Internet 或虚拟网络中的任何网站
- 修改客户端的
AllowedIPs
为服务器ip
地址,表示只将该ip
的流量转发
参考