近来搬了一次家,新屋的宽带是 NAT 套 NAT 套 cgNAT, 意味着家里的 NAS 只能通过 DERP 中转来通联了。虽然从技术上来说,距离最近的公用 DERP 服务器应该是香港节点,但是不知为何,NAS 偏偏对德克萨斯情有独钟。
顶着按秒计算的延迟和按位计算的带宽连 SSH 操作都很困难,而且短时间内我也不太可能找到换宽带的方法,那看来只有选择自建 DERP 这一个方案了。
DERP 服务器选型
和 Headscale 服务器不同,DERP 服务是要实打实转发流量的。2M 小水管肯定是没法承接这些任务的。况且我也不太希望流量需要绕一圈出省之后再进省,万一触发了 PCDN 一刀切我还得再各种扯皮。所以需要找到一个满足以下条件的服务器:
- 可用区和我在同一个省
- 带宽足够大
- 便宜
- 月度流量不要太抠门
为了省钱,CPU 和内存指标都可以压得尽可能低,1 CPU + 1 GB 内存已经足够使用。一般来说,国内各个大厂云的轻量服务器就能满足要求。或者,如果你人缘够好,说不定别人已经建好了 DERP 服务器,你只需要加入即可。
之后的部分假定你有一台专门作为 DERP 的服务器(至少,80, 443 和 3478 端口空闲的服务器),安装 Debian 系的系统。同时假定你已经有一个备案过的可签发证书的域名。如果你需要直接通过 IP 访问的话,可以参考这个或者这个方案来爆改 DERP 服务器实现。
配置安全组 / 防火墙
需要放行以下端口和协议:
80/tcp443/tcp3478/udpicmp
3478 端口是为了 STUN 打洞。
安装 DERP 服务
首先安装好 Go:
sudo apt install golang-go
如果你的 DERP 机器选在了国内,则还需要配置好 Go 的代理服务:
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
安装 DERP 服务只需要一行:
go install tailscale.com/cmd/derper@latest
这会把 derper 安装到 ${HOME}/go/bin/ 下。你可以把这个路径加到 PATH 中方便操作。
配置 DERP 服务
你的域名不一定非得是 derp.my.server.arpa. 之后遇到这个域名时替换成你的实际域名即可。
弄个证书
derper 无法指定证书文件,它要求证书名称一定是 $hostname.crt 和 $hostname.key. 假如你通过 CertBot 或者 acme.sh 签发的证书不是这个格式,则还需要稍加修改。以 acme.sh 签发为例:
签发的证书在 ${HOME}/.acme.sh/derp.my.server.arpa_ecc 下,分别为 ${HOME}/.acme.sh/derp.my.server.arpa_ecc/fullchain.cer 和 ${HOME}/.acme.sh/derp.my.server.arpa_ecc/derp.my.server.arpa.key. 我们可以通过符号链接的方式创建满足 derper 要求的证书:
sudo mkdir -p /etc/derp/cert
sudo -E ln -s ${HOME}/.acme.sh/derp.my.server.arpa_ecc/fullchain.cer /etc/derp/cert/derp.my.server.arpa.crt
sudo -E ln -s ${HOME}/.acme.sh/derp.my.server.arpa_ecc/derp.my.server.arpa.key /etc/derp/cert/derp.my.server.arpa.key
之后可以手动启动 derper 测试配置是否正确:
sudo -E ${HOME}/go/bin/derper --certmode manual --certdir /etc/derp/cert --hostname derp.my.server.arpa
derper 启动后,访问 https://derp.my.server.arpa 应该可以看到 DERP 服务器的默认页面。
设置 Systemd 服务
derper 由于不是很稳定,经常会自己把自己跑崩溃,所以需要每隔 12 小时重启一下这个服务。如果你的 Systemd 版本比较新,可以通过指定 Restart 和 RuntimeMaxSec 属性来设置其自动重启。
你需要替换一下 ExecStart 中 derper 文件的路径
# /etc/systemd/system/derp.service
[Unit]
Description=Tailscale DERP Server
After=network.target
Wants=network.target
[Service]
Type=simple
User=root
Restart=always
RuntimeMaxSec=12h
ExecStart=/home/user/go/bin/derper --hostname derp.srvcdiag.com --certmode manual --certdir /etc/derp/cert
RestartSec=10
[Install]
WantedBy=multi-user.target
重载并使能服务即可:
sudo systemctl daemon-reload
sudo systemctl enable derp.service --now
设置 Headscale
进入到 Headscale 机器,新增一个 DERP 服务器描述文件 /etc/headscale/derp.yml:
# /etc/headscale/derp.yml
regions:
900:
regionid: 900
regioncode: xaa
regionname: My DERP
nodes:
- name: 900a
regionid: 900
hostname: derp.my.server.arpa
stunport: 3478
stunonly: false
derpport: 443
然后编辑主配置文件包含 DERP 描述文件:
# /etc/headscale/config.yml
# 前略
derp:
paths:
- /etc/headscale/derp.yaml
# 后略
重启 Headscale 服务即可。所有客户端都会自动发现新配置的服务器并尝试与之通联。
冲浪
要验证自己的 DERP 服务器是否正确通联,可以在客户端节点上执行 tailscale netcheck:
$ tailscale netcheck
Report:
* Time: 2025-09-20T05:38:55.582472335Z
* UDP: true
* IPv4: yes, ---.---.---.---:-----
* IPv6: no, but OS has support
* MappingVariesByDestIP: false
* PortMapping: UPnP
* CaptivePortal: false
* Nearest DERP: My DERP
* DERP latency:
- xaa: 11.7ms (My DERP)
- sfo: 170.2ms (San Francisco)
- lax: 170.8ms (Los Angeles)
- sea: 178.5ms (Seattle)
- den: 189.4ms (Denver)
- hel: 192.6ms (Helsinki)
- nue: 206.7ms (Nuremberg)
- hkg: 210.8ms (Hong Kong)
- dfw: 214.4ms (Dallas)
- ord: 219.8ms (Chicago)
- iad: 221.3ms (Ashburn)
- hnl: 222.8ms (Honolulu)
- tor: 225.7ms (Toronto)
- mia: 226ms (Miami)
- nyc: 227ms (New York City)
- par: 237.7ms (Paris)
- fra: 245.2ms (Frankfurt)
- ams: 247.1ms (Amsterdam)
- lhr: 254.6ms (London)
- waw: 266.8ms (Warsaw)
- mad: 271.6ms (Madrid)
- tok: 273.2ms (Tokyo)
- syd: 319.9ms (Sydney)
- sin: 343.3ms (Singapore)
- sao: 358.9ms (São Paulo)
- blr: 381.1ms (Bangalore)
- nai: 390.9ms (Nairobi)
- dbi: 416.2ms (Dubai)
- jnb: 437.5ms (Johannesburg)
至此,即使打洞失败,也可以通过 DERP 转发来实现可接受范围内的延迟和带宽了。
正在加载评论……