使用WireGuard内网穿透

1. 前言

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

1.1. WireGuard 优点

配置精简,可直接使用默认值
只需最少的密钥管理工作,每个主机只需要 1 个公钥和 1 个私钥。
就像普通的以太网接口一样,以 Linux 内核模块的形式运行,资源占用小。
能够将部分流量或所有流量通过 威屁恩 传送到局域网内的任意主机。
能够在网络故障恢复之后自动重连,戳到了其他 威屁恩 的痛处。
比目前主流的 威屁恩 协议,连接速度要更快,延迟更低。
使用了更先进的加密技术,具有前向加密和抗降级攻击的能力。
支持任何类型的二层网络通信,例如 ARP、DHCP 和 ICMP,而不仅仅是 TCP/HTTP。
可以运行在主机中为容器之间提供通信,也可以运行在容器中为主机之间提供通信。

1.2. WireGuard 工作原理

中继服务器工作原理
中继服务器(Bounce Server)和普通的对等节点一样,它能够在 NAT 后面的 威屁恩 客户端之间充当中继服务器,可以将收到的任何 威屁恩 子网流量转发到正确的对等节点。事实上 WireGuard 并不关心流量是如何转发的,这个由系统内核和 iptables 规则处理。

如果所有的对等节点都是公网可达的,则不需要考虑中继服务器,只有当有对等节点位于 NAT 后面时才需要考虑。

在 WireGuard 里,客户端和服务端基本是平等的,差别只是谁主动连接谁而已。双方都会监听一个 UDP 端口,谁主动连接,谁就是客户端。主动连接的客户端需要指定对端的公网地址和端口,被动连接的服务端不需要指定其他对等节点的地址和端口。如果客户端和服务端都位于 NAT 后面,需要加一个中继服务器,客户端和服务端都指定中继服务器作为对等节点,它们的通信流量会先进入中继服务器,然后再转发到对端。

WireGuard 是支持漫游的,也就是说,双方不管谁的地址变动了,WireGuard 在看到对方从新地址说话的时候,就会记住它的新地址(跟 mosh 一样,不过是双向的)。所以双方要是一直保持在线,并且通信足够频繁的话(比如配置 persistent-keepalive),两边的 IP 都不固定也不影响的。

2. 安装wireguard

2.1. 前提条件

需要有公网IP, VPS, 而且公网IP需要直接绑定在VPS上,
公网IP绑定在网关, 然后通过端口转发, 配置不能成功, 因为中继服务器必须知道对端的公网IP, 如果中继服务器放在网关后面, 对端IP对中继服务器来说已经不可见.

系 统: centos 7.x
内核要求: > 3.10 (uname -r)

三种安装方式, 根据具体情况任选其一

2.2. 安装方法 1: a signed module is available as built-in to CentOS’s kernel-plus

1
2
3
4
5
sudo yum install yum-utils epel-release
sudo yum-config-manager --setopt=centosplus.includepkgs=kernel-plus --enablerepo=centosplus --save
sudo sed -e 's/^DEFAULTKERNEL=kernel$/DEFAULTKERNEL=kernel-plus/' -i /etc/sysconfig/kernel
sudo yum install kernel-plus wireguard-tools
sudo reboot

2.3. 安装方法 2: users wishing to stick with the standard kernel may use ELRepo’s pre-built module

1
2
3
4
sudo yum install epel-release elrepo-release
sudo yum install yum-plugin-elrepo
sudo yum install kmod-wireguard wireguard-tools
sudo reboot

2.4. 安装方法 3: users running non-standard kernels may wish to use the DKMS package instead

1
2
3
4
sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
sudo curl -o /etc/yum.repos.d/jdoss-wireguard-epel-7.repo https://copr.fedorainfracloud.org/coprs/jdoss/wireguard/repo/epel-7/jdoss-wireguard-epel-7.repo
sudo yum install wireguard-dkms wireguard-tools
sudo reboot

3. 服务器端配置

3.1. 首先为wireguard节点创建密钥对

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
## 进入wireguard的配置文件目录

cd /etc/wireguard

## 设置umask自动为私钥加上合适的权限
umask 077

# 为节点1生成私钥
wg genkey > node1_priv_key

# 为节点1生成公钥
wg pubkey < node1_priv_key > node1_pub_key

## 查看公钥和私钥
cat node1_priv_key && cat node1_pub_key

创建wireguard节点1配置文件

/etc/wireguard/wg0.conf

1
2
3
4
5
6
7
8
9
10
11
12
13

[Interface]
Address = 192.168.2.100
DNS = 114.114.114.114
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
ListenPort = 8888
PrivateKey = private_key from node1_priv_key # 将上一步生成的private_key拷贝过来

[Peer]
PublicKey = zy3IkHgq6SdM ## Peer节点的公钥
AllowedIPs = 192.168.2.101/32

说明:
Address为wireguard新生成的网卡的IP地址;
PostUp为wireguard服务启动后的执行的命令, 即一些iptables规则
PostDown为wireguard服务关闭时需要清理的规则
其中的参数eth0为网卡名称, 需要根据节点的实际情况替换
ListenPort 可用为任意可用的端口, 只有中继服务器(Bounce Server)才需要配置, 其它节点不需要配置, 它主要是为了内网穿透时UDP打洞使用.
服务启动后将监听在udp端口, 所以防火墙需要放开对应的UDP端口而不是TCP端口
[Peer] 用来配置对端信息例如Node2
PublicKey 为Node2的公钥
AllowedIPs 为节点Node2的ip(单台主机) 或Node2节点的网段, 可参考为节点1生成密钥对

3.2. 启动node1

1
2
3
## 启动wireguard
wg-quick up wg0

查查启动是否成功,

启动成功后, 使用ifconfig查看, 应该会多出一块wg0的网卡.

使用wg命令可用查看到wireguard的当前状态.

如果要重启, 使用如下命令组合

1
2
3
4
5
6

## 关闭wireguard
wg-quick down wg0
## 启动wireguard
wg-quick up wg0

3.3. 设置为开机启动

1
2
3

systemctl enable wg-quick@wg0

通过服务启动wireguard

1
2
3

systemctl start wg-quick@wg0

查看服务状态

1
2
3

systemctl start wg-quick@wg0

查看日志

1
2
3

journalctl -u wg-quick@wg0

3.4. 配置node2

在配置node2之前需要在节点2上安装wireguard, 方法参照前面介绍的安装方法

说明, 我的节点都是Linux主机, 而且是redhat系列主机
在windows, 安装方法稍有不同, 具体请参考官网的安装指南

创建配置文件/etc/wireguard/wg0.conf

1
2
3
4
5
6
7
8
9
10
11
[Interface]
Address = 192.168.2.40
PrivateKey = node2_private_key
DNS = 114.114.114.114

# 服务端配置
[Peer]
PublicKey = node1_public_key
AllowedIPs = 192.168.2.0/24
Endpoint = 1.1.1.1:8888 ## 1.1.1.1代表公网IP
PersistentKeepalive = 25

说明: Address 是Node2的地址, 和之前配置的Node1处在同一个网段
PrivateKey: 为node2节点的私钥
DNS: DNS服务器IP
PublicKey: 为Node1的公钥
AllowedIPs: Node1节点所处网段, 如果只允许Node1节点连接该节点可用指定Node1的IP
Endpoint: 1.1.1.1 为公网IP, 替换成你自己的公网IP
PersistentKeepalive: keepalive 时间, 单位秒, 这是断线后自动重连的关键.

3.5. 在Node2上启动wireguard

启动wireguard的方法跟在Node1上启动wireguard的方法一样

1
2
3

wg-quick up wg0

设置为开机启动

1
2
3

systemctl enable wg-quick@wg0

4. 关联阅读

frp内网穿透

更多网络相关请访问鹏叔的技术博客 - network

本文原文位于鹏叔的技术博客 - 使用WireGuard内网穿透, 需要获得最近更新及反馈问题请访问原文.

5. 参考文档

WireGuard 官网

使用NPS搭建内网(穿透(保姆级教程)

Centos 7 安装 Wireguard

WireGuard 教程:WireGuard 的工作原理

基于Wireguard组网技术的内网穿透教程

作者

鹏叔

发布于

2023-04-16

更新于

2024-07-10

许可协议

评论