xChar
·7 months ago

之前一直是通过端口映射访问家里的 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 服务器的配置文件

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

创建自签名证书

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 文件,内容如下:

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.cnghcr.io

最后启动 DERP 服务器

docker compose pull
docker compose up -d

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

{
  "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 配置文件目录

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.v4prefixes.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.5223.6.6.6(可以根据情况自行修改)
  • dns_config.base_domain 修改为你自己的域名,会显示在客户端中

创建 docker-compose.yaml 文件:

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 即可

docker compose pull
docker compose up -d

部署 Headscale-Admin

创建 Headscale-Admin 配置文件目录

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

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

nano Caddyfile

内容如下:

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

创建 docker-compose.yaml 文件:

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

最后启动即可

docker compose pull
docker compose up -d

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

docker exec -it headscale headscale apikey create

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

创建用户

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

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

客户端配置

Linux

首先安装 Tailscale 客户端

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

然后申请加入 Headscale 网络

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

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

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

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

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 设备,无法实际测试验证,各位看官请移步参考资料中的教程。

参考资料

Loading comments...