wireguard

WireGuard#

文内所有操作均进行了实际验证,可放心食用.

另外本文参考了很多互联网公开资料(见文末),因部分博主是自建blog,担心某天域名消失,故摘录于此.

简介#

是一个虚拟子网软件,类似于OpenWPN,使用虚拟网卡,但是只支持UDP协议连接,配置简单。在Kernel 5.6之后已经内置。

组网方式#

最简单的peer-to-peer#

pear[公网v4/v6]===========================pear[公网v4/v6]

  • 优点是直连,很快,缺点是需要双方都要有公网IPV4/IPV6地址,且连接前一端需要知晓另外一端的公网IP,否则就会无法连接.且链接后不得随意变动
  • 如果只有一端有公网地址也行,他作为被动的一端,等待另一方没有公网ip的去主动连接.(也就是我们不在被动端填对端 Peer 的 Endpoint,而是在主动端那边填上被动端的 Endpoint,这样就能让对端向我们主动建立连接。)
  • 但是如果公网IP老是变动,对于以上问题一般有两种解决方案:DDNS或者中继转发
  • 当两端都没有公网IP,但是你有一个类似共有云节点,可以考虑中继转发

接下来会介绍下这几种方式。

### DDNS

有域名,使用共有DNS服务器:#

这种情况比较简单,直接调用域名DNS服务器的API进行注册ip变动.对端直接访问这个域名即可.

缺点是域名有TTL

没有域名#

中继转发#

中继服务器#

  • 作为中继服务器(Bounce Server),和普通的对等节点一样,它能够在 NAT 后面的客户端之间充当中继服务器,可以将收到的任何子网流量转发到正确的对等节点,这个过程并非由WireGuard处理,而是由系统内核和iptables处理的。公网可达的子网(有公网IP)不需要中继服务器,只有当有节点位于 NAT 后面(无公网IP)时才需要。
  • wg不是C-S架构,而是peer-to-peer的架构。也就是在WireGuard里客户端和服务端的功能是平等的,差别只是谁主动连接谁而已。如果双方都在监听端口,谁主动连接,谁就是客户端。主动连接的一方需要预知对方的公网地址和端口(Endpoint),被动连接的一方则不需要。如果双方都位于NAT后面,则需要加一个中继节点,双方都以中继服务器作为对等节点,它们的通信流量会先进入中继服务器,然后再转发给对方。
  • 如果某一端同时连接了多个对端,当它想访问某个IP时,如果有具体的路由可用,则优先使用具体的路由,否则就会将流量转发到中继服务器,中继服务器再根据系统路由表进行转发。可以通过检查wg show wg0route找到WireGuard对一个给定地址的路由方式。

注意事项#

  • 在 WireGuard 网络中,每一个 Peer 设备都对应一个 IP、一个公钥、一个私钥,需要保证不能冲突。并且在 WireGuard 中,需要手动给各个设备分配 IP。
  • WireGuard 组网的 IP 段需要选择私有 IP 段,不要使用公网 IP 段。并且不能和你使用的网络 IP 段冲突,例如,您可以使用 192.168.x.x10.x.x.x 等私有 IP 段。在本文档中,我使用 192.168.100.1/24 做为 WireGuard 私有段。 中继节点的 IP 地址为 192.168.100.1,Peer 节点的 IP 地址为 192.168.100.2 。Mac 的 IP 地址为 192.168.100.3
  • 后续会进行IPv6的配置

Ubuntu 安装WireGuard#

命令行安装#

sudo apt install wireguard

注意需要下载 45.7 MB 的归档,解压缩后会消耗 255 MB 的额外空间。

生成密钥#

1
2
3
4
5
6
7
8
9
10
#  tee命令用于读取标准输入的数据,并将其内容输出成文件。
wg genkey | sudo tee /etc/wireguard/privatekey | wg pubkey | sudo tee /etc/wireguard/publickey

# 或者
sudo mkdir /etc/wireguard
cd /etc/wireguard
wg genkey | tee privatekey
cat privatekey > wg pubkey publickey

# 生成的私钥将保存在 `/etc/wireguard/privatekey` 中,公钥将保存在 `/etc/wireguard/publickey` 中。

服务端配置#

  • 配置文件可以放在任何路径下,但必须通过绝对路径引用。默认路径是 /etc/wireguard/wg0.conf

  • 配置文件的命名形式必须为 ${WireGuard 接口的名称}.conf。通常情况下 WireGuard 接口名称以 wg 为前缀,并从 0 开始编号.

先看字段说明:#

  • Addresswg0 接口的 IPv4 或 IPv6 的地址。请使用保留给私有网络范围内的 IP 地址。不要和你已经使用的网络段冲突。
  • SaveConfig:在 WireGuard 关闭时自动保存配置。
  • PostUp:在 WireGuard 启动后执行的命令 。
  • PostDown:在 WireGuard 关闭后执行的命令。
  • ListenPort:WireGuard 服务器监听的端口。
  • PrivateKey:WireGuard 服务器的私钥。

先确认wlan网口名称#

1
ip -o -4 route show to default | awk '{print $5}'

不支持的也可以简单ifconfig一下人肉瞅瞅,会发现类似 wlp2s0/eth0/wlan0

找到要出口的wan口名称.

注意事项:#

PostUpPostDown 中的网络接口名称需要替换真实的也就是 -A POSTROUTING 后面的 eth0

修改配置文件#

sudo vim /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
[Interface]
Address = 192.168.100.1/24
SaveConfig = true
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o wlan0 -j MASQUERADE
ListenPort = 63520
PrivateKey = 上面生成的私有钥


[Peer]
PublicKey = 允许客户端1的公钥
AllowedIPs = 192.168.100.1/24



[Peer]
PublicKey = 允许客户端2的公钥
AllowedIPs = 192.168.100.1/24

......

启动/查看状态/开机自启动#

启动wg#

sudo wg-quick up wg0

查看状态#

sudo wg show wg0

1
2
3
4
5
6
7
8
9
10
11
12
wg show wg0
interface: wg0
public key: xxxxxxxxxxxxxxxxxxxxxxxxxxxx
private key: (hidden)
listening port: 63520

peer: xxxxxxxxxxxxxxxxxxxxxxxx
endpoint: xxxxxxxxxxxxx:63520
allowed ips: 192.168.100.0/24
latest handshake: 46 minutes, 14 seconds ago
transfer: 668 B received, 660 B sent

ip a show wg0

sudo systemctl status wg-quick@wg0 显示 Active: active (exited) 是正常的

sudo systemctl enable wg-quick@wg0

客户端配置#

1
2
3
4
5
6
7
8
9
10
11
12
[Interface]
Address = 192.168.100.1/24
SaveConfig = true
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o wlan0 -j MASQUERADE
ListenPort = 63520
PrivateKey = CLIENT_PRIVATE_KEY

[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = SERVER_IP_ADDRESS:63520
AllowedIPs = 192.168.100.1/24

注意,其中AllowedIPs = 0.0.0.0/0意思是把客户端所有流量全都转到这个网口上去,相当于全局模式.

一般只是为了局域网组网的话,仅允许Address的网段,以及对方能访问的网段(假如Peer是家里一个openwrt,多个用逗号分隔).

然后启动 sudo systemctl start wg-quick@wg0,

查看状态:

wg 或者 sudo systemctl status wg-quick@wg0

Docker安装WireGuard#

安装前需要密钥,可以在已安装wg的机器上生成,生成命令见上面.

注意:部分CPU架构不支持!比如部分Arm CPU无法运行此镜像

1
2
3
4
5
6
7
8
9
10
11
docker run \
-it \
--rm \
--cap-add NET_ADMIN \
--device /dev/net/tun:/dev/net/tun \
-v wg-access-server-data:/data \
-e "WG_ADMIN_PASSWORD=$WG_ADMIN_PASSWORD" \
-e "WG_WIREGUARD_PRIVATE_KEY=$WG_WIREGUARD_PRIVATE_KEY" \
-p 58930:8000/tcp \
-p 62820:51820/udp \
place1/wg-access-server

UDP增强#

UDP2Raw#

udp比较容易被运营商发现和屏蔽,如果有这种情况,推荐使用udp2raw,将udp流量为装成tcp流量:

(移动端伪装太麻烦了,国内稳定运行的话没必要,放弃)

https://github.com/wangyu-/udp2raw/blob/unified/doc/README.zh-cn.md

Over Vless#

参考博文#

https://yaoyao.io/posts/using-wireguard-on-ubuntu.html

https://www.cnblogs.com/milton/p/14178344.html

https://www.iplayio.cn/post/66835623