https://github.com/juanfont/headscale

部署一个完整的 Headscale 环境(包括自建 DERP 中继服务器)是实现私有虚拟内网的最佳方案。Headscale 作为 Tailscale 控制端的开源实现,能让你完全掌控网络节点和数据。

以下是为您准备的详细部署手册。


一、 准备工作

在开始之前,请确保你拥有以下资源:

  1. 一台公网 Linux 服务器:建议使用 Ubuntu 22.04 或 Debian 11/12。
  2. 一个域名:用于 Headscale 访问以及 DERP 的 SSL 证书申请(如 hs.example.com)。
  3. 开放端口:
  4. 80/tcp, 443/tcp:用于 Web 服务和证书申请。
  5. 8080/tcp:Headscale 默认 API 端口。
  6. 3478/udp:STUN 服务(用于 NAT 打洞)。
  7. DERP 端口(通常映射在 443 或自定义):用于流量转发。

二、 架构设计

  • Headscale Server:核心控制面,管理节点、分配 IP、同步状态。
  • DERP Server:当中继节点无法实现 P2P 直接连接时,流量通过 DERP 转发。
  • Reverse Proxy (Caddy/Nginx):负责处理 HTTPS 证书和请求转发。

三、 部署步骤(推荐 Docker Compose 方式)

使用 Docker 部署是最简单且易于维护的方式。

1. 安装 Docker

确保服务器已安装 Docker 和 Docker Compose。

2. 创建目录结构

mkdir -p /opt/headscale/config
cd /opt/headscale
touch config/config.yaml
touch docker-compose.yaml

3. 配置 Headscale (config.yaml)

从 Headscale 官方仓库 下载示例配置,主要修改以下几项:

  • server_url: https://hs.example.com
  • dns_config: 设置私有 DNS 或公共 DNS(如 Google/Cloudflare)。
  • derp: 稍后配置自建 DERP。

4. 编写 docker-compose.yaml

建议配合 Caddy 使用,因为它能自动申请 SSL 证书。

version: '3'
services:
  headscale:
    image: headscale/headscale:latest
    container_name: headscale
    volumes:
      - ./config:/etc/headscale
      - ./data:/var/lib/headscale
    ports:
      - "8080:8080"
    command: headscale serve
    restart: always

  headscale-ui: # 可选:图形化界面
    image: ghcr.io/gurucomputing/headscale-ui:latest
    restart: always

  caddy:
    image: caddy:latest
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
    environment:
      - DOMAIN=hs.example.com

volumes:
  caddy_data:

四、 部署 DERP 中继服务器

DERP 是提升连接成功率的关键。Headscale 可以内置 DERP,但为了性能,通常建议单独部署或配置专属节点。

关键配置

在 config.yaml 的 derp 部分:

  1. 禁用官方 DERP(可选):如果你追求极致私密。
  2. 添加自定义路径:指向一个包含 DERP 节点信息的 JSON 文件。

DERP 节点配置示例 (derp.json):

{
  "Regions": {
    "901": {
      "RegionID": 901,
      "RegionCode": "my-derp",
      "Nodes": [
        {
          "Name": "1a",
          "RegionID": 901,
          "HostName": "hs.example.com",
          "IPv4": "你的服务器IP",
          "STUNPort": 3478,
          "DERPPort": 443
        }
      ]
    }
  }
}

五、 客户端连接流程

1. 创建命名空间(User)

在服务端执行:

docker exec headscale headscale users create myuser

2. 客户端登录 (Windows/macOS/Linux)

使用以下命令指定你的控制端:

tailscale up --login-server https://hs.example.com

3. 服务端认证

客户端会给出一个链接,复制该链接中的 Key,在服务器上执行:

docker exec headscale headscale nodes register --user myuser --key <NODE_KEY>

六、 注意事项与避坑指南

  1. HTTPS 必须配置:Tailscale 客户端强制要求控制端使用 HTTPS。
  2. STUN 端口 (3478 UDP):一定要在防火墙放行。如果没有 STUN,节点将无法发现彼此的公网 IP,只能走中继,速度会很慢。
  3. 持久化数据:务必挂载 /var/lib/headscale,否则重启后所有节点信息和密钥都会丢失。
  4. 打洞原理:Headscale 只是“媒婆”,负责交换节点信息。真正的流量尽可能在节点间点对点传输,只有失败时才走 DERP。
  5. 安全建议:
  6. 定期备份 db.sqlite 文件。
  7. 如果使用图形界面(Headscale-UI),务必给 UI 设置强密码或通过 Caddy 配置 Basic Auth。