准备工作
- 服务器:一台具有公网 ip 的服务器,离客户端地区最近优先
- 域名:一个解析到服务器的域名,例如
dp.example.com
- 防火墙配置:确保所需要的端口防火墙已放开,如
3477/tcp 和 3478/udp
Docker 部署
安装 Docker
1
| curl -fsSL https://get.docker.com | bash -s docker
|
创建 Docker Compose 配置
创建工作目录并编写 docker-compose.yml
1 2
| mkdir -p /opt/derper cd /opt/derper
|
创建 docker-compose.yml 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| services: derper: image: fredliang/derper:latest container_name: derper restart: always ports: - "3477:3477" - "3478:3478/udp" environment: - DERP_DOMAIN=dp.example.com # 替换为你的域名 - DERP_CERT_MODE=manual # 使用手动证书 - DERP_ADDR=:3477 # DERP 服务端口 - DERP_STUN_PORT=3478 # STUN 端口 - DERP_VERIFY_CLIENTS=true # 启用客户端验证 volumes: # 启用客户端验证需映射 - /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock # 挂载证书目录到容器内部(手动存放证书) - ./certs:/app/certs
# ------------------------------------------------------- # 自动挂载 NPM 的证书文件,根据需要选择 # 注意:这里使用 NPM 申请的泛域名证书,当 NPM 自动续签证书后只需要重启 derper 容器即可 # 注意:请将映射路径替换为 NPM 下泛域名证书的真实路径 # ------------------------------------------------------- # 映射公钥 (fullchain.pem -> dp.example.com.crt) - /opt/nginx-proxy-manager/letsencrypt/live/npm-1/fullchain.pem:/app/certs/dp.example.com.crt:ro # 映射私钥 (privkey.pem -> dp.example.com.key) - /opt/nginx-proxy-manager/letsencrypt/live/npm-1/privkey.pem:/app/certs/dp.example.com.key:ro
|
证书管理
自动申请证书
使用标准的 80/443 端口,Derper 可以自动申请和续期 Let’s Encrypt 证书
docker-compose.yml 文件:
1 2 3 4
| environment: - DERP_CERT_MODE=letsencrypt - DERP_ADDR=:443 - DERP_HTTP_PORT=80
|
手动管理证书
使用自定义端口或已有证书,需要手动管理证书,证书放置在 ./certs 目录下,并且证书文件命名符合规则,例如:
derper.example.com.crt 和 derper.example.com.key
客户端验证
启用客户端验证功能可以防止自建的 Derper 服务器被白嫖,只有在同一个 Tailscale 网络中的设备才能使用。
安装 Tailscale 客户端
在 Derper 服务器上安装 Tailscale 客户端:
1 2 3 4 5
| # 安装 Tailscale curl -fsSL https://tailscale.com/install.sh | sh
# 启动并加入网络 sudo tailscale up
|
启用验证
docker-compose.yml 文件:
1 2 3 4
| environment: - DERP_VERIFY_CLIENTS=true volumes: - /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock
|
Tailscale 配置
登录 Tailscale Admin Console
进入 Access Controls 中选择 JSON 格式添加自定义 DERP 配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| { // ... 其他配置 ...
"derpMap": { "OmitDefaultRegions": false, // 是否忽略官方节点,建议 false,仅作补充 "Regions": { "900": { // RegionID,建议选 900-999 之间的数字 "RegionID": 900, "RegionCode": "myderp", "RegionName": "Custom Derper", "Nodes": [ { "Name": "900a", "RegionID": 900, "HostName": "derper.example.com", // 你的域名 "DERPPort": 3477, // 如使用自定义端口,修改此处 "STUNPort": 3478, // 如使用自定义端口,修改此处 "STUNOnly": false } ] } } } }
|
最终测试
在任意一台连接了 Tailscale 的客户端上(例如你的 PC),运行命令:
查看输出结果,类似如下输出说明配置成功:
1 2 3 4 5 6 7 8 9 10 11
| Report: * Time: 2026-04-08T14:46:58.941345Z * UDP: true * IPv4: yes, 120.235.250.104:52940 * IPv6: no, but OS has support * MappingVariesByDestIP: * PortMapping: UPnP, NAT-PMP * CaptivePortal: false * Nearest DERP: Custom Derper * DERP latency: - myderp: 20.2ms (Custom Derper)
|
可选配置
我的服务器项目一般都是通过 NginxProxyManager 进行反代,并且配置了泛域名证书,这里为了方便,直接挂载 NPM 的泛域名证书,按需选择
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| services: derper: image: fredliang/derper:latest container_name: derper restart: always ports: - "3477:3477" - "3478:3478/udp" environment: - DERP_DOMAIN=dp.example.com # 替换为你的域名 - DERP_CERT_MODE=manual # 使用手动证书 - DERP_ADDR=:3477 # DERP 服务端口 - DERP_STUN_PORT=3478 # STUN 端口 - DERP_VERIFY_CLIENTS=true # 启用客户端验证 volumes: # 启用客户端验证需映射 - /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock # 映射公钥 (fullchain.pem -> dp.example.com.crt) - /opt/nginx-proxy-manager/letsencrypt/live/npm-1/fullchain.pem:/app/certs/dp.example.com.crt:ro # 映射私钥 (privkey.pem -> dp.example.com.key) - /opt/nginx-proxy-manager/letsencrypt/live/npm-1/privkey.pem:/app/certs/dp.example.com.key:ro
|
注意:当 NPM 自动续签证书后需要重启 Derper 容器后才能完成更新