自建 Tailscale Derper 中继服务
1. 背景
Tailscale 是基于 wireguard 的跨平台虚拟组网工具,可以非常方便地实现多个设备的 mesh 虚拟组网。组网后,设备间可以直接使用内网 IP / 域名进行通信,可以随意切换网络,不会引起地址变动。这在远程访问、自建服务等场景下是极为有用的。
其优点和用途不再赘述,见另一篇文章《自建 Tailscale 服务并实现多设备组网互联》。
不过,由于国内没有现成的 Tailscale Derper 中继服务器,直接使用 Tailscale 默认提供的境外中继服务会出现延迟爆炸的问题。这里详细介绍一下如何在自己的服务器上搭建 Derper 中继,并完成中继节点配置工作。
2. 准备
部署 Derper 中继需要你拥有一台具有公网 IP 地址的服务器,至少拥有一个能对外公开的 TCP 端口和一个能对外公开的 UDP 端口。
下面介绍的部署方式将使用 docker-compose,因此你服务器的系统最好是 Linux。
3. 部署 Derper 中继
我们使用 Derper 的自签名 IP 证书模式进行部署,这在国内服务器特殊的 HTTPS 政策下有一定的优势。
Derper 中继服务器的 docker-compose.yml 文件如下:
services:
derper:
container_name: derper
image: fredliang/derper:latest
restart: unless-stopped
ports:
- <Derper工作端口>:<Derper工作端口>
- <STUN工作端口>:<STUN工作端口>/udp
environment:
DERP_DOMAIN: "<Derper服务器IP地址>"
DERP_CERT_MODE: "manual"
DERP_CERT_DIR: "/cert"
DERP_ADDR: ":<Derper工作端口>"
DERP_STUN: "true"
DERP_STUN_PORT: "<STUN工作端口>"
DERP_HTTP_PORT: "-1"
DERP_VERIFY_CLIENTS: "false"
volumes:
- "/etc/localtime:/etc/localtime:ro"
- "/etc/timezone:/etc/timezone:ro"
- "./cert:/cert"其中,
- 在
DERP_ADDR中设置 Derper 中继的工作端口(TCP) - 在
DERP_STUN_PORT中设置 STUN 打洞服务的工作端口(UDP) - 将这两个端口暴露给外部以对外提供服务
- 在
DERP_DOMAIN设置 当前所在服务器的 IP 地址,以使用内置的自签名证书服务
配置完毕后,执行 docker compose up -d 命令启动 Derper 中继服务器。
3.1. 记录自签名证书指纹
接下来,使用 docker compose logs -f 命令查看中继服务器日志。不出意外的话会看到类似如下的日志输出:
derper | 2026/01/10 00:00:10 Using self-signed certificate for IP address "<Derper服务器IP地址>". Configure it in DERPMap using: (https://tailscale.com/s/custom-derp)
derper | {"Name":"custom","RegionID":900,"HostName":"<Derper服务器IP地址>","CertName":"sha256-raw:XXXXXXXXXXXXXXXXXXXXXXXXXX"}将其中的证书指纹 sha256-raw:XXXXXXXXXXXXXXXXXXXXXXXXXX复制出来备用。
3.2. 服务器防火墙放行
服务器的防火墙 / 安全组需要放行如下端口,以允许中继 Derper 对外提供服务:
- Derper 中继工作端口(TCP)
- Derper STUN 服务工作端口(UDP)
设置完毕后,使用浏览器打开 https://<Derper服务器IP地址>:<Derper工作端口>,观察是否有正常的 HTTP 响应,如图

如果能访问到此页面,表明部署成功。
注意到浏览器会报错 HTTPS 证书错误(证书无效),这是正常现象,因为我们使用的是自签名证书
4. 将自建 Derper 加入中继节点
接下来,为了让 Tailscale 客户端用上我们自建的 Derper 中继服务,需要进行一些设置
4.1. 我使用的是官方 Tailscale
如果你使用的是官方 Tailscale 控制面板,登录官方控制面板,进入 Access Control 页面,添加如下 ACL 设置:
......
//////////////////////////////// 自定义Derper中继 ////////////////////////////////
"randomizeClientPort": true, // 客户端使用随机端口,提升打洞成功率
"derpMap": {
"OmitDefaultRegions": true, // 不使用官方的境外中继节点
"Regions": {
// 添加自己的中继服务器
// 不同地理位置的服务器建议放在不同Region
"900": {
"RegionID": 900,
"RegionCode": "<随便起一个区域名字>",
"Nodes": [
{
"RegionID": 900,
"Name": "<给节点起个名字>",
"HostName": "<Derper服务器IP地址>",
"IPv4": "<Derper服务器IP地址>",
"DERPPort": <Derper工作端口>,
"STUNPort": <STUN工作端口>,
"STUNOnly": false,
"CertName": "<前面保存的 sha256-raw:XXXXXXX 证书指纹>",
"InsecureForTests": true,
},
],
},
},
},
......地址、端口等和前面搭建 Derper 中继时设置的参数保持一致。
添加完成后保存 ACL 设置,然后在所有 Tailscale 客户端先断开连接,再重新连接。这时候你自建的 Derper 服务器应该就已经被用上了,在客户端终端执行 tailscale netcheck 命令就可以看到。
4.2. 我使用的是自建 Headscale
如果你自建了 Headscale 控制面板,需要修改 headscale 的 derp-map 配置,将此 Derper 加入列表。
切换到 headscale 的工作目录,在./headscale-config/config.yaml 中设置 derp-map 配置文件的路径:
derp:
...
paths:
- /etc/headscale/derp.yaml然后在./headscale-config/derp.yaml 中添加中继区域和中继节点信息:
regions:
# 添加自己的中继服务器
# 不同地理位置的服务器建议放在不同Region
900:
regionid: 900
regioncode: "<随便起一个区域名字>"
nodes:
- name: "<给节点起个名字>"
regionid: 900
hostname: "<Derper服务器IP地址>"
certname: "<前面保存的 sha256-raw:XXXXXXX 证书指纹>"
ipv4: "<Derper服务器IP地址>"
derpport: <Derper工作端口>
stunport: <STUN工作端口>
stunonly: false
insecurefortests: true地址、端口等和前面搭建 Derper 中继时设置的参数保持一致。
添加完成后保存文件,重启 Headscale,然后在所有 Tailscale 客户端先断开连接,再重新连接。这时候你自建的 Derper 服务器应该就已经被用上了,在客户端终端执行 tailscale netcheck 命令就可以看到。
5. 防止 Derper 被白嫖
目前,我们建立的 Derper 服务器是没有认证的,任何人都可以使用我们的 Derper 服务,占用服务器带宽。为了避免自己的 Derper 服务器被别人白嫖,我们需要进一步启用客户端认证。
5.1. 我使用的是官方 Tailscale
如果你使用的是官方 Tailscale 控制面板,我们需要在 Derper 中继服务器旁再添加一个 Tailscale 客户端,用于 DERP_VERIFY_CLIENTS 客户端验证功能。
登录官方控制面板,进入 Settings → Keys,创建一个 Auth key,用于客户端登录
在服务器上执行
docker compose down命令,停止 Derper 中继服务修改 Derper 的
docker-compose.yml文件:services: # ......(前面的保持不变) DERP_STUN: "true" DERP_STUN_PORT: "<STUN工作端口>" DERP_HTTP_PORT: "-1" DERP_VERIFY_CLIENTS: "true" # 验证客户端选项改成true volumes: - "/etc/localtime:/etc/localtime:ro" - "/etc/timezone:/etc/timezone:ro" - "./cert:/cert" - "ts-socket-share:/var/run/tailscale" # 添加Tailscale Socket接口的映射 # 新增一个Tailscale客户端,用于Derper的权限认证 ts-client-velify: container_name: ts-client-velify image: tailscale/tailscale:latest restart: unless-stopped environment: TS_AUTHKEY: "<刚刚创建的Auth key>" TS_STATE_DIR: "/var/lib/tailscale" TS_SOCKET: "/var/run/tailscale/tailscaled.sock" TS_USERSPACE: "true" volumes: - "/etc/localtime:/etc/localtime:ro" - "/etc/timezone:/etc/timezone:ro" - "./tailscale-state:/var/lib/tailscale" - "ts-socket-share:/var/run/tailscale" # 添加一个共享卷,用于接口共享 volumes: ts-socket-share:保存文件,退出,执行
docker compose up -d重新启动 Derper 中继回到官方 Tailscale 控制面板,可以看到 Machines 页面多了一个设备,选择 Approve 允许其加入 Tailnet 网络
在服务器上执行
docker compose restart,重启 Derper 和 Tailscale 客户端
此时 Derper 中继服务将正常工作,并受客户端验证保护。对于不在你 tailnet 网络中的设备,Derper 将拒绝进行中继,有效防止被其它未知客户端白嫖。
说起来,笔者曾经 提过 Issue 建议 Tailscale 官方增加用于 Derper –verify-client-url 参数的官方验证 API,可惜目前暂时没有回复~因此官方用户只能麻烦一点了
5.2. 我使用的是自建 Headscale
所有 v0.23.1 及以后的 Headscale 服务端提供了一个 /verify 接口用于进行客户端身份验证。相比于传统的 Tailscale 客户端验证,这个方法要简单方便得多。
具体的配置方法如下:
在 Derper 中继的 docker-compose.yml 的环境变量部分,添加 DERP_VERIFY_CLIENT_URL 条目:
services:
# ......(前面的保持不变)
DERP_HTTP_PORT: "-1"
DERP_VERIFY_CLIENTS: "false"
DERP_VERIFY_CLIENT_URL: "https://<你的Headscale服务器域名>:<工作端口>/verify" # 添加这个
volumes:
- "/etc/localtime:/etc/localtime:ro"
- "/etc/timezone:/etc/timezone:ro"
- "./cert:/cert"修改好后保存文件,执行 docker compose restart 命令重启 Derper。
从此以后,每当有客户端试图连接到 Derper 时,它会通过 Headscale 的接口查询验证客户端身份,进而决定接收 / 拒绝请求,有效防止被其它未知客户端白嫖。
6. 总结
经过如上配置,你的 Tailscale 客户端就可以使用自建的国内 Derper 中继服务器进行通信了,这大大降低了中继状态下节点之间的延迟,带宽也得到了很大的提高。
7. Q&A
7.1. 为什么 Derper 用自签名 IP 证书模式?
一般来说,Derper 中继需要一个正常的 TLS 证书用于中继 - 客户端之间的加密通信。
但是,由于免费的 TLS 证书必须绑定域名,而国内对于未备案服务器绑定域名提供 HTTPS 服务控制相当严格,这导致在国内服务器上自建 Derper 中继可能会存在一些问题。
很巧的是,在 Issue #11776 · tailscale/tailscale 中,bradfitz 决定为 Derper 中继提供自签名证书支持 —— 你可以让 Derper 自动生成基于服务器 IP 的自签名证书,然后将证书指纹写进 DerpMap 配置中。
这样,我们不需要使用域名,仅仅只用服务器 IP + 自签名证书,就可以正常使用 Derper 进行中继通信了。
7.1.1. 这么做的优点有哪些?
- 不需要手动部署证书
- 不用操心证书续期问题
- 不需要绑定域名,因此 Derper 服务可以在国内服务器上随意自建,不用担心 HTTPS 被封锁
- 一定程度上可以防止 Derper 被他人滥用
另外,Tailscale 各节点间的通信本身就是端到端加密的,引入自签名证书并不会破坏系统本身的安全性,因此这里自签名证书可以放心使用。