headscale保底设施之DERP中继服务器自建
背景
上次我们完成了headscale私有部署,但是为了保证headscale组网中的稳定和可靠性,为设备p2p连接设置一个保底措施,我们需要自建derp服务器。
什么是DERP
DERP 即 Detoured Encrypted Routing Protocol,这是 Tailscale 自研的一个协议:
- 它是一个通用目的包中继协议,运行在 HTTP 之上,而大部分网络都是允许 HTTP 通信的。
- 它根据目的公钥(destination’s public key)来中继加密的流量(encrypted payloads)。
Tailscale 会自动选择离目标节点最近的 DERP server 来中继流量
Tailscale 使用的算法很有趣: __所有客户端之间的连接都是先选择 DERP 模式(中继模式),这意味着连接立即就能建立(优先级最低但 100% 能成功的模式),用户不用任何等待。然后开始并行地进行路径发现,通常几秒钟之后,我们就能发现一条更优路径,然后将现有连接透明升级(upgrade)过去,变成点对点连接(直连)__。
因此, DERP 既是 Tailscale 在 NAT 穿透失败时的保底通信方式(此时的角色与 TURN 类似),也是在其他一些场景下帮助我们完成 NAT 穿透的旁路信道。换句话说,它既是我们的保底方式,也是有更好的穿透链路时,帮助我们进行连接升级(upgrade to a peer-to-peer connection)的基础设施。
Tailscale 官方内置了很多 DERP 服务器,分步在全球各地,惟独不包含中国大陆,原因你懂得。这就导致了一旦流量通过 DERP 服务器进行中继,延时就会非常高。而且官方提供的 DERP 服务器是万人骑,存在安全隐患。
官方内置了很多 DERP 服务器
1 | - tok: 96.6ms (Tokyo) |
为了实现低延迟、高安全性,我们可以参考 Tailscale 官方文档自建私有的 DERP 服务器。
Custom DERP Servers
部署DERP
还是docker
1 | version: '3.5' |
- stunport: 3478 默认情况下也会开启 STUN 服务,UDP 端口是 3478
- derpport: 23479
1 | 2022/09/06 01:21:27 no config path specified; using /var/lib/derper/derper.key |
部署好 derper 之后,就可以修改 Headscale 的配置来使用自定义的 DERP 服务器了。Headscale 可以通过两种形式的配置来使用自定义 DERP:
一种是在线 URL,格式是 JSON,与 Tailscale 官方控制服务器使用的格式和语法相同。
另一种是本地文件,格式是 YAML。
我们可以直接使用本地的 YAML 配置文件,内容如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14# /etc/headscale/derp.yaml
regions:
901:
regionid: 901
regioncode: gz
regionname: Tencent Guangzhou
nodes:
- name: 901a
regionid: 901
hostname: '实际域名'
ipv4: '可不需要'
stunport: 3478
stunonly: false
derpport: 23479regions 是 YAML 中的对象,下面的每一个对象表示一个可用区,每个可用区里面可设置多个 DERP 节点,即 nodes。
每个可用区的 regionid 不能重复。每个 node 的 name 不能重复。
regionname 一般用来描述可用区,regioncode 一般设置成可用区的缩写。
ipv4 字段不是必须的,如果你的域名可以通过公网解析到你的 DERP 服务器地址,这里可以不填。如果你使用了一个二级域名,而这个域名你并没有在公共 DNS server 中添加相关的解析记录,那么这里就需要指定 IP(前提是你的证书包含了这个二级域名,这个很好支持,搞个泛域名证书就行了)。
stunonly: false 表示除了使用 STUN 服务,还可以使用 DERP 服务。
hostname和 ipv4部分根据你的实际情况填写。
接下来还需要修改 Headscale 的配置文件,引用上面的自定义 DERP 配置文件。需要修改的配置项如下:
1 | # /etc/headscale/config.yaml |
在 Tailscale 客户端上使用以下命令查看目前可以使用的 DERP 服务器:
1 | $ tailscale netcheck |
tailscale netcheck 实际上只检测 3478/udp 的端口, 就算 netcheck 显示能连,也不一定代表 23479 端口可以转发流量。最简单的办法是直接打开 DERP 服务器的 URL:https://derp.XXXX.cn:23479,如果看到如下页面,且地址栏的 SSL 证书标签显示正常可用,那才是真没问题了。
Tailscale 命令行工具来测试:
查看与通信对端的连接方式及状态
1 | tailscale status |
ping一下
1 | tailscale ping 100.64.0.2 |
这个tailscale ping更加友好一点,会直接告诉你是通过DERP中继服务器还是点对点来和对方通信的。
DERP安全
我们总要设置一下DERP的访问权限,不能成为万人骑
步骤:
1、在 DERP 服务器上安装 Tailscale。
2、derper 启动时加上参数 –verify-clients
tip:因为derp是通过本地tailscale进行检测,所以docker部署的derper必须在容器内启有Tailscale客户端的实例,我们把服务器的
/var/run/tailscale/tailscaled.sock
映射进入derp容器目录中,让derp能检测到tailscale
tip:如果是使用docker安装的tailscale,请将/var/run/tailscale/tailscaled.sock映射出来,然后再映射进入derp,即让derp和tailscale容器共享volume(/var/run/tailscale/tailscaled.sock)
1 | version: '3.5' |