wireguard

1.介绍

2.升级内核

3.安装wireguard

4.wireguard配置详解

5.手动配置wireguard

6.配置Wiregurad-ui界面

1.介绍

WireGuard 是由 Jason Donenfeld 等人用 C 语言编写的一个开源3层网络隧道工具,被视为下一代 VPN 协议,旨在解决许多困扰 IPSec/IKEv2、OpenVPN 或 L2TP 等其他 VPN 协议的问题。它与 Tinc 和 MeshBird 等现代 VPN 产品有一些相似之处,即加密技术先进、配置简单。从 2020 年 1 月开始,它已经并入了 Linux 内核的 5.6 版本,这意味着大多数 Linux 发行版的用户将拥有一个开箱即用的 WireGuard。ubuntu22.02默认是5.15版本内核
WireGuard 优点:

  • 配置精简,可直接使用默认值
  • 只需最少的密钥管理工作,每个主机只需要 1 个公钥和 1 个私钥。
  • 就像普通的以太网接口一样,以 Linux 内核模块的形式运行,资源占用小。
  • 能够将部分流量或所有流量通过 VPN 传送到局域网内的任意主机。

WireGuard 不能做的事:

  • 通过信令服务器突破双重 NAT。
  • 通过中央服务器自动分配和撤销密钥。
  • 发送原始的二层以太网帧。

2.升级内核

WireGuard 的安装条件非常苛刻,对内核版本要求极高,不仅如此,在不同的系统中,内核,内核源码包,内核头文件必须存在且这三者版本要一致,Red Hat、CentOS、Fedora 等系统的内核,内核源码包,内核头文件包名分别为 kernel、kernel-devel、kernel-headers;Debian、Ubuntu 等系统的内核,内核源码包,内核头文件包名分别为 kernel、linux-headers。果这三者任一条件不满足的话,则不管是从代码编译安装还是从 repository 直接安装,也只是安装了 wireguard-tools 而已。而 WireGuard 真正工作的部分,是 wireguard-dkms,也就是动态内核模块支持(DKMS),是它将 WireGuard 编译到系统内核中。

目前 WireGuard 已经被合并到 Linux 5.6 内核中了,如果你的内核版本 >= 5.6,就可以用上原生的 WireGuard 了,只需要安装 wireguard-tools 即可,内核版本<5.6,可能需要首先更新内核,否则可能会报错:Unable to access interface: Protocol not supported,如下为更新内核版本示例(CentOS)

了,只需要安装 wireguard-tools 即可,内核版本<5.6,可能需要首先更新内核,否则可能会报错:Unable to access interface: Protocol not supported,如下为更新内核版本示例

2.1.CentOS升级内核

如果你使用的是 CentOS 等 rpm 系的发行版,必须要升级内核,步骤如下:

2.1.1 载入公钥
$ rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
2.1.2 升级安装 elrepo
$ rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
2.1.3 载入 elrepo-kernel 元数据
$ yum --disablerepo=\* --enablerepo=elrepo-kernel repolist
2.1.4 安装最新版本的内核
$ yum --disablerepo=\* --enablerepo=elrepo-kernel install  kernel-ml.x86_64  -y
2.1.5 删除旧版本工具包
$ yum remove kernel-tools-libs.x86_64 kernel-tools.x86_64  -y
2.1.6 安装新版本工具包
$ yum --disablerepo=\* --enablerepo=elrepo-kernel install kernel-ml-tools kernel-ml-devel kernel-ml-headers -y
2.1.7 查看内核插入顺序
$ grep "^menuentry" /boot/grub2/grub.cfg | cut -d "'" -f2

CentOS Linux (3.10.0-1127.10.1.el7.x86_64) 7 (Core)
CentOS Linux (5.7.2-1.el7.elrepo.x86_64) 7 (Core)
CentOS Linux (0-rescue-96820b9851c24560b5f942f2496b9aeb) 7 (Core)

默认新内核是从头插入,默认启动顺序也是从 0 开始。

2.1.8 查看当前实际启动顺序
$ grub2-editenv list

saved_entry=CentOS Linux (3.10.0-1127.10.1.el7.x86_64) 7 (Core)
2.1.9 设置默认启动
$ grub2-set-default 'CentOS Linux (5.7.2-1.el7.elrepo.x86_64) 7 (Core)'
2.1.10 最后重启检查:
$ reboot
$ uname -r
2.2 Ubuntu升级内核

内核下载 选择你需要的内核 https://kernel.ubuntu.com/~kernel-ppa/mainline/

点开网页滑到底,选择你的系统版本,我的是64位操作系统

三个generic的deb,加一个_all的deb,下载到一个文件夹中。

-rw-r--r-- 1 root root 11434148 Dec 13  2020 linux-headers-5.10.0-051000_5.10.0-051000.202012132330_all.deb
-rw-r--r-- 1 root root  1234988 Dec 13  2020 linux-headers-5.10.0-051000-generic_5.10.0-051000.202012132330_amd64.deb
-rw-r--r-- 1 root root 10970584 Dec 13  2020 linux-image-unsigned-5.10.0-051000-generic_5.10.0-051000.202012132330_amd64.deb
-rw-r--r-- 1 root root 55087372 Dec 13  2020 linux-modules-5.10.0-051000-generic_5.10.0-051000.202012132330_amd64.deb

下载好了之后安装deb文件

dpkg -i *.deb
reboot

验证

root@RainGod:~/kernel# uname -r
5.10.0-051000-generic

3.安装wireguard

示例为:Ubuntu22.04 服务端

3.1.开启内核转发
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
3.2.安装wireguard
apt update
apt install wireguard
apt install resolvconf

验证是否安装成功:

root@RainGod:~/kernel# modprobe wireguard && lsmod | grep wireguard
wireguard              86016  0
curve25519_x86_64      36864  1 wireguard
libchacha20poly1305    16384  1 wireguard
libblake2s             16384  1 wireguard
ip6_udp_tunnel         16384  1 wireguard
udp_tunnel             24576  1 wireguard
libcurve25519_generic    49152  2 curve25519_x86_64,wireguard

4.Wireguard配置详解

WireGuard配置文件必须通过绝对路径引用。默认路径是 /etc/wireguard/wg0.conf
配置文件的命名形式必须为 ${WireGuard 接口的名称}.conf。通常情况下 WireGuard 接口名称以 wg 为前缀,并从 0 开始编号,但你也可以使用其他名称,只要符合正则表达式 ^[a-zA-Z0-9_=+.-]{1,15}$ 就行。
你可以选择使用 wg 命令来手动配置 VPN,但一般建议使用 wg-quick,它提供了更强大和用户友好的配置体验,可以通过配置文件来管理配置。
下面是一个配置文件示例:

[Interface]
# Name = node1.example.tld
Address = 192.0.2.3/32
ListenPort = 51820
PrivateKey = localPrivateKeyAbcAbcAbc=
DNS = 1.1.1.1,8.8.8.8
Table = 12345
MTU = 1500
PreUp = /bin/example arg1 arg2 %i
PostUp = /bin/example arg1 arg2 %i
PreDown = /bin/example arg1 arg2 %i
PostDown = /bin/example arg1 arg2 %i

[Peer]
# Name = node2-node.example.tld
AllowedIPs = 192.0.2.1/24
Endpoint = node1.example.tld:51820
PublicKey = remotePublicKeyAbcAbcAbc=
PersistentKeepalive = 25
4.1 Interface 本地接口参数配置

这一节定义本地 VPN 配置。例如:
本地节点是客户端,只路由自身的流量,只暴露一个 IP。

[Interface]
# Name = phone.example-vpn.dev
Address = 192.0.2.5/32
PrivateKey = <private key for phone.example-vpn.dev>

本地节点是中继服务器,它可以将流量转发到其他对等节点(peer),并公开整个 VPN 子网的路由。

[Interface]
# Name = public-server1.example-vpn.tld
Address = 192.0.2.1/24
ListenPort = 51820
PrivateKey = <private key for public-server1.example-vpn.tld>
DNS = 1.1.1.1
4.1.1 # Name

这是 INI 语法中的标准注释,用于展示该配置部分属于哪个节点。这部分配置会被 WireGuard 完全忽略,对 VPN 的行为没有任何影响。

4.1.2 Address

定义本地节点应该对哪个地址范围进行路由。如果是常规的客户端,则将其设置为节点本身的单个 IP(使用 CIDR 指定,例如 192.0.2.3/32);如果是中继服务器,则将其设置为可路由的子网范围。
例如:

常规客户端,只路由自身的流量:Address = 192.0.2.3/32
中继服务器,可以将流量转发到其他对等节点(peer):Address = 192.0.2.1/24
也可以指定多个子网或 IPv6 子网:Address = 192.0.2.1/24,2001:DB8::/64
4.1.3 ListenPort

当本地节点是中继服务器时,需要通过该参数指定端口来监听传入 VPN 连接,默认端口号是 51820。常规客户端不需要此选项。

4.1.4 PrivateKey

本地节点的私钥,所有节点(包括中继服务器)都必须设置。不可与其他服务器共用。
私钥可通过命令 wg genkey > example.key 来生成。

4.1.5 DNS

通过 DHCP 向客户端宣告 DNS 服务器。客户端将会使用这里指定的 DNS 服务器来处理 VPN 子网中的 DNS 请求,但也可以在系统中覆盖此选项。例如:

如果不配置则使用系统默认 DNS
可以指定单个 DNS:DNS = 1.1.1.1
也可以指定多个 DNS:DNS = 1.1.1.1,8.8.8.8
4.1.6 Table

定义 VPN 子网使用的路由表,默认不需要设置。该参数有两个特殊的值需要注意:

Table = off : 禁止创建路由
Table = auto(默认值) : 将路由添加到系统默认的 table 中,并启用对默认路由的特殊处理。
例如:Table = 1234
4.1.7 MTU

定义连接到对等节点(peer)的 MTU(Maximum Transmission Unit,最大传输单元),默认不需要设置,一般由系统自动确定。

4.1.8 PreUp

启动 VPN 接口之前运行的命令。这个选项可以指定多次,按顺序执行
例如:

添加路由:PreUp = ip rule add ipproto tcp dport 22 table 1234
4.1.9 PostUp

启动 VPN 接口之后运行的命令。这个选项可以指定多次,按顺序执行。
例如:
从文件或某个命令的输出中读取配置值:

PostUp = wg set %i private-key /etc/wireguard/wg0.key <(some command here)

添加一行日志到文件中:

PostUp = echo "$(date +%s) WireGuard Started" >> /var/log/wireguard.log

调用 WebHook:

PostUp = curl https://events.example.dev/wireguard/started/?key=abcdefg

添加路由:

PostUp = ip rule add ipproto tcp dport 22 table 1234

添加 iptables 规则,启用数据包转发:

PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

强制 WireGuard 重新解析对端域名的 IP 地址:

PostUp = resolvectl domain %i "~."; resolvectl dns %i 192.0.2.1; resolvectl dnssec %i yes
4.1.10 PreDown

停止 VPN 接口之前运行的命令。这个选项可以指定多次,按顺序执行。
例如:
添加一行日志到文件中:

PreDown = echo "$(date +%s) WireGuard Going Down" >> /var/log/wireguard.log

调用 WebHook:

PreDown = curl https://events.example.dev/wireguard/stopping/?key=abcdefg
4.1.11 PostDown

停止 VPN 接口之后运行的命令。这个选项可以指定多次,按顺序执行。
例如:
添加一行日志到文件中:

PostDown = echo "$(date +%s) WireGuard Going Down" >> /var/log/wireguard.log

调用 WebHook:

PostDown = curl https://events.example.dev/wireguard/stopping/?key=abcdefg

删除 iptables 规则,关闭数据包转发:

PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
4.2 Peer 对端接口参数配置

定义能够为一个或多个地址路由流量的对等节点(peer)的 VPN 设置。对等节点(peer)可以是将流量转发到其他对等节点(peer)的中继服务器,也可以是通过公网或内网直连的客户端。
中继服务器必须将所有的客户端定义为对等节点(peer),除了中继服务器之外,其他客户端都不能将位于 NAT 后面的节点定义为对等节点(peer),因为路由不可达。对于那些只为自己路由流量的客户端,只需将中继服务器作为对等节点(peer),以及其他需要直接访问的节点。
举个例子,在下面的配置中,public-server1 作为中继服务器,其他的客户端有的是直连,有的位于 NAT 后面:

①.public-server1 中继服务器

[peer] : public-server2,home-server,laptop,phone

②.public-server2 直连客户端

[peer] : public-server1

③.home-server 客户端位于 NAT 后面

[peer] : public-server1, public-server2

④.laptop 客户端位于 NAT 后面

[peer] : public-server1,public-server2

⑤.phone 客户端位于 NAT 后面

[peer] : public-server1, public-server2

配置示例:
对等节点(peer)是路由可达的客户端,只为自己路由流量

[Peer]
# Name = public-server2.example-vpn.dev
Endpoint = public-server2.example-vpn.dev:51820
PublicKey = <public key for public-server2.example-vpn.dev>
AllowedIPs = 192.0.2.2/32

对等节点(peer)是位于 NAT 后面的客户端,只为自己路由流量

[Peer]
# Name = home-server.example-vpn.dev
Endpoint = home-server.example-vpn.dev:51820
PublicKey = <public key for home-server.example-vpn.dev>
AllowedIPs = 192.0.2.3/32

对等节点(peer)是中继服务器,用来将流量转发到其他对等节点(peer)

[Peer]
# Name = public-server1.example-vpn.tld
Endpoint = public-server1.example-vpn.tld:51820
PublicKey = <public key for public-server1.example-vpn.tld>
# 路由整个 VPN 子网的流量
AllowedIPs = 192.0.2.1/24
PersistentKeepalive = 25
4.2.1 Endpoint

指定远端对等节点(peer)的公网地址。如果对等节点(peer)位于 NAT 后面或者没有稳定的公网访问地址,就忽略这个字段。通常只需要指定中继服务器的 Endpoint,当然有稳定公网 IP 的节点也可以指定。例如:
通过 IP 指定:

Endpoint = 123.124.125.126:51820

通过域名指定:

Endpoint = public-server1.example-vpn.tld:51820
4.2.2 AllowedIPs

允许该对等节点(peer)发送过来的 VPN 流量中的源地址范围。同时这个字段也会作为本机路由表中 wg0 绑定的 IP 地址范围。如果对等节点(peer)是常规的客户端,则将其设置为节点本身的单个 IP;如果对等节点(peer)是中继服务器,则将其设置为可路由的子网范围。可以使用 , 来指定多个 IP 或子网范围。该字段也可以指定多次。
当决定如何对一个数据包进行路由时,系统首先会选择最具体的路由,如果不匹配再选择更宽泛的路由。例如,对于一个发往 192.0.2.3 的数据包,系统首先会寻找地址为 192.0.2.3/32 的对等节点(peer),如果没有再寻找地址为 192.0.2.1/24 的对等节点(peer),以此类推。
例如:
对等节点(peer)是常规客户端,只路由自身的流量:

AllowedIPs = 192.0.2.3/32

对等节点(peer)是中继服务器,可以将流量转发到其他对等节点(peer):

AllowedIPs = 192.0.2.1/24

对等节点(peer)是中继服务器,可以转发所有的流量,包括外网流量和 VPN 流量,可以用来干嘛你懂得:

AllowedIPs = 0.0.0.0/0,::/0

对等节点(peer)是中继服务器,可以路由其自身和其他对等节点(peer)的流量:

AllowedIPs = 192.0.2.3/32,192.0.2.4/32

对等节点(peer)是中继服务器,可以路由其自身的流量和它所在的内网的流量:

AllowedIPs = 192.0.2.3/32,192.168.1.1/24
4.2.3 PublicKey

对等节点(peer)的公钥,所有节点(包括中继服务器)都必须设置。可与其他对等节点(peer)共用同一个公钥。
公钥可通过命令 wg pubkey < example.key > example.key.pub 来生成,其中 example.key 是上面生成的私钥。

例如:PublicKey = somePublicKeyAbcdAbcdAbcdAbcd=
4.2.4 PersistentKeepalive

如果连接是从一个位于 NAT 后面的对等节点(peer)到一个公网可达的对等节点(peer),那么 NAT 后面的对等节点(peer)必须定期发送一个出站 ping 包来检查连通性,如果 IP 有变化,就会自动更新Endpoint。
例如:

本地节点与对等节点(peer)可直连:该字段不需要指定,因为不需要连接检查。
对等节点(peer)位于 NAT 后面:该字段不需要指定,因为维持连接是客户端(连接的发起方)的责任。
本地节点位于 NAT 后面,对等节点(peer)公网可达:需要指定该字段 PersistentKeepalive = 25,表示每隔 25 秒发送一次 ping 来检查连接。

5.手动配置Wireguard

5.1 生成证书

cd /etc/wireguard/
生成服务端和客户端的公钥私钥

wg genkey | tee sprivatekey | wg pubkey > spublickey
wg genkey | tee green-tao-privatekey | wg pubkey > green-tao-publickey
5.2 生成服务端配置文件
echo "[Interface]
PrivateKey = $(cat sprivatekey)
Address = 10.0.0.1/24 
#如果你的服务器主网卡名称不是 eth0 ,那么请修改下面防火墙规则中最后的 eth0 为你的主网卡名称。ens33
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
DNS = 8.8.8.8
MTU = 1420
#[Peer] 代表客户端配置,每增加一段 [Peer] 就是增加一个客户端账号
[Peer]
PublicKey = $(cat green-tao-publickey)
AllowedIPs = 10.0.0.3/32"|sed '/^#/d;/^\s*$/d' > wg0.conf
5.3 生成客户端配置文件
echo "[Interface]
PrivateKey = $(cat green-tao-privatekey)
Address = 10.0.0.3/24
DNS = 8.8.8.8
MTU = 1420
[Peer]
PublicKey = $(cat spublickey)
# 服务器地址和端口,下面的 X.X.X.X 记得更换为你的服务器公网IP,端口请填写服务端配置时的监听端口
Endpoint = X.X.X.X:51820
AllowedIPs = 0.0.0.0/1, ::0/0,128.0.0.0/1
PersistentKeepalive = 25"|sed '/^#/d;/^\s*$/d' > green-tao.conf
5.4 运行wireguard

systemd管理

    wg show wg0                     #查看wg0虚拟网卡当前状态
    systemctl status wg-quick@wg0
    systemctl restart wg-quick@wg0

5.5 命令控制
#启动

wg-quick up wg0

#停止

wg-quick down wg0

#查看wireguard的状态

wg
5.6 添加用户
5.6.1 生成密钥对
wg genkey |tee green-iphone-privatekey|wg pubkey > green-iphone-publickey
5.6.2 添加peer节点 ip不能重复
root@RainGod:/etc/wireguard# wg set wg0 peer $(cat green-iphone-publickey) allowed-ips 10.0.0.5/32
root@RainGod:/etc/wireguard# wg-quick save wg0
[#] wg showconf wg0



root@RainGod:/etc/wireguard# cat wg0.conf 
[Interface]
Address = 10.0.0.1/24
MTU = 1420
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 = YAPkAf88Dss5ev2i+so0qfd1nqrp7miyLhABZrO0k3g=


[Peer]
PublicKey = 3z1RHlorufY+USRME6HILL/es7OS0oX483hHYbC/tE8=
AllowedIPs = 10.0.0.4/32
Endpoint = 218.57.107.234:61017

[Peer]
PublicKey = gF18igCSuw2Ufx7DClEcv46B+wrYtYPCCZ4LEtSszGM=
AllowedIPs = 10.0.0.5/32

5.6.3 生成客户端配置文件
#生成客户端配置文件1
echo "[Interface]
PrivateKey = $(cat green-iphone-privatekey)
Address = 10.0.0.5/24
DNS = 8.8.8.8
MTU = 1420
[Peer]
PublicKey = $(cat spublickey)
Endpoint = X.X.X.X:51820
AllowedIPs = 0.0.0.0/0, ::0/0
PersistentKeepalive = 25"|sed '/^#/d;/^\s*$/d' > green-iphone.conf

windows 直接导入这个配置文件即可
手机可以生成二维码扫描使用

apt -y install qrencode
qrencode -t ansiutf8 < green-iphone.conf

6.配置Wiregurad-ui界面

6.1.下载Wireguard-ui项目
git clone https://github.com/ngoduykhanh/wireguard-ui.git
6.2.配置用户登录信息
root@GreenCloud:~/wireguard-ui# vim docker-compose.yaml 
version: "3"
services:
  wg:
    build: .
    #image: ngoduykhanh/wireguard-ui:latest
    container_name: wgui
    cap_add:
      - NET_ADMIN
    network_mode: host
    environment:
      - SENDGRID_API_KEY
      - EMAIL_FROM_ADDRESS
      - EMAIL_FROM_NAME
      - SESSION_SECRET
      - WGUI_USERNAME=xxxx       #修改用户登录信息
      - WGUI_PASSWORD=xxxxxx     #修改用户登录密码
      - WG_CONF_TEMPLATE
    logging:
      driver: json-file
      options:
        max-size: 50m
    volumes:
      - ./db:/app/db
      - /etc/wireguard:/etc/wireguard
6.3.启动项目
docker-compose up -d 
6.4.登录项目
http://$ip:5000

6.5.配置server


Post Up Script

iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Post Down Script

iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

配置完成后点击 Apply Config 按钮

6.6.配置全局配置

6.7.创建Wiregurad-ui守护进程

WireGuard-UI 仅负责生成配置文件。可以使用 systemd 来监视更改并重新启动服务。下面是一个例子:
系统

vim /etc/systemd/system/wgui.service

[Unit]
Description=Restart WireGuard
After=network.target

[Service]
Type=oneshot
ExecStart=/bin/systemctl restart wg-quick@wg0.service

[Install]
RequiredBy=wgui.path

#########################################

vim /etc/systemd/system/wgui.path

[Unit]
Description=Watch /etc/wireguard/wg0.conf for changes

[Path]
PathModified=/etc/wireguard/wg0.conf

[Install]
WantedBy=multi-user.target

########################################

systemctl enable wgui.{path,service}
systemctl start wgui.{path,service}

6.8.生成client配置


生成二维码

点击 Apply Config 使其生效
查看效果

posted @ 2022-06-14 09:17  老夫聊发少年狂88  阅读(3487)  评论(0编辑  收藏  举报