boxmoe_header_banner_img

希望是美好的,也许是人间至善,而美好的事物永不消逝

文章导读

Headscale+Derper部署


avatar
hydrangea 11 8 月, 2026 49

Headscale和Derper是可以替代付费Tailscale的开源方案,可以让处于不同网络环境下的不同设备通过虚拟局域网互联;Headscale负责客户端协调和打洞,Derper负责打洞不通时作为中继转发流量。简中社区对于建立Headscale和Derper的博客很多,但是姿势各不相同导致楼主第一次部署踩了大坑。在Gemini的帮助下搞好了,这里作为笔记记录一下。

1.日常启动和配置记录

1.1 启动命令

sudo env -u HTTP_PROXY -u HTTPS_PROXY -u http_proxy -u https_proxy tailscale up --login-server <HTTPS_LINK> --authkey <KEY> --accept-routes --accept-dns=false --hostname=<HOSTNAME>

accept-dns = false非常重要,如果接受了它会和代理软件dns起冲突,导致浏览器无法正常上网。

-u防止系统代理设置影响tailscale

注:iStoreOS别通过Luci登录tailscale(当然得先通过Luci启动它),因为无法填写–accept-dns=false会导致断网;而且Luci安装的tailscale客户端无法持久保存私有服务器登录信息,所以建议opkg update && opkg install tailscale安装tailscale客户端。

1.2 IP地址

100.64.0.1 Armbian

其它省略

2 通过Docker Compose部署

方便起见,docker compose放在了/etc/derp/目录中;如果未安装Docker,可curl -fsSL https://get.docker.com -o get-docker.sh && sudo sh get-docker.sh安装。

2.1 使用acme.sh申请和安装证书

sudo apt update && sudo apt install -y curl socat cron

curl https://get.acme.sh | sh -s email=<Your Email>

sudo mkdir -p /etc/derp/certs/<Your Domain>

acme.sh --issue -d --standalone

以上就申请好了证书,存放在~/.acme.sh中,不能直接使用,所以要再次使用acme.sh把它安装到容器使用的目录:

mkdir -p /etc/derp/certs/<Your Domain>/

接下来安装证书。由于要用docker compose部署,所以renew证书的时候附加命令,在安装证书时就写好了:

~/.acme.sh/acme.sh --install-cert -d <Your Domain> \
  --key-file       /etc/derp/certs/<Your Domain>/<Your Domain>.key \
  --fullchain-file /etc/derp/certs/<Your Domain>/<Your Domain>.crt \
  --reloadcmd      "docker restart derper && systemctl reload nginx"

2.2 容器部署

vim /etc/derp/docker-compose.yml添加如下内容:

services:
  headscale:
    image: headscale/headscale:latest
    container_name: headscale
    restart: unless-stopped
    volumes:
      # 方便起见使用明确的绝对路径
      - /etc/derp/headscale:/etc/headscale
      - /etc/derp/headscale-data:/var/lib/headscale
    ports:
      - "127.0.0.1:8080:8080"
    command: serve --config /etc/headscale/config.yaml


  derper:
      image: ghcr.io/kaaanata/derper:latest
      container_name: derper
      restart: unless-stopped
      volumes:
        # 挂载你的域名证书目录到容器内的 /app/certs
        # 容器会自动在 /app/certs 寻找 .crt 和 .key
        - /etc/derp/certs/:/app/certs
      ports:
        - "8443:8443/tcp"
        - "3478:3478/udp"
      environment:
        # 必填:你的 DERP 域名
        - DERP_DOMAIN=
        # 指定监听地址与端口(匹配宿主机映射的 8443)
        - DERP_ADDR=:8443
        # 禁用 80 端口 HTTP 服务(防止与 Nginx 抢占端口)
        - DERP_HTTP_PORT=-1
        # 显式使用我们已申请好的 manual 证书模式
        - DERP_CERT_MODE=manual
        # 证书存放路径
        - DERP_CERT_DIR=/app/certs
        # STUN 打洞服务及 UDP 端口
        - DERP_STUN=true
        - DERP_STUN_PORT=3478
        # 开启客户端身份校验(防止被他人免费滥用)(不过本节点并没有公开,身份认证密钥也不公开,可以放心关掉)
        - DERP_VERIFY_CLIENTS=false

接下来,要给headscale和derp写配置文件:

vim /etc/derp/headscale/config.yaml

内容:

server_url: https://
listen_addr: 0.0.0.0:8080
metrics_listen_addr: 0.0.0.0:9090
grpc_listen_addr: 0.0.0.0:50443
grpc_allow_insecure: true

private_key_path: /var/lib/headscale/private.key
noise:
  private_key_path: /var/lib/headscale/noise_private.key

database:
  type: sqlite3
  sqlite:
    path: /var/lib/headscale/db.sqlite

prefixes:
  v4: 100.64.0.0/10
  v6: fd7a:115c:a1e0::/48

dns:
  magic_dns: true
  base_domain: lcsh
  nameservers:
    global:
      -8.8.8.8
      -1.1.1.1
  override_local_dns: true

node:
  ephemeral:
    inactivity_timeout: 30m

derp:
  server:
    enabled: false
  urls: []
  paths:
    - /etc/headscale/derp.yaml
  auto_update_enabled: true
  update_frequency: 24h

disable_check_updates: true

在这个文件中,有headscale的自有密钥,影响使用吗?Gemini的回答:

  • /var/lib/derper/derper.key(身份私钥)
  • 这是 DERP 服务器自身的节点身份私钥(Node Key),用来向 Tailscale/Headscale 网络标识“我是一台 DERP 节点”。
  • 当镜像没有指定 -keyfile 路径时,derper 会自动在本地生成/读取这个文件(提示 using /var/lib/derper/derper.key)。这是 Tailscale 原生 derper 的标准行为,与域名证书毫无关系。
  • /app/certs 中的证书(TLS 加密证书)
  • 这是用来进行 HTTPS/TLS 握手的域名证书(.crt.key)。
  • 在你的配置中,DERP_CERT_MODE=manualDERP_CERT_DIR=/app/certs 已经成功生效,日志中的 derper: serving on :8443 with TLS 就是最好的证明 —— 说明它已经加载了你的 acme.sh 证书,并用它开启了安全的 TLS 传输。

以及derp的配置文件:

vim /etc/derp/headscale/derp.yaml

内容:

regions:
  901:
    regionid: 901
    regioncode: hk-derp
    regionname: "HK Private DERP"
    nodes:
      - name: 901a
        regionid: 901
        hostname: 
        stunport: 3478
        derpport: 8443
        stunonly: false

别急,还有nginx反代需要配置。首先安装nginx

apt install nginx -y

然后vim /etc/nginx/sites-available/headscale,写入以下内容,用来转发443请求给headscale,以及给acme.sh验证做一个回落;另外我配置derper使用8443,不与headscale抢端口。

server {
    listen 80;
    server_name ;

    # 1. 专门给 acme 验证用的目录
    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }

    # 2. 其他 HTTP 请求重定向到 HTTPS(保持原样或加上)
    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl http2;
    server_name ;

    # 引用你在第一步申请到的 acme.sh 证书绝对路径
    ssl_certificate     /etc/derp/certs//.crt;
    ssl_certificate_key /etc/derp/certs//.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # 将所有 HTTPS 请求转发给 Docker 容器中的 Headscale (8080)
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_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;
    }
}

链接配置文件到另一个目录,然后启动nginx:

ln -s /etc/nginx/sites-available/headscale /etc/nginx/sites-enabled/

另外,之前申请证书是用standalone模式,但是由于安装了nginx导致80端口被占用,不能再用80端口做验证了,所以要改成nginx+webroot做响应的验证模式,上面代码块的#1部分已经做了响应目录的设置;这时再renew和安装一下证书:

~/.acme.sh/acme.sh --renew -d <Your_Domain> --force

~/.acme.sh/acme.sh --install-cert -d <Your_Domain> \ --key-file /etc/derp/certs/<Your_Domain>/<Your_Domain>.key \ --fullchain-file /etc/derp/certs/<Your_Domain>/<Your_Domain>.crt \ --reloadcmd "docker restart derper && systemctl reload nginx"

最后,重启nginx。
nginx -t && systemctl restart nginx

2.3 启动

docker exec -it headscale headscale users create <MyUserName>

只有一个user的话,这里填–user 1就可以,有效期10年

docker exec -it headscale headscale preauthkeys create --user 1 --reusable --expiration 3650d

完成后会打印一长串密钥,一定要复制保存下来,只显示一次。

2.4 检查

检查连接是否正常:

tailscale netcheck

检查工作状态:

tailscale status

2.5 管理

查看客户端节点

docker exec -it headscale headscale node list

删除客户端节点

docker exec -it headscale headscale node delete -i 7

3 客户端安装

Linux系统:

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

启动命令看开头。

Win10/11直接找官网下载。但安装完了不要登录官方节点,使用开头的启动命令去掉sudo和env部分在cmd运行。

安卓加入节点的命令:


docker exec -it headscale headscale auth register --auth-id <Android client ID> --user <User Name>



评论(0)

查看评论列表

暂无评论


发表评论

表情 颜文字
插入代码