Tailscale 自建 DERP 中继服务器
DERP(Designated Encrypted Relay for Packets)是 Tailscale 的中继与连通性组件。它主要承担两件事:
- 协助节点打洞,尽量建立直连
- 直连失败时,作为中继节点转发流量
两条部署路线:
- Docker:上手快,依赖容器生态,换镜像即可升级
- 非 Docker:系统服务 + 二进制,更接近系统级运维,替换二进制即可升级
快速导航
根据你的操作系统和部署方式,按下表选择对应章节:
| 操作系统 | Docker 部署 | 非 Docker 部署 |
|---|---|---|
| Debian / Ubuntu | §3.1 | §4.1 |
| RHEL / CentOS / Rocky | §3.2 | §4.2 |
| Alpine | §3.3 | §4.3 |
完成部署后,所有路径统一执行:§5 ACL 配置 → §6 客户端重连 → §7 测试验收
1. 部署参数
文中使用占位符表示需要替换的参数。后续步骤中出现这些占位符时,请替换为你的实际值。
| 占位符 | 说明 | 示例值 |
|---|---|---|
<VPS_IP> |
VPS 公网 IP | xxx.xxx.xxx.xxx |
<DERP_TCP_PORT> |
DERP TCP 端口 | 13477 |
<STUN_UDP_PORT> |
STUN UDP 端口 | 13478 |
<REGION_ID> |
自定义 DERP 区域 ID | 900 |
<REGION_CODE> |
自定义 DERP 区域代码 | tyxy |
<RELAY_HOSTNAME> |
DERP 服务器的 Tailscale IP(通过 tailscale status 查看第一列) |
100.x.x.x |
如果你想先完整跑一遍,可把
<VPS_IP>、<DERP_TCP_PORT>、<STUN_UDP_PORT>先替换为xxx.xxx.xxx.xxx、13477、13478。
2. 通用准备工作
2.1 检查服务器资源与网络信息
free -m
df -h
ip addr show
2.2 放行安全组与防火墙端口
<DERP_TCP_PORT>/tcp:DERP 服务端口<STUN_UDP_PORT>/udp:STUN 服务端口
建议同时检查”云厂商安全组 + 系统防火墙”两层规则,避免本地通、外网不通。
3. Docker 部署
3.1 Debian / Ubuntu
安装 Docker 与 Compose
apt update
apt install -y docker.io docker-compose-plugin
systemctl enable --now docker
docker --version
docker compose version
可选:配置国内镜像加速
国内网络下拉取镜像较慢时可配置加速源,此配置写入后永久生效。
mkdir -p /etc/docker
cat > /etc/docker/daemon.json << 'EOF'
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://dockerproxy.com",
"https://docker.m.daocloud.io"
]
}
EOF
systemctl restart docker
低配置 VPS 可在
daemon.json中追加以下参数:{ "registry-mirrors": ["..."], "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" }, "max-concurrent-downloads": 2 }
log-opts:限制单个日志文件最大 10MB、最多保留 3 个,防止磁盘被日志撑满max-concurrent-downloads:限制同时下载层数为 2,降低内存和带宽占用
创建 docker-compose.yml
services:
derper:
image: ghcr.io/yangchuansheng/ip_derper
container_name: derper
restart: unless-stopped
ports:
- <DERP_TCP_PORT>:<DERP_TCP_PORT> # 替换为 DERP 端口,如 13477
- <STUN_UDP_PORT>:3478/udp # 替换为 STUN 端口,如 13478
environment:
- DERP_ADDR=:<DERP_TCP_PORT> # 替换为 DERP 端口,格式为 :<端口号>
- DERP_VERIFY_CLIENTS=true # 开启客户端验证,避免被公网滥用
volumes:
- /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock
- STUN 容器内部端口固定为
3478/udp,左边是主机映射端口
启动并验证
docker compose up -d
docker logs derper
ss -tulnp | grep -E "<DERP_TCP_PORT>|<STUN_UDP_PORT>" # 替换为实际端口号
安装 Tailscale 客户端
curl -fsSL https://tailscale.com/install.sh | sh
systemctl enable --now tailscaled
tailscale up
复制终端中的 https://login.tailscale.com/a/... 认证链接到浏览器完成登录,然后执行 tailscale status 确认状态。
3.2 RHEL / CentOS / Rocky / AlmaLinux
安装 Docker 与 Compose
dnf install -y docker docker-compose-plugin
systemctl enable --now docker
docker --version
docker compose version
可选:配置国内镜像加速
国内网络下拉取镜像较慢时可配置加速源,此配置写入后永久生效。
mkdir -p /etc/docker
cat > /etc/docker/daemon.json << 'EOF'
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://dockerproxy.com",
"https://docker.m.daocloud.io"
]
}
EOF
systemctl restart docker
低配置 VPS 可在
daemon.json中追加以下参数:{ "registry-mirrors": ["..."], "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" }, "max-concurrent-downloads": 2 }
log-opts:限制单个日志文件最大 10MB、最多保留 3 个,防止磁盘被日志撑满max-concurrent-downloads:限制同时下载层数为 2,降低内存和带宽占用
创建 docker-compose.yml
services:
derper:
image: ghcr.io/yangchuansheng/ip_derper
container_name: derper
restart: unless-stopped
ports:
- <DERP_TCP_PORT>:<DERP_TCP_PORT> # 替换为 DERP 端口,如 13477
- <STUN_UDP_PORT>:3478/udp # 替换为 STUN 端口,如 13478
environment:
- DERP_ADDR=:<DERP_TCP_PORT> # 替换为 DERP 端口,格式为 :<端口号>
- DERP_VERIFY_CLIENTS=true # 开启客户端验证,避免被公网滥用
volumes:
- /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock
- STUN 容器内部端口固定为
3478/udp,左边是主机映射端口
启动并验证
docker compose up -d
docker logs derper
ss -tulnp | grep -E "<DERP_TCP_PORT>|<STUN_UDP_PORT>" # 替换为实际端口号
安装 Tailscale 客户端
curl -fsSL https://tailscale.com/install.sh | sh
systemctl enable --now tailscaled
tailscale up
复制终端中的 https://login.tailscale.com/a/... 认证链接到浏览器完成登录,然后执行 tailscale status 确认状态。
3.3 Alpine
可选:使用国内镜像源
国内网络下 apk 拉取较慢时可切换阿里云镜像,此配置对后续所有 apk 操作生效:
# 备份原配置
cp /etc/apk/repositories /etc/apk/repositories.bak
# 使用阿里云镜像(版本号需与你的 Alpine 一致,通过 cat /etc/alpine-release 查看)
cat > /etc/apk/repositories << 'EOF'
https://mirrors.aliyun.com/alpine/v3.22/main
https://mirrors.aliyun.com/alpine/v3.22/community
EOF
apk update
安装 Docker 与 Compose
apk add docker docker-compose
rc-update add docker boot
service docker start
docker --version
docker-compose --version
提示:Alpine 下 Compose 通常是 V1(
docker-compose),如需 V2 可通过二进制安装docker-compose-plugin。
可选:配置国内镜像加速
国内网络下拉取镜像较慢时可配置加速源,此配置写入后永久生效。
mkdir -p /etc/docker
cat > /etc/docker/daemon.json << 'EOF'
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://dockerproxy.com",
"https://docker.m.daocloud.io"
]
}
EOF
service docker restart
低配置 VPS 可在
daemon.json中追加以下参数:{ "registry-mirrors": ["..."], "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" }, "max-concurrent-downloads": 2 }
log-opts:限制单个日志文件最大 10MB、最多保留 3 个,防止磁盘被日志撑满max-concurrent-downloads:限制同时下载层数为 2,降低内存和带宽占用
创建 docker-compose.yml
services:
derper:
image: ghcr.io/yangchuansheng/ip_derper
container_name: derper
restart: unless-stopped
ports:
- <DERP_TCP_PORT>:<DERP_TCP_PORT> # 替换为 DERP 端口,如 13477
- <STUN_UDP_PORT>:3478/udp # 替换为 STUN 端口,如 13478
environment:
- DERP_ADDR=:<DERP_TCP_PORT> # 替换为 DERP 端口,格式为 :<端口号>
- DERP_VERIFY_CLIENTS=true # 开启客户端验证,避免被公网滥用
volumes:
- /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock
- STUN 容器内部端口固定为
3478/udp,左边是主机映射端口
启动并验证
docker-compose up -d
docker logs derper
netstat -tulnp | grep -E "<DERP_TCP_PORT>|<STUN_UDP_PORT>" # 替换为实际端口号
安装 Tailscale 客户端
Alpine 不支持官方一键脚本(
curl -fsSL https://tailscale.com/install.sh | sh),必须通过apk安装。
确保 /etc/apk/repositories 包含 community 仓库(以 Alpine 3.19 为例):
http://dl-cdn.alpinelinux.org/alpine/v3.19/main
http://dl-cdn.alpinelinux.org/alpine/v3.19/community
若缺失可追加:
echo "http://dl-cdn.alpinelinux.org/alpine/v3.19/community" >> /etc/apk/repositories
安装并启动:
apk update
apk add tailscale
rc-update add tailscale default
rc-service tailscale start
tailscale up
复制终端中的 https://login.tailscale.com/a/... 认证链接到浏览器完成登录,然后执行 tailscale status 确认状态。
4. 非 Docker 部署
官方 Tailscale 包不包含
derper二进制,需从源码编译。
4.1 Debian / Ubuntu
系统准备
apt update
apt upgrade -y
apt install -y wget openssl curl netcat-openbsd
创建目录结构
mkdir -p /usr/local/derp/{bin,certs}
编译 derper
安装 Go 环境:
apt install -y golang
go version
大陆地区切换下载源(Go 1.13 及以上):
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
编译(内存 >= 2GB):
go install tailscale.com/cmd/derper@latest
cp ~/go/bin/derper /usr/local/derp/bin/
低内存 VPS 编译可能报 OOM,可改用 §4.4 异机交叉编译,完成后回到本节「验证编译结果」继续。
验证编译结果
chmod +x /usr/local/derp/bin/derper
# 验证是否为静态二进制
ldd /usr/local/derp/bin/derper # 应输出 "not a dynamic executable"
# 验证版本
/usr/local/derp/bin/derper --version
--version输出类似1.xx.x-ERR-BuildInfo是正常的(go install编译不含完整构建信息)。
如果遇到 Permission denied,可能是 /usr/local 被挂载为 noexec:
# 检查挂载选项
mount | grep /usr/local
# 如果存在 noexec,复制到其他位置运行
cp /usr/local/derp/bin/derper /root/derper
chmod +x /root/derper
/root/derper --version
确认可执行后,将二进制放回 /usr/local/derp/bin/ 或调整挂载选项。
生成自签名证书
关键点:证书文件名要与
-hostname对应,建议直接使用<VPS_IP>.crt与<VPS_IP>.key。
cd /usr/local/derp/certs
# 将下方所有 <VPS_IP> 替换为你的服务器公网 IP
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 \
-nodes -keyout <VPS_IP>.key -out <VPS_IP>.crt \
-subj "/CN=<VPS_IP>" \
-addext "subjectAltName=IP:<VPS_IP>"
-keyout <VPS_IP>.key:私钥输出文件,文件名需与-hostname一致-out <VPS_IP>.crt:证书输出文件,文件名需与-hostname一致-subj "/CN=<VPS_IP>":证书通用名称,设为服务器 IP-addext "subjectAltName=IP:<VPS_IP>":SAN 扩展,必须包含 IP-days 3650:有效期 10 年
创建 systemd 服务
cat > /etc/systemd/system/derper.service << 'EOF'
[Unit]
Description=Tailscale DERP Server
After=network.target
Wants=network.target
[Service]
User=root
Group=root
# 下方 <VPS_IP>、<DERP_TCP_PORT>、<STUN_UDP_PORT> 替换为实际值(参考 §1)
ExecStart=/usr/local/derp/bin/derper \
-certmode=manual \
-certdir=/usr/local/derp/certs \
-hostname=<VPS_IP> \
-a :<DERP_TCP_PORT> \
-stun-port=<STUN_UDP_PORT> \
-http-port=-1 \
--verify-clients
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
参数要点:
-certmode=manual:手动证书模式-http-port=-1:关闭 HTTP 端口--verify-clients:开启客户端验证Restart=on-failure+RestartSec=5:崩溃后自动重启
启动并验证
systemctl daemon-reload
systemctl enable derper
systemctl start derper
systemctl status derper
# 检查监听端口(替换为实际端口号)
ss -tulnp | grep -E "<DERP_TCP_PORT>|<STUN_UDP_PORT>"
# 本地 TCP 连通性(替换为 DERP 端口)
nc -zv 127.0.0.1 <DERP_TCP_PORT>
# 查看进程
ps aux | grep derper
# 启动失败可查看日志
journalctl -u derper --no-pager -n 30
预期输出:
tcp 0 0 :::<DERP_TCP_PORT> :::* LISTEN 1234/derper
udp 0 0 :::<STUN_UDP_PORT> :::* 1234/derper
如果缺少某一行,说明对应端口未监听成功,需检查服务日志。
安装 Tailscale 客户端
curl -fsSL https://tailscale.com/install.sh | sh
systemctl enable --now tailscaled
tailscale up
复制终端中的 https://login.tailscale.com/a/... 认证链接到浏览器完成登录,然后执行 tailscale status 确认状态。
4.2 RHEL / CentOS / Rocky / AlmaLinux
系统准备
dnf update -y
dnf install -y wget openssl curl nmap-ncat
创建目录结构
mkdir -p /usr/local/derp/{bin,certs}
编译 derper
安装 Go 环境:
dnf install -y golang
go version
大陆地区切换下载源(Go 1.13 及以上):
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
编译(内存 >= 2GB):
go install tailscale.com/cmd/derper@latest
cp ~/go/bin/derper /usr/local/derp/bin/
低内存 VPS 编译可能报 OOM,可改用 §4.4 异机交叉编译,完成后回到本节「验证编译结果」继续。
验证编译结果
chmod +x /usr/local/derp/bin/derper
# 验证是否为静态二进制
ldd /usr/local/derp/bin/derper # 应输出 "not a dynamic executable"
# 验证版本
/usr/local/derp/bin/derper --version
--version输出类似1.xx.x-ERR-BuildInfo是正常的(go install编译不含完整构建信息)。
如果遇到 Permission denied,可能是 /usr/local 被挂载为 noexec:
# 检查挂载选项
mount | grep /usr/local
# 如果存在 noexec,复制到其他位置运行
cp /usr/local/derp/bin/derper /root/derper
chmod +x /root/derper
/root/derper --version
确认可执行后,将二进制放回 /usr/local/derp/bin/ 或调整挂载选项。
生成自签名证书
关键点:证书文件名要与
-hostname对应,建议直接使用<VPS_IP>.crt与<VPS_IP>.key。
cd /usr/local/derp/certs
# 将下方所有 <VPS_IP> 替换为你的服务器公网 IP
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 \
-nodes -keyout <VPS_IP>.key -out <VPS_IP>.crt \
-subj "/CN=<VPS_IP>" \
-addext "subjectAltName=IP:<VPS_IP>"
-keyout <VPS_IP>.key:私钥输出文件,文件名需与-hostname一致-out <VPS_IP>.crt:证书输出文件,文件名需与-hostname一致-subj "/CN=<VPS_IP>":证书通用名称,设为服务器 IP-addext "subjectAltName=IP:<VPS_IP>":SAN 扩展,必须包含 IP-days 3650:有效期 10 年
创建 systemd 服务
cat > /etc/systemd/system/derper.service << 'EOF'
[Unit]
Description=Tailscale DERP Server
After=network.target
Wants=network.target
[Service]
User=root
Group=root
# 下方 <VPS_IP>、<DERP_TCP_PORT>、<STUN_UDP_PORT> 替换为实际值(参考 §1)
ExecStart=/usr/local/derp/bin/derper \
-certmode=manual \
-certdir=/usr/local/derp/certs \
-hostname=<VPS_IP> \
-a :<DERP_TCP_PORT> \
-stun-port=<STUN_UDP_PORT> \
-http-port=-1 \
--verify-clients
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
参数要点:
-certmode=manual:手动证书模式-http-port=-1:关闭 HTTP 端口--verify-clients:开启客户端验证Restart=on-failure+RestartSec=5:崩溃后自动重启
启动并验证
systemctl daemon-reload
systemctl enable derper
systemctl start derper
systemctl status derper
# 检查监听端口(替换为实际端口号)
ss -tulnp | grep -E "<DERP_TCP_PORT>|<STUN_UDP_PORT>"
# 本地 TCP 连通性(替换为 DERP 端口)
nc -zv 127.0.0.1 <DERP_TCP_PORT>
# 查看进程
ps aux | grep derper
# 启动失败可查看日志
journalctl -u derper --no-pager -n 30
预期输出:
tcp 0 0 :::<DERP_TCP_PORT> :::* LISTEN 1234/derper
udp 0 0 :::<STUN_UDP_PORT> :::* 1234/derper
如果缺少某一行,说明对应端口未监听成功,需检查服务日志。
安装 Tailscale 客户端
curl -fsSL https://tailscale.com/install.sh | sh
systemctl enable --now tailscaled
tailscale up
复制终端中的 https://login.tailscale.com/a/... 认证链接到浏览器完成登录,然后执行 tailscale status 确认状态。
4.3 Alpine
可选:使用国内镜像源
国内网络下 apk 拉取较慢时可切换阿里云镜像,此配置对后续所有 apk 操作生效:
# 备份原配置
cp /etc/apk/repositories /etc/apk/repositories.bak
# 使用阿里云镜像(版本号需与你的 Alpine 一致,通过 cat /etc/alpine-release 查看)
cat > /etc/apk/repositories << 'EOF'
https://mirrors.aliyun.com/alpine/v3.22/main
https://mirrors.aliyun.com/alpine/v3.22/community
EOF
apk update
系统准备
apk update
apk upgrade
apk add wget openssl curl netcat-openbsd
创建目录结构
mkdir -p /usr/local/derp/bin /usr/local/derp/certs
编译 derper
安装 Go 环境:
apk add go
go version
大陆地区切换下载源(Go 1.13 及以上):
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
编译(内存 >= 2GB):
go install tailscale.com/cmd/derper@latest
cp ~/go/bin/derper /usr/local/derp/bin/
低内存 VPS 编译可能报 OOM,可改用 §4.4 异机交叉编译,完成后回到本节「验证编译结果」继续。
验证编译结果
chmod +x /usr/local/derp/bin/derper
# 验证是否为静态二进制
ldd /usr/local/derp/bin/derper # 应输出 "not a dynamic executable"
# 验证版本
/usr/local/derp/bin/derper --version
--version输出类似1.xx.x-ERR-BuildInfo是正常的(go install编译不含完整构建信息)。
如果遇到 Permission denied,可能是 /usr/local 被挂载为 noexec:
# 检查挂载选项
mount | grep /usr/local
# 如果存在 noexec,复制到其他位置运行
cp /usr/local/derp/bin/derper /root/derper
chmod +x /root/derper
/root/derper --version
确认可执行后,将二进制放回 /usr/local/derp/bin/ 或调整挂载选项。
生成自签名证书
关键点:证书文件名要与
-hostname对应,建议直接使用<VPS_IP>.crt与<VPS_IP>.key。
cd /usr/local/derp/certs
# 将下方所有 <VPS_IP> 替换为你的服务器公网 IP
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 \
-nodes -keyout <VPS_IP>.key -out <VPS_IP>.crt \
-subj "/CN=<VPS_IP>" \
-addext "subjectAltName=IP:<VPS_IP>"
-keyout <VPS_IP>.key:私钥输出文件,文件名需与-hostname一致-out <VPS_IP>.crt:证书输出文件,文件名需与-hostname一致-subj "/CN=<VPS_IP>":证书通用名称,设为服务器 IP-addext "subjectAltName=IP:<VPS_IP>":SAN 扩展,必须包含 IP-days 3650:有效期 10 年
创建 OpenRC 服务
cat > /etc/init.d/derper << 'EOF'
#!/sbin/openrc-run
description="Tailscale DERP Server"
command="/usr/local/derp/bin/derper"
# 下方 <VPS_IP>、<DERP_TCP_PORT>、<STUN_UDP_PORT> 替换为实际值(参考 §1)
command_args="-certmode=manual -certdir=/usr/local/derp/certs -hostname=<VPS_IP> -a :<DERP_TCP_PORT> -stun-port=<STUN_UDP_PORT> -http-port=-1 --verify-clients"
command_user="root:root"
supervisor=supervise-daemon
respawn_delay=5
respawn_max=0
depend() {
need net
after firewall
}
EOF
参数要点:
-certmode=manual:手动证书模式-http-port=-1:关闭 HTTP 端口--verify-clients:开启客户端验证supervisor=supervise-daemon+respawn_delay=5:崩溃后自动重启(等效 systemd 的Restart=on-failure)
启动并验证
chmod +x /etc/init.d/derper
rc-update add derper default
rc-service derper start
rc-service derper status
# 检查监听端口(替换为实际端口号)
netstat -tulnp | grep -E "<DERP_TCP_PORT>|<STUN_UDP_PORT>"
# 本地 TCP 连通性(替换为 DERP 端口)
nc -zv 127.0.0.1 <DERP_TCP_PORT>
# 查看进程
ps aux | grep derper
# 启动失败可看内核日志
dmesg | tail -20
预期输出:
tcp 0 0 :::<DERP_TCP_PORT> :::* LISTEN 1234/derper
udp 0 0 :::<STUN_UDP_PORT> :::* 1234/derper
如果缺少某一行,说明对应端口未监听成功,需检查服务日志。
安装 Tailscale 客户端
Alpine 不支持官方一键脚本(
curl -fsSL https://tailscale.com/install.sh | sh),必须通过apk安装。
确保 /etc/apk/repositories 包含 community 仓库(以 Alpine 3.19 为例):
http://dl-cdn.alpinelinux.org/alpine/v3.19/main
http://dl-cdn.alpinelinux.org/alpine/v3.19/community
若缺失可追加:
echo "http://dl-cdn.alpinelinux.org/alpine/v3.19/community" >> /etc/apk/repositories
安装并启动:
apk update
apk add tailscale
rc-update add tailscale default
rc-service tailscale start
tailscale up
复制终端中的 https://login.tailscale.com/a/... 认证链接到浏览器完成登录,然后执行 tailscale status 确认状态。
4.4 附:异机交叉编译(低内存 VPS)
VPS 内存不足 2GB 编译会 OOM,可在其他机器编译后上传。
# 1) 准备 Go 环境(版本建议 >= 1.21)
go version
# 2) 大陆地区切换下载源
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
# 3) 设定目标平台(示例:Linux AMD64)
export GOOS=linux
export GOARCH=amd64 # ARM64 改为 arm64
export CGO_ENABLED=0
# 4) 构建 derper
go install tailscale.com/cmd/derper@latest
ls ~/go/bin/derper
# 5) 在 VPS 上创建目录(替换 <VPS_IP> 为服务器公网 IP)
ssh root@<VPS_IP> "mkdir -p /usr/local/derp/bin /usr/local/derp/certs"
# 6) 上传到 VPS
scp ~/go/bin/derper root@<VPS_IP>:/usr/local/derp/bin/
# 7) 在 VPS 上验证
ssh root@<VPS_IP>
chmod +x /usr/local/derp/bin/derper
ldd /usr/local/derp/bin/derper # 应输出 "not a dynamic executable"
/usr/local/derp/bin/derper --version
编译参数说明:
CGO_ENABLED=0:生成纯静态二进制,降低运行环境依赖GOOS/GOARCH:目标操作系统和架构
上传并验证通过后,回到对应操作系统章节(§4.1 / §4.2 / §4.3),从「验证编译结果」步骤继续完成证书、服务配置与 Tailscale 安装。
5. 配置 ACL(derpMap)
进入 Tailscale 管理后台 Access controls 的 JSON 编辑器,把下列 derpMap 合并到现有 ACL(不要覆盖其他配置项)。
将以下 JSON 中的
<REGION_ID>、<REGION_CODE>、<VPS_IP>、<DERP_TCP_PORT>、<STUN_UDP_PORT>替换为你的实际值(参考 §1)。
{
"derpMap": {
"OmitDefaultRegions": false, // 保留官方 DERP 作为兜底
"Regions": {
"<REGION_ID>": {
"RegionID": <REGION_ID>, // 自定义区域 ID,建议 900 及以上
"RegionCode": "<REGION_CODE>", // 自定义区域代码
"RegionName": "Custom DERP",
"Nodes": [
{
"Name": "myderper",
"RegionID": <REGION_ID>,
"HostName": "<VPS_IP>", // 必须与证书和 -hostname 一致
"DERPPort": <DERP_TCP_PORT>, // 必须与服务监听端口一致
"STUNPort": <STUN_UDP_PORT>, // 必须与 STUN 监听端口一致
"CanPort80": false,
"InsecureForTests": true // IP + 自签证书场景必须开启
}
]
}
}
}
}
Tailscale ACL 编辑器支持 HuJSON 格式,
//注释可直接保留,无需删除。
常见坑:
- JSON 尾逗号导致保存失败
- ACL 端口与服务监听端口不一致
HostName与证书 SAN 不一致
6. 客户端重连与配置下发
ACL 保存后,建议客户端重连一次,确保拉取新配置:
# Debian / Ubuntu / RHEL / CentOS(systemd)
systemctl restart tailscaled
# Alpine(OpenRC)
rc-service tailscale restart
# 或通用方式(所有系统)
tailscale down
tailscale up
建议等待 1-2 分钟后再跑连通性测试。
6.1 启用 Peer Relay 与 Exit Node(可选)
如果你希望 DERP 节点同时作为 Peer Relay 和 Exit Node 使用:
启用 Peer Relay
Peer Relay 目前处于 Beta 阶段,需要 Tailscale 1.86+。它允许 tailnet 内的设备充当高吞吐中继,直连失败时优先走 Peer Relay,再回退到 DERP。适用于严格 NAT 环境下的大文件传输、高清流媒体等场景。
第一步:在中继设备上开启 Peer Relay
# 确认版本 >= 1.86
tailscale version
# 启用 Peer Relay,指定 UDP 端口
tailscale set --relay-server-port=40000
确保防火墙和云安全组放行该 UDP 端口(如 40000/udp),否则其他设备无法通过 Peer Relay 连接。
第二步:在 ACL 中添加 grant 策略
仅开启端口不够,还必须在 Tailscale 管理后台的 Access controls 中添加 Peer Relay 的 grants 策略。
先查询 DERP 服务器的 Tailscale IP:
tailscale status
输出中第一列 100.x.x.x 即为 Tailscale IP。
在现有 ACL 的 grants 数组中追加 Peer Relay 条目(grants 支持多条共存)。以下是包含基础网络访问和 Peer Relay 的完整示例,将 <RELAY_HOSTNAME> 替换为 DERP 服务器的 Tailscale IP:
{
"grants": [
{
"src": ["*"],
"dst": ["*"],
"ip": ["*"] // 基础网络访问,允许所有设备互通
},
{
"src": ["*"],
"dst": ["<RELAY_HOSTNAME>"], // 替换为 DERP 服务器的 Tailscale IP
"app": {
"tailscale.com/cap/relay": [] // relay 能力,无需额外参数
}
}
],
"acls": [
{
"action": "accept",
"src": ["*"],
"dst": ["*:*"] // 允许所有流量通过
}
]
}
注意:Tailscale ACL 默认拒绝所有流量。如果你的 ACL 中没有
acls规则或网络访问 grant(第一条"ip": ["*"]),设备之间将无法通信,Peer Relay 也不会生效。上方示例中两者都保留以确保正常工作。如果你已有自己的
acls和grants配置,只需将第二条 Peer Relay grant 追加到现有grants数组末尾即可。
dst:必须替换<RELAY_HOSTNAME>为 DERP 服务器的 Tailscale IPtailscale.com/cap/relay:必须的 relay 能力声明
多台 Peer Relay 场景:如果你有多台 Peer Relay 或想精细控制,可改用标签。详见 Tailscale Peer Relays 文档。
第三步:验证
# 生成流量后查看状态
tailscale status | grep peer-relay
# 或用 ping 测试
tailscale ping <对端设备>
当连接走 Peer Relay 时,tailscale status 会显示 peer-relay 而非 direct 或 relay。
禁用 Peer Relay
tailscale set --relay-server-port=""
启用 Exit Node
Linux 必须先开启 IP 转发才能作为 Exit Node:
# 如果系统存在 /etc/sysctl.d/ 目录(推荐)
echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf
# 否则使用 /etc/sysctl.conf
echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p /etc/sysctl.conf
如果使用 firewalld,需额外允许 masquerade:
firewall-cmd --permanent --add-masquerade开启 IP 转发后,请确认防火墙默认拒绝转发流量(
ufw、firewalld默认如此),避免意外路由不相关流量。
广播 Exit Node 并启用路由接受:
sudo tailscale set --advertise-exit-node
sudo tailscale up --accept-routes
最后到 Tailscale 管理后台批准 Exit Node:
- 打开 Machines 页面,找到该设备
- 点击设备右侧
...菜单 → Edit route settings - 启用 Use as exit node
如果该设备的用户已在 ACL
autoApprovers中配置了 Exit Node 权限,则会自动批准,无需手动操作。
6.2 网络性能优化(可选)
启用 UDP GRO forwarding 和关闭 GRO list 可提升 Tailscale 的网络吞吐:
# 启用 UDP GRO forwarding
ethtool -K eth0 rx-udp-gro-forwarding on
# 启用 UDP segmentation offload
ethtool -K eth0 rx-gro-list off
# 检查设置
ethtool -k eth0 | grep gro
如果提示
ethtool: command not found:# Alpine apk add ethtool # Debian / Ubuntu apt install -y ethtool # RHEL / CentOS / Rocky dnf install -y ethtool
7. 测试与验收
7.1 快速测试命令
# 网络能力检查(UDP / DERP)
tailscale netcheck
# 设备与对等节点状态
tailscale status
# 结构化状态(便于排障与留档)
tailscale status --json
7.2 tailscale netcheck 关注点
UDP: true:UDP 通信正常Nearest DERP:应接近你设置的自定义区域DERP latency:自建节点延迟越低越好
7.3 tailscale status 关注点
- 本机是否
active - 对等节点是否可见
- 连接路径是否出现
relay "<REGION_CODE>"或direct ...
7.4 示例输出解读
不同版本输出可能略有差异,重点看判读思路。
示例 1:tailscale netcheck
Report:
* UDP: true
* IPv4: yes, 203.0.113.24:41641
* IPv6: no, but OS has support
* MappingVariesByDestIP: false
* HairPinning: false
* Nearest DERP: tyxy
* DERP latency:
- tyxy: 18.2ms
- tok: 62.4ms
解读要点:
UDP: true:STUN 打洞能力正常Nearest DERP: tyxy:客户端已命中自定义区域MappingVariesByDestIP: false:通常表示 NAT 映射更稳定
示例 2:tailscale status
100.64.0.2 vps-derp linux active; direct 198.51.100.10:41641, tx 12 rx 20
100.64.0.8 laptop windows active; relay "tyxy", tx 3 rx 6
解读要点:
active; direct ...:当前直连active; relay "tyxy":当前走 DERP 中继,区域为tyxy- 如果长期全部
relay,继续排查 NAT/防火墙/端口策略
8. 常见问题与排查
8.1 编译时报 OOM
症状:fatal error: runtime: out of memory 或 signal: killed。
处理:使用 §4.4 异机交叉编译、或临时加 swap。
8.2 Permission denied 执行 derper
症状:chmod +x 后仍报 Permission denied。
原因:/usr/local 可能被挂载为 noexec。
mount | grep /usr/local
处理:复制到其他位置运行,或重新挂载去掉 noexec:
cp /usr/local/derp/bin/derper /root/derper
chmod +x /root/derper
/root/derper --version
8.3 端口冲突(address already in use)
# systemd 系统(替换为实际端口号)
ss -tulnp | grep -E "<DERP_TCP_PORT>|<STUN_UDP_PORT>"
# Alpine(替换为实际端口号)
netstat -tulnp | grep -E "<DERP_TCP_PORT>|<STUN_UDP_PORT>"
处理:停止冲突进程或更换端口,并同步修改服务参数和 ACL。
8.4 看不到自定义 DERP(证书/hostname 问题)
ls -la /usr/local/derp/certs/
# 替换 <VPS_IP> 为实际 IP
openssl x509 -in /usr/local/derp/certs/<VPS_IP>.crt -text -noout | grep -E "Subject:|IP Address"
# 检查服务配置中的 hostname
grep hostname /etc/systemd/system/derper.service # systemd 系统
grep hostname /etc/init.d/derper # Alpine (OpenRC)
处理:确认证书文件名、SAN IP、-hostname 三者一致。
8.5 本地通、外网不通(防火墙问题)
# 本地测试(替换为 DERP 端口)
nc -zv 127.0.0.1 <DERP_TCP_PORT>
# 从外部机器测试(替换为实际 IP 和端口)
nc -zv <VPS_IP> <DERP_TCP_PORT>
处理:重点检查云安全组与系统防火墙规则。
8.6 ACL 配置未生效
处理顺序:
- 检查 JSON 语法(尤其尾逗号)
- 等待 1-2 分钟同步
- 客户端重连:
tailscale down && tailscale up - 再执行
tailscale netcheck
8.7 服务脚本问题
systemd(Debian/Ubuntu/RHEL/CentOS):
症状:Failed to start derper.service 或 status=203/EXEC。
处理:检查 ExecStart 路径是否正确、二进制是否有执行权限,修改后执行 systemctl daemon-reload。
OpenRC(Alpine):
症状:syntax error: unterminated quoted string。
处理:删除后用 cat << 'EOF' 方式重建,避免手工改引号。
9. 总结
关键要点:
- Docker 上手快,非 Docker 更接近系统级运维,按需选择
- IP 场景下,自签证书 +
InsecureForTests: true通常是成套配置 HostName、证书 SAN、监听端口、ACL 端口必须全链路一致- 配置完成后务必重连客户端,并用
netcheck/status做验收
至此,你可以在 Debian/Ubuntu、RHEL/CentOS、Alpine 等主流发行版上,按本文的独立指南完成 DERP 的部署、验证与排障。