自建 Headscale + DERP 服务器

之前一直是通过端口映射访问家里的 NAS 的，但是会存在一些问题：

需要配置 DDNS，IP 切换时会存在延迟

访问 Web 服务需要加端口

只能暴露出部分服务，比较核心的服务（例如路由器的配置）不能放开公网访问

最近一段时间也调研和尝试了各路组网方案（ZeroTier/WireGuard/Tailscale），最后选择了自建 Headscale 全家桶方案。

准备

一台 VPS，安装 Docker 及 Docker Compose，需要开放下面端口

8080 Headscale HTTP

9090 Headscale Metrics

8443 DERP 服务器 HTTPS

3478/udp DERP 服务器 STUN

8008 Headscale-Admin

客户端（Linux/macOS/Windows/iOS/Android）

部署 DERP 服务器

创建一个目录，存放 DERP 服务器的配置文件

Copy
mkdir -p /app/derper/certs
cd /app/derper

创建自签名证书

Copy
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes -keyout /app/derper/certs/<hostname>.key -out /app/derper/certs/<hostname>.crt -subj "/CN=<hostname>" -addext "subjectAltName=DNS:<hostname>"

hostname 可随意，统一即可

创建 docker-compose.yaml 文件，内容如下：

Copy
services:
derper:
image: ghcr.nju.edu.cn/yangchuansheng/derper:latest
container_name: derper
restart: always
volumes:
- /app/derper/certs:/app/certs
environment:
- DERP_CERT_MODE=manual
- DERP_ADDR=:443
- DERP_DOMAIN=<hostname>
ports:
- 8443:443
- 3478:3478/udp

这里使用了南京大学提供的 GHCR 镜像，如不需要可替换 ghcr.nju.edu.cn 为 ghcr.io

最后启动 DERP 服务器

Copy
docker compose pull
docker compose up -d

写一份 derp.json 配置文件，传到一个能直接访问的地方备用：

Copy
{
"Regions": {
"901": {
"RegionID": 901,
"RegionCode": "cn-hangzhou",
"RegionName": "Hangzhou",
"Nodes": [
{
"Name": "901h",
"RegionID": 901,
"DERPPort": 8443,
"HostName": "<hostname>",
"IPv4": "<IP>",
"InsecureForTests": true
}
]
}
}
}

这里假设我们已经上传到了 https://example.com/derp.json

部署 Headscale

创建 Headscale 配置文件目录

Copy
mkdir -p /app/headscale
cd /app/headscale
mkdir config
touch config/db.sqlite
wget -O config/config.yaml https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml

修改 config/config.yaml 文件中的配置：

server_url 修改为 http://<IP>:8080

listen_addr 修改为 0.0.0.0:8080

metrics_listen_addr 修改为 0.0.0.0:9090（可选）

grpc_listen_addr 修改为 0.0.0.0:50443

noise.private_key_path 修改为 /etc/headscale/noise_private.key

prefixes.v4 和 prefixes.v6 按需修改即可

derp.urls[0] 修改为刚刚上传的 derp.json 文件 URL，这里是 https://example.com/derp.json

database.sqlite.path 修改为 /etc/headscale/db.sqlite

dns_config.nameservers 修改为 223.5.5.5 和 223.6.6.6（可以根据情况自行修改）

dns_config.base_domain 修改为你自己的域名，会显示在客户端中

创建 docker-compose.yaml 文件：

Copy
services:
headscale:
image: headscale/headscale:0.23.0-alpha8
container_name: headscale
restart: always
command: serve
volumes:
- ./config:/etc/headscale
ports:
- 8080:8080
- 9090:9090

最后启动 Headscale 即可

Copy
docker compose pull
docker compose up -d

部署 Headscale-Admin

创建 Headscale-Admin 配置文件目录

Copy
mkdir -p /app/headscale-admin
cd /app/headscale-admin

因浏览器的 HTTP 安全限制，直接通过域名访问会跨域，这里通过 Caddy 反向代理规避

Copy
nano Caddyfile

内容如下：

Copy
:{$PORT:80} {
reverse_proxy /api/* <IP>:8080
root * /app
encode gzip zstd
try_files {path}.html {path}
file_server
}

创建 docker-compose.yaml 文件：

Copy
services:
headscale-admin:
image: goodieshq/headscale-admin:latest
container_name: headscale-admin
restart: unless-stopped
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
environment:
- PORT=80
- ENDPOINT=/headscale
ports:
- 8008:80

最后启动即可

Copy
docker compose pull
docker compose up -d

Headscale 的 API Key 可以通过如下命令创建：

Copy
docker exec -it headscale headscale apikey create

Web UI 可以通过 http://<IP>:8008/headscale 访问，配置需要去掉 Legacy API 的勾选状态。

创建用户

在服务端执行下面命令即可

Copy
docker exec -it headscale headscale users create <你的用户名>

客户端配置

Linux

首先安装 Tailscale 客户端

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

然后申请加入 Headscale 网络

Copy
tailscale up --login-server=http://<IP>:8080 --accept-routes

如果需要通过这个节点访问其他网段，增加 --advertise-routes 参数即可：

Copy
tailscale up --login-server=http://<IP>:8080 --advertise-routes=192.168.1.0/24 --accept-routes

打开返回结果中的链接，里面有一段认证命令，回到服务端执行即可

Copy
docker exec headscale headscale nodes register --user <你的用户名> --key nodekey:******

Apple 设备

直接访问 http://<IP>:8080/apple，按步骤操作即可。

Android

打开 F-Droid 这个页面下载 APK 安装包安装：

f-droid.org/en/packages/com.tailscale.ipn

安装后打开 App，右上角三个点，多点几次，就会出现 Change Server，填入 http://<IP>:8080 后按提示完成认证即可。

Windows

家里没有 Windows 设备，无法实际测试验证，各位看官请移步参考资料中的教程。

参考资料

Tailscale 基础教程：Headscale 的部署方法和使用教程

Tailscale 基础教程：部署私有 DERP 中继服务器

Headscale 部署和 DERP 服务器配置

headscale-admin