前言
本人是 Tailscale 重度用户,一家八口十几台全球各地的服务器以及笔记本手机 NAS 之类的设备都安装了 Tailscale,爽死了。
但是最近电信不知道抽了什么风,早晚高峰Q得妈都不认识,还时不时间歇封锁几个官方中继,导致连接稳定性骤降。
为了对抗封锁和运营商 QoS,提升连接稳定性,萌生了自建中继的想法。
正好赶上阿里云做活动,2C2G 200Mbps 的轻量云服务器首年仅需 79,叠了点券 60 拿下,困了就有人送枕头,这下不得不建了(
准备:编译 derper
官方的 DERP 服务端不提供预编译的二进制文件,需要手动Go建:
1 | git clone https://github.com/tailscale/tailscale.git |
若你网络环境不佳(意思是在大陆且没有梯子),可在Go建前预先设置代理:
1 | export GO111MODULE=on |
等一会儿,应该会在构建目录看到一个叫 derper 的二进制文件,将它移动/上传到合适的地方并设置权限:
1 | cp ./derper /usr/local/bin/ |
测试一下:
1 | derper -h |
应能看到类似如下输出:
1 | Usage of derper: |
到这里,derper 已经安装完毕。
方式一:使用域名运行(推荐,中国大陆需备案)
如果你有中国大陆备案域名,可以看这一段;否则请直接跳到「方式二:使用 IP 运行」。
1. 域名解析
准备一个域名,解析到你的服务器 IP,例如:
1 | relay.inm.com → 114.51.41.9 |
2. 安装 acme.sh 申请证书
安装 acme.sh(网络条件良好时):
1 | curl https://get.acme.sh | sh |
如果网络条件不佳,可以改用 Gitee 镜像:
1 | git clone https://gitee.com/neilpang/acme.sh.git |
假设你的域名 在 Cloudflare 托管,可以使用 DNS-01 验证方式:
- 在 Cloudflare 控制台创建一个 API Token,权限设定为:DNS 区域 - 编辑 - 你的域名。
- 在配置文件里填写凭据:
1 | vi ~/.acme.sh/account.conf |
添加如下内容:
1 | CF_Token="你的Cloudflare API Token" |
然后申请证书并安装:
1 | acme.sh --issue \ |
3. 将 DERP 节点限制为仅你的 Tailnet 可用
如果不想被人搭便车偷跑流量,最好设置为仅你的 Tailnet 网络设备可用。
在服务器上登录你的 Tailscale 账户,然后把服务器加入 Tailnet:
1 | tailscale up |
确认无误后,编写 systemd 服务文件:
1 | sudo vi /etc/systemd/system/derper.service |
示例:
1 | [Unit] |
重载并启动:
1 | sudo systemctl daemon-reload |
检查运行情况:
1 | journalctl -u derper -f |
若日志中出现:
1 | DERP server running on :443 |
说明已经正常运行。
关于未备案域名
未备案域名绑定大陆 IP,在特定网络环境下会遭遇「部分阻断」:
- 普通 HTTP/HTTPS/UDP 流量不受干扰;
- 但在进行 WebSocket Upgrade 时会遭到双向 RST 注入,打断连接。
表现为:
- 客户端可以侦测到 DERP 节点在线,延迟也有数据;
- Tailnet 内任何一台主机都无法连接到受影响的客户端;
- 服务端日志频繁出现如下错误:
1 | Apr 1 11:45:14 foxserver-cn derper[11451]: 1919/08/10 11:45:14 http: TLS handshake error from 114.51.41.9:11451: write tcp 191.98.10.1:19198->114.51.41.9:11451: write: connection reset by peer |
受影响客户端会看到类似提示:
1 | # Health check: |
若出现上述情况,这基本可以判定你受到了阻断,建议更换到 基于 IP 的运行方式。
方式二:使用 IP 运行(自签证书)
使用 IP 地址运行 DERP 节点则不需要公网可用的域名,仅需要公网 IP 自签证书即可。
1. 准备证书目录
1 | sudo mkdir -p /var/lib/derper |
一般情况下,在后续步骤中,derper 会自动生成自签证书,无需手动干预。但如果出现错误或者想更改证书内容,可以手动生成:
1 | # 以 114.51.41.91 为例 |
这里的
CN=114.51.41.91使得证书只对114.51.41.91这个 IP 有效。
有效期可以随便写,但不宜设置得太短,因为到期需要手动更换,可以直接签个 100 年。
将证书和私钥放到 /var/lib/derper 中(如有需要):
1 | sudo mv 114.51.41.91.* /var/lib/derper/ |
2. 编写 systemd 服务
接下来写一个 systemd service 文件用来运行服务(注意更改 IP 和端口):
1 | sudo vi /etc/systemd/system/derper.service |
内容示例:
1 | [Unit] |
加载并启动服务:
1 | sudo systemctl daemon-reload |
3. 计算自签证书指纹
后续在 ACL 中配置自签证书时,需要用到证书的 SHA256 指纹:
1 | openssl x509 -in /var/lib/derper/114.51.41.91.crt -noout -fingerprint -sha256 |
输出类似:
1 | SHA256 Fingerprint=39c6db53804bc0992ea35a1d64dc3ec381a904222a6360cc40c3e6677896f278 |
请妥善保存该指纹,这是后面会用到的神奇妙妙工具。
检查服务运行情况:
1 | journalctl -u derper -f |
确认它为 active (running),且日志里没有明显错误或警告即可。
为什么不推荐IP证书?
DERP 路径里,Tailscale 客户端是按我们在 derpMap 里写的 HostName + CertName 来校验证书的:
现在如果用的是自签证书,配上CertName: “sha256-raw:<证书指纹>”
tailnet 里所有 client 都是按 指纹 pin,不会走系统 CA,也不在乎证书是不是可信 CA 签出来的。
若你的 DERP 是 完全私用,只有你自己接入,就不需要让普通浏览器访问它,也不需要给外部第三方看这个证书。
更别说免费IP证书有效期往往只有一个月甚至几天,配这种东西就是徒增成本。
从功能 / 稳定性角度来说,换成「免费 IP 证书」几乎没有额外收益,反而增加复杂度和潜在故障点。
接入 Tailnet:控制台配置 derpMap
此时 DERP 服务器已经成功运行,但 Tailnet 还不知道它的存在,需要在控制台 ACL 规则中声明。
打开管理后台:Access controls - Tailscale
在你原有的配置中,新增一个 derpMap 块。
1. 使用域名 + 证书的配置示例
如果在 DERP 中使用了域名(如 relay.inm.com),并且证书链正常,可以参考如下配置:
1 | { |
2. 使用 IP + 自签证书的配置示例
如果使用 IP 地址并且采用自签证书,可以参考以下写法:
1 | { |
注意根据你实际的:
- 公网 IP;
derper监听端口(DERPPort);- STUN 端口;
- 证书指纹;
进行对应替换。
刷新客户端配置并测试
1. 强制刷新客户端 DERP 配置
在客户端机器上执行:
1 | sudo tailscale down |
2. 检查 DERP 节点状态
使用以下命令检查 DERP 节点是否已更新,并且连接正常(假设 RegionID 为 900):
1 | tailscale debug derp 900 |
如果输出中没有错误,那么表示配置已经生效。
IP 搭建的 DERP 有时会出现
failed to verify certificate或者Error making request to the captive portal check的错误,这并不影响使用。
3. 实际连通性测试
使用 tailscale ping 命令检查与其它设备的连接:
1 | tailscale ping foxstation |
若无问题,可再进行 SSH 测试:
1 | ssh root@foxstation |
如果能够正常连接、且在晚高峰也没有明显卡死或大面积超时,便可以认为自建 DERP 已经正确接入 Tailnet,并且在当前网络环境下比官方节点更稳定。






