Wireguard打洞探索和dn11内的实践

本文参考:https://www.jordanwhited.com/posts/wireguard-endpoint-discovery-nat-traversal/

其实想写这个很久了,但由于某些原因(咕咕咕),一直拖到最近才拿出个合理的方案。

0. 起因

由于一些原因,在去年学校进行了改造,改造后的结果就是原本的公网ipv4全部木大,取而代之的是一个代播系统;而ipv6更是重量级,时有时无。而我要做的是让家里和学校建立一个wireguard隧道。

1. ipv6?

我一开始是尝试用ipv6来建立一个隧道,但由于上面提到的学校时有时无的ipv6连接,一般第二天起来就没有ipv6了,要重启op才能重新获得访问ipv6的能力。同时学校这烂网。。。还是果断放弃了。

2. NATMAP

说实话这个比较吃运营商。家里的网络是NAT1,所以能这么玩。

我们需要现在op里安装luci-app-natmap,然后这样设置

如果在wireguard监听的端口上起natmap会出现端口挤占的问题,所以我们需要一个转发。

但这个方案还是有问题,一个是这样建立的隧道在bird内可能会有个端口不一致报错(可以不用鸟),还有一个是必须由学校这边主动发起连接(稳定性不是很高)。

3. 自写打洞

这个应该是最适合目前的方案,具体原理参考jwhited的这篇博客,这边简单概述一下:首先,Wireguard设置了Listen Port之后就会通过这个端口收发消息;其次,Wireguard能设置多个Peer。将这两个特性结合,我们就能得到一个类似stun的功能,同时通过Keepalive选项能够自动维持端口。

这个方法有点妙,是躺在床上睡不着的时候想清楚的。这个老哥也是个天才。

项目在这里wg-drill,后续应该会集成到wg-quick-op里面。

只需要在Wireguard加一个Peer和两条指令就可以实现兼容现有dn11内的网络。

具体配置

Client端

安装wg-drill-client

1
./wg-drill-client install
并用systemd或proc启动wg-drill-client服务。

在Wireguard配置里添加wg-drill-client的PostUp、PreDown和服务器的Peer。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[Interface]
PrivateKey = <Private Key>
ListenPort = 10011
PostUp = /sbin/ip addr add dev %i 172.16.48.254 peer 172.16.53.254
PostUp = wg-drill-client up %i
PreDown = wg-drill-client down %i
Table = off
MTU = 1388


#home
[Peer]
PublicKey = <Target Pubkey>
AllowedIPs = 0.0.0.0/0

#stun
[Peer]
Endpoint = naclwww.com:114514
PublicKey = <Server Pubkey>
PersistentKeepalive = 3

Server端

同理,我们先安装wg-drill-server

1
./wg-drill-server install
在配置文件中添加stun的接口
1
2
3
4
5
6
7
8
[server]
listenaddr = "0.0.0.0"
listenport = 14514 //server部分不用在意,之后会移除

[drill]
enable = true
iface = "stun"
interval = 10
stun接口配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# /etc/wireguard/stun.conf
[Interface]
PrivateKey = <Server Private key>
ListenPort = 39001
Table = off
MTU = 1388

#Target A
[Peer]
PublicKey = <Target A Pubkey>

#Target B
[Peer]
PublicKey = <Target B Pubkey>

随后在server端用systemd或者proc启动wg-drill-server服务。

4. 关于其他

后面可能会尝试一下SyncThing🤔,以后再说吧。

细节可以去看看我写的💩和这位老哥的博客。