2026 全能版企业级私有组网实战系列教程(Headscale + Tailscale + DERP)更新中……

2026 全能版企业级私有组网实战系列教程(Headscale + Tailscale + DERP)更新中……

第一章:架构与环境准备 (Infrastructure & Preparation)

1.1、安装 Docker Engine (官方推荐方式)

不要使用 apt install docker.io,为了 2026 年的兼容性,我们直接上 Docker 官方源。

Bash
# 1. 更新系统索引并安装基础依赖
apt-get update && apt-get install -y curl vim git

# 2. 使用官方一键安装脚本 (这是 2026 年最稳健的姿势)
curl -fsSL https://get.docker.com | sh

# 3. 检查 Docker 状态
# 预期输出应包含 Docker version 2x.x.x 以及 Docker Compose version v2.x.x
docker --version && docker compose version

1.2、开启内核 IP 转发

这是组网的“灵魂”,必须永久生效。

Bash
# 临时开启
sudo sysctl -w net.ipv4.ip_forward=1

# 永久开启
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

1.3、部署流量闸门 (Nginx Proxy Manager)

我们先建立一个专门的目录来存放所有的组网容器配置。

1.3.1、建立工作目录

Bash
mkdir -p /root/iot-architect/network
cd /root/iot-architect/network
mkdir -p ~/iot-architect/network/headscale/config
mkdir -p ~/iot-architect/network/headscale/data
mkdir -p ~/iot-architect/network/npm/data
mkdir -p ~/iot-architect/network/npm/letsencrypt

1.3.2、编写 docker-compose.yml

我们将 NPM 放在这里,它是所有流量的入口。

YAML
cat <<'EOF' > ~/iot-architect/network/docker-compose.yml
services:
  npm:
    image: 'jc21/nginx-proxy-manager:latest'
    container_name: npm
    restart: unless-stopped
    ports:
      - '80:80'
      - '81:81' # 管理后台端口
      - '443:443'
    volumes:
      - ./npm/data:/data
      - ./npm/letsencrypt:/etc/letsencrypt
    networks:
      - headscale-net

networks:
  headscale-net:
    name: headscale-net
EOF

1.3.3、启动服务

Bash
docker compose up -d

1.3.4、 基础环境对齐检查 (Verification)

在继续之前,请确认以下状态:

  1. 访问管理后台: 在浏览器打开 http://你的服务器IP:81
    • 默认账号:admin@your-domain.com
    • 默认密码:password
  2. 准备域名: 既然你有 your-domain.com,我建议为主线教程预留三个子域名:
    • hs.your-domain.com (用于 Headscale 控制面)
    • hs-ui.your-domain.com (用于 Headscale Web控制)
    • derp.your-domain.com (用于 DERP 中继节点)

第二章:核心控制面——Headscale 容器化部署

2.1、部署 Headscale 核心服务

Headscale 是整个组网的“大脑”,它负责分发密钥和管理节点。

2.1.1、准备配置目录

/root/iot-architect/network 目录下创建 headscale 专属配置空间:

Bash
mkdir -p ./headscale/config
# 创建一个空的数据库文件,防止容器启动时因权限或文件缺失报错
touch ./headscale/data/db.sqlite

2.2.2、初始化 config.yaml

./headscale/config/ 目录下创建 config.yaml

脱敏提示: 教程中请将 your-domain.com 替换为您实际在 Cloudflare 解析好的域名(如 hs.your-domain.com)。

YAML
cat <<'EOF' > ~/iot-architect/network/headscale/config/config.yaml
# --- Headscale 2026 核心配置文件 (全栈兼容生产版) ---

# [基础设置]
# 客户端连接的外部地址。虽然容器内监听 8080,但外部通过 NPM 反代 443 接入。
server_url: https://hs.your-domain.com

# 服务监听地址。使用 "[::]" 可同时绑定 IPv4 和 IPv6 所有的物理网卡。
listen_addr: "[::]:8080"

# 指标监控与调试地址。用于 Prometheus 监控容器运行状态。
metrics_listen_addr: "[::]:9090"

# gRPC 监听地址。用于 Headscale 远程管理,必须配合证书使用。
grpc_listen_addr: "[::]:50443"
grpc_allow_insecure: false

# [安全协议]
# 噪声协议 (TS2021) 密钥路径,容器启动时会自动生成密钥文件。
noise:
  private_key_path: /var/lib/headscale/noise_private.key

# [内网 IP 分配]
# 必须使用 Tailscale 官方定义的子集网段,确保客户端逻辑兼容。
prefixes:
  v4: 100.64.0.0/10       # IPv4 CGNAT 保留网段
  v6: fd7a:115c:a1e0::/48 # IPv6 ULA 私有地址网段
  allocation: sequential # IP 分配策略:顺序分配

# [中继服务器 (DERP) 配置]
derp:
  server:
    enabled: false # 初次部署建议关闭,待主线连通后再开启自建 DERP 专章
    region_id: 999
    region_code: "headscale"
    region_name: "Headscale Embedded DERP"
    stun_listen_addr: "[::]:3478"
    private_key_path: /var/lib/headscale/derp_server_private.key
    automatically_add_embedded_derp_region: true
  
  # 外部 DERP 列表。默认拉取官方节点,保证基础连通性。
  urls:
    - https://controlplane.tailscale.com/derpmap/default
  auto_update_enabled: true
  update_frequency: 3h

# [数据库配置]
# 2026 年官方建议生产环境统一使用 SQLite,性能稳健且易于备份。
database:
  type: sqlite
  debug: false
  sqlite:
    path: /var/lib/headscale/db.sqlite
    write_ahead_log: true # 开启 WAL 模式,提升多端接入时的并发写入能力

# [核心 DNS 配置]
# 注意:global 采用 JSON 数组格式 ["IP1", "IP2"],这是解决 v0.28.0 解析 Bug 的关键。
dns:
  magic_dns: true          # 开启内部主机名解析,允许通过机器名互访
  base_domain: your-domain.com # 内网私有后缀
  override_local_dns: true # 强制客户端使用 Headscale 下发的 DNS 设置
  nameservers:
    global: ["223.5.5.5", "2400:3200::1", "119.29.29.29", "2402:4e00::", "1.1.1.1", "2606:4700:4700::1111"]
  split: {}
  search_domains: []
  extra_records: []

# [日志与安全]
log:
  level: info
  format: text

# 权限策略。暂不启用外部 ACL 文件,后续可在 UI 面板中细化。
policy:
  mode: file
  path: ""

# 文件分享功能 (Taildrop)。允许组网内的设备直接互传文件。
taildrop:
  enabled: true

# 本地通信套接字。用于宿主机 docker exec 命令免密管理容器。
unix_socket: /var/run/headscale/headscale.sock
unix_socket_permission: "0770"

# [其他杂项]
disable_check_updates: false
ephemeral_node_inactivity_timeout: 30m
randomize_client_port: false
EOF

2.2.3、更新 docker-compose.yml

将 Headscale 服务加入到我们的网络架构中。编辑之前的 docker-compose.yml

YAML
cat <<'EOF' > ~/iot-architect/network/docker-compose.yml
services:
  npm:
    image: 'jc21/nginx-proxy-manager:latest'
    container_name: npm
    restart: unless-stopped
    ports:
      - '80:80'
      - '81:81'
      - '443:443'
    volumes:
      - ./npm/data:/data
      - ./npm/letsencrypt:/etc/letsencrypt
    networks:
      - headscale-net

  headscale:
    image: headscale/headscale:latest
    container_name: headscale
    restart: unless-stopped
    volumes:
      - ./headscale/config:/etc/headscale
      - ./headscale/data:/var/lib/headscale
    # 我们不需要直接映射端口到宿主机,因为流量会通过 NPM 进入
    command: serve
    networks:
      - headscale-net

networks:
  headscale-net:
    name: headscale-net
EOF

2.2.4、启动并联调

执行以下命令启动服务:

Bash
docker compose up -d

2.2.5、NPM 反向代理配置

启动容器后,你需要进入 NPM 的管理后台(http://IP:81),按照以下步骤操作:

  1. Add Proxy Host:
    • Domain Names: hs.your-domain.com (你的域名)
    • Scheme: http
    • Forward Name/IP: headscale (这里直接填容器名,因为在同一网络下)
    • Forward Port: 8080
  2. SSL 标签页:
    • 选择 Request a new SSL Certificate
    • 开启 Force SSL
    • 同意协议并保存。
  3. Advanced 标签页:
Bash
# 允许跨域请求的配置
location / {
    # 允许来自 UI 域名的请求
    add_header 'Access-Control-Allow-Origin' 'https://hs-ui.your-domain.com' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
    add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;

    # 处理浏览器的预检请求 (OPTIONS)
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' 'https://hs-ui.your-domain.com' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
    }

    # 转发请求给后端 Headscale 容器
    proxy_pass http://headscale:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # 兼容 Tailscale 的 Websockets
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

2.2.6、既然“大脑”已经开始稳定呼吸,我们要正式激活管理权限。请依次执行:

  1. 创建命名空间docker exec -it headscale headscale namespaces create default
  2. 生成 UI 面板钥匙 (API Key)docker exec -it headscale headscale apikeys create --expiration 90d

一旦拿到 API Key,我们将配置 Nginx Proxy Manager (NPM) 并上线可视化管理面板,彻底结束命令行时代!

第三章:可视化管理——Headscale-UI 的集成

3.1、部署 Headscale-UI

接下来,我们将可视化管理面板加入到 docker-compose.yml 中。请修改文件,在 services 下追加:

YAML
headscale-ui:
    image: ghcr.io/gurucomputing/headscale-ui:latest
    container_name: headscale-ui
    restart: unless-stopped
    networks:
      - headscale-net

修改完成后,执行部署:

Bash
docker compose up -d

现在我们进入最后的“合体”阶段:通过 Nginx Proxy Manager (NPM) 将服务安全地发布到公网,并在浏览器中激活可视化管理。

3.2、Nginx Proxy Manager (NPM) 配置对齐

请登录您的 NPM 管理后台 (http://IP:81),添加以下两个 Proxy Host。由于所有容器都在 headscale-net 网络中,我们直接用容器名转发,这最安全也最专业。

3.2.1、 配置 Headscale-UI 转发

  • Domain Names: hs-ui.your-domain.com
  • Scheme: http
  • Forward Name: headscale-ui
  • Forward Port: 8080
  • SSL 选项: 同样开启 Force SSL

3.2.2、UI 面板激活

访问 https://hs-ui.your-domain.com,您会看到一个设置页面。请填入以下信息进行“握手”:

  1. Headscale URL: https://hs.your-domain.com (必须带 https)
  2. API Key: hskey-api-yvZkXQYOAmoq-F4XXCvA7h2YQaHP3l8senWI1aXxcBW_W_UKsC2KYfsZ_-a86Z6bOHigGbOKFxwVZ

点击 Save。如果配置正确,您将看到左侧侧边栏显示出 default 命名空间,此时您的可视化“指挥部”正式上线。

第四章:性能飞跃——自建 DERP 中继节点

  • 核心痛点: 解决国内运营商对原生 Tailscale 节点的 UDP 封锁。
  • Docker 方案: 部署 derper 容器,配置证书自动映射。
  • 验证环节: 使用 tailscale netcheck 测试中继延迟。

第五章:多端接入与子网路由 (Subnet Router)

  • 全平台接入: Linux (Docker/Native)、Windows、iOS/Android 接入技巧。
  • 打通局域网: 开启 advertise-routes,让远程设备透明访问内网 NAS 或 PLC。
  • 出口节点: 开启 exit-node 实现异地安全上网。

第六章:运维监控与自动化

  • 健康检查: Uptime Kuma 监控服务状态。
  • 版本管理: Watchtower 自动更新容器。
  • 备份方案: 定期备份 db.sqlite 数据库。

Comments

No comments yet. Why don’t you start the discussion?

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注