Tailscale自部署(Headscale)

前言

最近有了远程连接家里面电脑的需求,于是研究了一下P2P内网穿透的方案,在折腾了Netmaker、Tailscale、ZeroTier等软件之后最终选择了Tailscale。由于Tailscale的官方DERP中继服务器都在国外,且线路质量也不好,所以就想到自建Tailscale,并配置DERP中继。

那么什么是Headscale?

An open source, self-hosted implementation of the Tailscale control server. —— Headscale项目介绍

通过Headscale,我们能在自己服务器上部署Tailscale的控制端,并且Headscale内置了DERP配置,不需要安装额外的软件即可一并完成DERP部署。

硬件要求

  • 需要一台VPS,配置不用很高,但是需要有公网IPv4。
  • 需要一个域名,该域名指向该VPS的IP地址。

目标

  • 使用Docker部署Headscale及其WebUI
  • 配置DERP
  • 配置Nginx反向代理

部署

开放端口

Tailscale客户端与Headscale之间的通信一般通过443/TCP完成;客户端与DERP中继节点的通信通过3478/UDP完成。如果在服务器内开启了或服务商自带了防火墙,需要提前开放这两个端口。以下以阿里云轻量应用服务器的防火墙为例。

安装

以下内容参考自Headscale的官方文档:Running headscale in a container

首先需要确保服务器上已安装了Docker,如果VPS在国内的话需要配置Docker镜像源。

然后SSH连接至服务器

mkdir -p ./headscale/config
cd ./headscale/config

然后将配置文件下载到服务器并重命名,其中版本号v0.25.1需要参考官方教程

wget -O config.yaml https://raw.githubusercontent.com/juanfont/headscale/v0.25.1/config-example.yaml

然后编辑配置文件,每个参数都有说明,可以自行参考,这里我给出我使用的配置文件

---
# url需要对应自己配置的域名地址
server_url: https://hs.example.com:443
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: false
noise:
  private_key_path: /var/lib/headscale/noise_private.key
prefixes:
  # 下面的地址表示分配给Tailscale客户端的IP地址
  v4: 100.65.64.0/24
  v6: fd7a:115c:a1e0:2000::/48
  allocation: sequential
derp:
  server:
    enabled: true
    region_id: 999
    # DERP名字
    region_code: "my-hangzhou"
    region_name: "Headscale Embedded DERP"
    stun_listen_addr: "0.0.0.0:3478"
    private_key_path: /var/lib/headscale/derp_server_private.key
    automatically_add_embedded_derp_region: true
    # 需要将IPv4和IPv6条目注释或改成服务器实际地址,不然会连不上DERP
    # ipv4: 1.2.3.4
    # ipv6: 2001:db8::1
  urls:
    - https://controlplane.tailscale.com/derpmap/default
  paths: []
  auto_update_enabled: true
  update_frequency: 24h
disable_check_updates: false
ephemeral_node_inactivity_timeout: 30m
database:
  type: sqlite
  debug: false
  gorm:
    prepare_stmt: true
    parameterized_queries: true
    skip_err_record_not_found: true
    slow_threshold: 1000
  sqlite:
    path: /var/lib/headscale/db.sqlite
    write_ahead_log: true
    wal_autocheckpoint: 1000
acme_url: https://acme-v02.api.letsencrypt.org/directory
acme_email: ""
tls_letsencrypt_hostname: ""
tls_letsencrypt_cache_dir: /var/lib/headscale/cache
tls_letsencrypt_challenge_type: HTTP-01
tls_letsencrypt_listen: ":http"
tls_cert_path: ""
tls_key_path: ""
log:
  format: text
  level: info
policy:
  mode: file
  path: ""
dns:
  magic_dns: true
  # 表示连接设备的域名
  base_domain: nuotian.my
  nameservers:
    global:
    # 可以添加国内的DNS地址
      - 114.114.114.114
      - 1.1.1.1
      - 1.0.0.1
      - 2606:4700:4700::1111
      - 2606:4700:4700::1001
    split:
      {}
  search_domains: []
  extra_records: []
unix_socket: /var/run/headscale/headscale.sock
unix_socket_permission: "0770"
logtail:
  enabled: false
randomize_client_port: false

然后保存,回到./headscale目录,创建docker-compose.yml,并编辑

cd ..
vim docker-compose.yml

下面是我使用的Docker Compose配置,主要完善了WebUI、数据存储目录、Nginx反向代理端口,可以参考。其中"127.0.0.1:9090:9090"是Headscale的图表暴露的端口,可以选择不暴露出来;WebUI我选择的是headscale-ui,其他WebUI可以查看这里

services:
  headscale:
    image: headscale/headscale:0.25.1
    restart: unless-stopped
    container_name: headscale
    ports:
      - "127.0.0.1:10010:8080"
      - "127.0.0.1:9090:9090"
      - "0.0.0.0:3478:3478/udp"
    volumes:
      - "./config:/etc/headscale"
      - "./data:/var/lib/headscale"
    command: serve
    cap_add:
      - NET_ADMIN
      - NET_RAW
      - SYS_MODULE
    sysctls:
      - net.ipv6.conf.all.forwarding=1
      - net.ipv4.ip_forward=1
    environment:
      - TZ=Asia/Shanghai
  headscale-ui:
    image: ghcr.io/gurucomputing/headscale-ui:2025.03.21
    restart: unless-stopped
    container_name: headscale-ui
    ports:
      - "127.0.0.1:10011:8080"
    environment:
      - TZ=Asia/Shanghai

保存之后,启动容器,并创建API Key以在WebUI上使用

docker compose up -d

# 检查服务是否正常启动
curl http://127.0.0.1:9090/metrics

# 创建API Key,有效期999天
docker exec -it headscale headscale apikeys create --expiration 999d

将输出的API Key复制,并保存在安全的地方。

反向代理

由于我服务器上还有其他网页,所以需要使用Nginx反向代理。这里也直接给出配置文件,SSL证书的获取可以通过Certbotacme.sh

map $http_upgrade $connection_upgrade {
    default      upgrade;
    ''           close;
}

server {
    listen 80;
    listen [::]:80;
    listen 443      ssl;
    listen [::]:443 ssl;
    http2 on;
    port_in_redirect off;
    server_name hs.furcode.cn;

    if ($ssl_protocol = "") {
        return 301 https://$host$request_uri;
    }

    ssl_certificate /etc/letsencrypt/live/hs.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/hs.example.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://127.0.0.1:10010;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $server_name;
        proxy_redirect http:// https://;
        proxy_buffering off;
        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;
        add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
    }

    location /web {
        proxy_pass http://localhost:10011;
        proxy_http_version 1.1;
        proxy_set_header Host $server_name;
        proxy_buffering off;
        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 $http_x_forwarded_proto;
    }
}

然后保存之后加载配置文件即可

nginx -t
nginx -s reload

访问WebUI

在浏览器内访问https://<你的域名>/web既可打开WebUI。首先点击左侧的Settings,在Headscale URL处输入https://<你的域名>,然后在Headscale API Key输入生成的API Key,点击Test Server Settings,如果一切正常的话旁边会显示一个勾,至此服务端配置就完成了。需要注意的是,我使用的这个WebUI是纯前端实现的,连接密钥和地址都保存在本地浏览器中,所以需要将API Key保存下来以便后续使用。

使用

在添加客户端之前先要在WebUI上添加一个用户,点击WebUI左侧的User View,点击顶部的+ New User,输入用户名后点击右侧的✓。

Windows

首先在官网下载Tailscale客户端,并安装。

然后打开Tailscale,再打开Powershell或CMD,输入

tailscale login --login-server https://<你的域名>

回车后Tailscale会有一个通知,点击通知打开浏览器,即可看到下面的内容

复制--key后面的字符串,打开Headscale的WebUI,进入Device View界面,点击顶部的+ New Device,Device Key粘贴刚刚复制的字符串,然后选择一个用户,然后点击✓。

在WebUI添加好设备之后,本地的Tailscale客户端应该会立即上线。然后打开Powershell或CMD,输入

tailscale netcheck

即可看到当前连接状态和各个DERP中继服务器的延迟。

MacOS

首先在官网下载Tailscale客户端,安装软件并打开。

然后在Account界面点击底部的按钮,在弹出框内输入https://<你的域名>,然后点击Add Account

然后浏览器会打开一个网页,网页中会出现Key,接下来的步骤与Windows端相同,这里就直接略过。

Android

首先在官网下载Tailscale客户端,安装软件并打开。打开软件后可能会提示登录Tailscale官方的网页,直接关掉界面即可。打开右上角的设置,再打开顶部的账号界面,点击右上角三个点,选择Use an alternate server

然后输入https://<你的域名>,点击Add account

之后同样会打开浏览器,出现Key,接下来的操作同样与Windows端相同,不再赘述。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇