自建 Tailscale DERP 中继服务器
国内使用 Tailscale 官方 DERP 中继服务器时,容易遇到延迟高和连接不稳定的情况。在一台有公网 IP 的 VPS 上自建 DERP 服务器,能明显改善节点间的通信延迟和打洞成功率。下面介绍两种基于 Docker 的部署方式:域名反向代理模式和纯 IP 模式。
前置条件
- 一台有公网 IP 的 VPS(建议选择延迟低的地区)
- 已安装 Docker 和 Docker Compose
- 域名并配置好 DNS 解析(方案一需要,方案二不需要)
- Nginx(或其他反向代理)处理 SSL(方案一需要,方案二不需要)
方案一:域名部署 DERP(反向代理模式)
Docker Compose 配置
创建 docker-compose.yml:
关键配置说明
| 配置项 | 说明 |
|---|---|
| network_mode: host | 必须。使用宿主机网络栈,支持 IPv6 和 STUN |
| DERP_DOMAIN | 你的 DERP 服务器域名 |
| DERP_ADDR | 监听地址和端口 |
| DERPVERIFYCLIENTS | 设为 true 验证客户端身份,防止滥用 |
| tailscaled.sock | 挂载 Tailscale socket,用于客户端验证 |
⚠️ 注意:
DERP_VERIFY_CLIENTS=true需要服务器上运行 Tailscale 客户端,并且挂载其 socket 文件。
启动服务
Nginx 反向代理配置
DERP 使用 WebSocket 进行通信,需要正确配置反向代理。
重要配置解释
- 强制 WebSocket 头:
proxy_set_header Upgrade "websocket"和Connection "upgrade"是必须的,否则在 HTTP/2 下会出现 426 错误 - 使用 HTTP/1.1:
proxy_http_version 1.1确保 WebSocket 正常工作 - 关闭缓冲:
proxy_buffering off避免中继数据被缓存 - 长超时:86400 秒(24 小时)保持连接不断开
重载 Nginx:
Tailscale ACL 配置
登录 Tailscale Admin Console,进入 Access Controls,添加 derpMap 配置:
配置说明
| 配置项 | 说明 |
|---|---|
| OmitDefaultRegions | 设为 true 禁用官方 DERP,只用自建的 |
| RegionID | 自定义区域 ID,建议用 900+ 避免冲突 |
| RegionCode | 区域代码,如 hkg、sgp、tyo |
| HostName | DERP 服务器域名 |
| DERPPort | DERP 端口,通过 Nginx 反代后是 443 |
| STUNPort | STUN 端口,保持 3478 |
可选:指定 IP 地址
如果不想走 DNS 解析,可以直接指定 IP:
方案二:无域名部署 DERP(纯 IP 模式)
如果你没有域名,或者不想折腾 DNS 和 SSL 证书,可以直接用 IP 地址部署 DERP 服务器。这种方式使用 ip_derper 镜像,会自动生成自签名证书,无需 Nginx 反向代理。
Docker Compose 配置
创建 docker-compose.yml:
关键配置说明
| 配置项 | 说明 |
|---|---|
| ip_derper 镜像 | 基于官方 derper 修改,支持纯 IP 运行,自动生成自签名证书 |
| DERP_ADDR | 监听端口,这里使用 13477 |
| DERP_CERTS | 自签名证书存放路径(容器内部自动生成) |
| DERPVERIFYCLIENTS | 设为 true 验证客户端身份,防止滥用 |
| network_mode: host | 使用宿主机网络栈,支持 IPv6 和 STUN |
💡 与域名版本的区别:无域名版本不需要配置 Nginx 反向代理,DERP 服务器直接暴露端口,使用自签名 TLS 证书。
启动服务
ACL 配置
登录 Tailscale Admin Console,进入 Access Controls,添加 derpMap 配置:
核心配置说明
| 配置项 | 说明 |
|---|---|
| OmitDefaultRegions | false 表示同时使用自建和官方 DERP;true 表示只用自建 |
| IPv4 / IPv6 | 直接指定服务器 IP 地址,不走 DNS 解析 |
| InsecureForTests | 核心配置:设为 true 允许跳过 TLS 证书校验(因为使用自签名证书) |
| DERPPort | 与 DERP_ADDR 配置的端口一致,这里是 13477 |
| STUNPort | STUN 端口,默认 3478;设为 -1 可禁用该节点的 STUN |
⚠️ 注意:
InsecureForTests虽然名称中包含 “ForTests”,但这是 Tailscale 官方提供的跳过 TLS 校验的正式配置项,在纯 IP 无域名场景下是必须的。
服务器防火墙配置
无论选择哪种部署方案,都必须在系统防火墙及云服务商安全组(如阿里云、腾讯云等)放行对应端口:
| 方案 | 端口 | 协议 | 作用 |
|---|---|---|---|
| 方案一 (反代) | 443 | TCP | Nginx 接收的 HTTPS/DERP 流量 |
| 方案二 (纯 IP) | 13477 | TCP | DERP Docker 原生中继监听 |
| 所有方案 | 3478 | UDP | STUN 协议,用于 NAT 打洞穿透 |
验证 DERP 服务器
检查 DERP 状态
在任意 Tailscale 客户端执行:
输出应显示你的自定义 DERP 区域及其延迟:
检查连接方式
如果显示 relay "hkg" 或类似内容,说明正在使用你的 DERP 中继。
常见问题
Q: 状态显示 IPv6: No
检查以下几点:
- 服务器是否有 IPv6 地址
- DNS 是否配置了 AAAA 记录
- Docker 是否使用
network_mode: host - 防火墙是否放行 IPv6
Q: 426 Upgrade Required 错误
Nginx 配置问题,确保:
- 设置了
proxy_set_header Upgrade "websocket" - 设置了
proxy_set_header Connection "upgrade" - 使用
proxy_http_version 1.1
Q: 客户端验证失败
确保:
- 服务器上运行了 Tailscale 客户端
- 正确挂载了
/var/run/tailscale/tailscaled.sock - 容器有权限访问该 socket
总结
自建 Tailscale DERP 服务器的主要作用:
- 访问私有节点,减少异地通信延迟。
- 流量不走官方服务器。
- 可选在特定区域如国内云服务器部署节点。
- 支持 IPv6,提高 P2P 打洞成功概率。
配置重点:
- Docker 的
network_mode需设为host。 - 域名反代模式下,Nginx 必须加上 WebSocket 头(
Upgrade "websocket"等),避免 426 错误。 - 纯 IP 模式下,ACL 配置中必须有
"InsecureForTests": true。 - ACL 中的
OmitDefaultRegions控制是否弃用官方的 DERP 节点。