Home
avatar

nax

Tailscale + 自建 DERP 中继服务器完整部署指南

目录


一、背景知识

什么是 Tailscale?

Tailscale 是基于 WireGuard 的零配置 VPN 组网工具,它允许你将分布在全球各地的设备(电脑、服务器、手机)组成一个虚拟局域网,设备之间可以像在同一网络中一样互相访问。

什么是 DERP?

当两个设备无法直接建立 P2P 连接时(如都在 NAT 后面),流量会通过 DERP(Designated Encrypted Relay for Packets)中继服务器转发。Tailscale 官方提供了全球多个 DERP 节点,但自建 DERP 可以:

  • 降低延迟:将 DERP 部署在离你设备最近的位置
  • 提高隐私:流量不经过第三方中继
  • 提高可用性:不受官方节点限制

架构示意

设备 A (Windows/Mac/Linux)

    ├── 直连 (P2P, WireGuard) ──── 设备 B

    └── 中继 (DERP) ──── 自建 DERP 服务器 ──── 设备 C

二、Tailscale 安装

2.1 Linux 服务器

# 一键安装
curl -fsSL https://tailscale.com/install.sh | sh

# 启动并登录
sudo tailscale up

# 查看状态
tailscale status

2.2 Windows

  1. 前往 Tailscale 官网 下载安装包
  2. 安装后在系统托盘中登录你的 Tailscale 账号

2.3 Android / iOS

在应用商店搜索 Tailscale 下载安装,登录同一账号即可。

2.4 验证安装

所有设备登录同一账号后,运行以下命令确认设备在线:

tailscale status

你应该看到所有设备列表,类似:

100.69.214.118  desktop    user@  windows  -
100.120.5.98    ali-hk     user@  linux    -
100.97.116.48   huawei-sg  user@  linux    -

三、自建 DERP 服务器

3.1 前提条件

条件说明
一台公网服务器推荐选择延迟低的区域(如香港、新加坡、日本)
域名需要一个域名并将子域名解析到服务器 IP
Docker服务器需要安装 Docker 和 Docker Compose
端口需要开放 80、443(TCP)和 3478(UDP)

3.2 域名解析

将子域名解析到 DERP 服务器的公网 IP,例如:

hk1.example.com  →  A 记录  →  你的服务器IP

3.3 安装 Docker

# 安装 Docker
curl -fsSL https://get.docker.com | sh

# 启动 Docker
systemctl enable docker && systemctl start docker

3.4 Tailscale 安装(DERP 服务器上)

DERP 服务器本身也需要安装 Tailscale,这是 verify-clients 功能所需要的:

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

3.5 部署 DERP 容器

创建部署目录和配置文件:

mkdir -p ~/derper && cd ~/derper

创建 docker-compose.yml

services:
  derper:
    image: fredliang/derper:latest
    container_name: derper
    restart: always
    network_mode: host
    volumes:
      # 挂载 Tailscale socket,用于客户端验证
      - /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock
      # 证书缓存目录(必须和 DERP_CERT_DIR 一致!)
      - ./certs:/app/certs
    environment:
      - DERP_DOMAIN=hk1.example.com        # ← 改成你的域名
      - DERP_ADDR=:443
      - DERP_HTTP_PORT=80
      - DERP_CERT_MODE=letsencrypt
      - DERP_CERT_DIR=/app/certs            # ← 必须和 volumes 挂载路径一致
      - DERP_VERIFY_CLIENTS=true            # 仅允许你自己的 Tailscale 网络成员使用
      - DERP_STUN=true
      - DERP_STUN_PORT=3478

启动容器:

docker compose up -d

⚠️ 关键提示volumes 中证书的挂载路径必须和 DERP_CERT_DIR 一致,都是 /app/certs。如果不匹配,Let’s Encrypt 获取的证书不会被持久化,每次重启都需要重新获取。

3.6 验证 DERP 服务

# 查看日志,确认正常启动
docker logs derper --tail 20

# 正常输出应该包含:
# STUN server listening on [::]:3478
# derper: serving on :443 with TLS

# 检查端口监听
ss -tlunp | grep -E '443|3478|80'

# 验证 HTTPS 证书(首次可能需要等待几十秒)
curl -v https://hk1.example.com/derp/probe
# 正常应返回:This is a Tailscale DERP server.

四、Tailscale 管理后台配置

4.1 配置自定义 DERP Map

打开 Tailscale Admin Console → Access Controls

在 ACL 配置的 JSON 中添加 derpMap 部分:

{
  // ... 其他 ACL 配置 ...

  "derpMap": {
    "OmitDefaultRegions": false,
    "Regions": {
      "900": {
        "RegionID": 900,
        "RegionCode": "hk",
        "RegionName": "Hong Kong Custom",
        "Nodes": [
          {
            "Name": "hk-1",
            "RegionID": 900,
            "HostName": "hk1.example.com",
            "DERPPort": 443,
            "STUNPort": 3478
          }
        ]
      }
    }
  }
}

参数说明:

参数说明
OmitDefaultRegionsfalse = 保留官方 DERP 节点作为备用,true = 只使用自建节点
RegionID自定义 ID,使用 900+ 避免与官方的冲突
HostName你的 DERP 服务器域名
DERPPortDERP 服务端口,默认 443
STUNPortSTUN 服务端口,默认 3478

💡 建议:排查问题时先将 OmitDefaultRegions 设为 false,等自建 DERP 稳定后再改为 true。如果设为 true 但自建 DERP 不可用,所有设备将完全无法中继通信

4.2 配置 DNS

打开 Tailscale Admin Console → DNS

建议配置:

  1. MagicDNS:开启(方便用主机名直接访问设备)
  2. Global Nameservers:添加公共 DNS
    • 8.8.8.8
    • 1.1.1.1

⚠️ 阿里云用户特别注意:阿里云内部 DNS 地址是 100.100.2.136 / 100.100.2.138,这些 IP 在 Tailscale 使用的 CGNAT 地址段 100.64.0.0/10 内,会被 Tailscale 拦截,导致 DNS 解析失败!必须添加公共 DNS 作为 Global Nameservers。

4.3 配置 ACL(访问控制)

确保 ACL 中允许设备互相通信:

{
  "acls": [
    {
      "action": "accept",
      "src": ["*"],
      "dst": ["*:*"]
    }
  ]
}

4.4 验证配置

在任一设备上运行:

# 查看 DERP Map 是否生效
tailscale debug derp-map

# 网络检查
tailscale netcheck

# 正常输出应包含你的自建 DERP:
# * Nearest DERP: Hong Kong Custom
# * DERP latency:
#     - hk: 30.2ms (Hong Kong Custom)

五、踩坑记录与排查指南

🔴 坑 1:云服务器安全组未放行端口

症状:服务器端口在监听(ss 显示正常),但从外网访问超时。

原因:阿里云、AWS、腾讯云等云平台的安全组(Security Group)默认只开放有限端口,需要手动添加入站规则。

解决:在云平台控制台的安全组中添加入站规则:

协议端口用途授权对象
TCP80Let’s Encrypt HTTP 验证0.0.0.0/0
TCP443DERP 中继 (TLS)0.0.0.0/0
UDP3478STUN NAT 穿透0.0.0.0/0

这是最常见的问题!如果 DERP 日志正常、端口在监听,但就是连不上,第一时间检查安全组


🔴 坑 2:证书目录挂载路径不匹配

症状:TLS 握手失败,/app/certs/ 目录为空,Let’s Encrypt 证书未成功获取或未持久化。

原因:Docker 的 volume 挂载路径和 derper 实际使用的 --certdir 不一致。

错误示例

volumes:
  - ./certs:/var/lib/derper    # ❌ 挂载到了 /var/lib/derper
# 但 derper 默认使用 --certdir=/app/certs

正确配置

volumes:
  - ./certs:/app/certs         # ✅ 和 DERP_CERT_DIR 一致
environment:
  - DERP_CERT_DIR=/app/certs   # ✅ 显式指定

🔴 坑 3:阿里云 DNS 与 Tailscale CGNAT 冲突

症状tailscale status 显示健康检查警告 Tailscale can't reach the configured DNS servers,服务器无法解析域名。

原因:阿里云内部 DNS(100.100.2.136)的 IP 地址落在 Tailscale 的 CGNAT 地址段 100.64.0.0/10(范围:100.64.0.0 - 100.127.255.255)内,Tailscale 会拦截发往这些地址的流量。

解决:在 Tailscale DNS 设置页 添加 Global Nameservers8.8.8.81.1.1.1


🟡 坑 4:OmitDefaultRegions: true 导致完全断连

症状:设备之间完全无法通信,tailscale ping 全部超时。

原因:如果禁用了所有官方 DERP 节点(OmitDefaultRegions: true),且自建 DERP 又不可用,设备之间无法建立任何中继连接。

解决:排查期间先设为 false,保留官方节点作为兜底。


🟡 坑 5:verify-clients 在 Docker 中不生效

症状:开启了 verify-clients 但任何人都能连接,或者所有人都被拒绝。

原因verify-clients 依赖 Tailscale 的 Unix socket 来验证客户端身份。Docker 容器中必须:

  1. 使用 network_mode: host
  2. 挂载 Tailscale socket:/var/run/tailscale/tailscaled.sock
  3. DERP 服务器本身安装并运行 Tailscale

六、常用诊断命令速查

Tailscale 状态检查

# 查看所有设备状态
tailscale status

# 网络连通性检查
tailscale netcheck

# 查看当前 DERP Map
tailscale debug derp-map

# Ping 指定设备(显示连接路径:直连 or DERP 中继)
tailscale ping <设备名或IP>

# 查看 Tailscale 偏好设置
tailscale debug prefs

DERP 服务器诊断

# 查看 DERP 容器日志
docker logs derper --tail 50

# 检查端口监听
ss -tlunp | grep -E '443|3478|80'

# 验证 TLS 和证书
curl -v https://你的域名/derp/probe

# 检查证书文件
docker exec derper ls -la /app/certs/

# 检查 Tailscale socket
ls -la /var/run/tailscale/tailscaled.sock

DNS 排查

# 查看系统 DNS 配置
cat /etc/resolv.conf

# 测试域名解析
ping 你的域名
curl -I https://acme-v02.api.letsencrypt.org/directory  # 测试能否访问 Let's Encrypt

端口连通性测试(从外部)

# Windows PowerShell
Test-NetConnection -ComputerName 你的服务器IP -Port 443
Test-NetConnection -ComputerName 你的服务器IP -Port 80
# Linux
nc -zv 你的服务器IP 443
nc -zv 你的服务器IP 80

附录:完整配置文件参考

docker-compose.yml

services:
  derper:
    image: fredliang/derper:latest
    container_name: derper
    restart: always
    network_mode: host
    volumes:
      - /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock
      - ./certs:/app/certs
    environment:
      - DERP_DOMAIN=hk1.example.com      # 你的域名
      - DERP_ADDR=:443
      - DERP_HTTP_PORT=80
      - DERP_CERT_MODE=letsencrypt
      - DERP_CERT_DIR=/app/certs
      - DERP_VERIFY_CLIENTS=true
      - DERP_STUN=true
      - DERP_STUN_PORT=3478

Tailscale ACL(含 DERP Map)

{
  "acls": [
    {
      "action": "accept",
      "src": ["*"],
      "dst": ["*:*"]
    }
  ],
  "derpMap": {
    "OmitDefaultRegions": false,
    "Regions": {
      "900": {
        "RegionID": 900,
        "RegionCode": "hk",
        "RegionName": "Hong Kong Custom",
        "Nodes": [
          {
            "Name": "hk-1",
            "RegionID": 900,
            "HostName": "hk1.example.com",
            "DERPPort": 443,
            "STUNPort": 3478
          }
        ]
      }
    }
  }
}

最后提醒:部署后记得用 tailscale netchecktailscale ping <设备名> 验证连通性。如果一切正常,你应该能看到流量通过自建 DERP 中继,延迟比官方节点更低 🎉

Tailscale DERP WireGuard VPN Docker