使用 Headscale 搭建 Tailscale 中转服务,实现端到端直连

发布时间 2023-12-15 10:50:08作者: jack_Meng

说明

Tailscale 终究是第三方平台,如该平台发生数据泄露、异常崩溃、服务终止等,就无能为力。或许,我们可以自己建一个类似的私有平台?

Headscale 旨在实现一个自托管、开源的Tailscale控制服务器替代方案,可以实现较小范围内和实现单个Tailnet的功能,通常可用于设置为单个组织、家庭或个人使用。

实际上,我们可以将之看作一个备案,或者是特殊信息链路,避免由其他第三方中继。

前文: Tailscale 端到端直连

注意:

  1. Headscale 需要有公网IP服务器,作为客户端端点彼此确认位置的锚点。

  2. 相较于 Tailscale 个人免费版, Headscale 取消了设备连接等限制:

    项目HeadscaleTailscale 个人免费版
    Devices 无限制(默认:100.64.0.0/10) 20 个
    IP Address 可自行更改网段 不同网段,地址定死
    Admin users 1 个 1 个
  3. Headscale 没有账户管理机制,没有 UI 界面,登录授权需要在服务器命令行中登记。

结果测试

先把测试结果摆在这里吧。

Headscale 与 Tailscale 其实原理相同,主要是提供服务的平台是否私有的区别。相比 600Kb/s 的中继服务,直连的优势一览无余。

可道云 5G 环境下载 200M 视频文件,30+M/s:

  • kod1
  • kod2

同时刻,Headscale 服务器网络流量只有 47Kbit/s 左右的出站:

  • 服务器流量

搭建服务器

下载 Wireguard

官网:Installation - WireGuard

Docker

Github 项目地址:juanfont/headscale: An open source, self-hosted implementation of the Tailscale control server (github.com)

官方提供了 Headscale 的 Docker 镜像,极大方便了更新维护。

docker-compose.yml :

复制version: '3.1'

services:
  headscale:
    image: headscale/headscale
    container_name: headscale
    volumes:
      - /home/docker/headscale/config:/etc/headscale
      - /home/docker/headscale/data:/var/lib/headscale
    ports:
      - 8080:8080
    command: headscale serve
    restart: unless-stopped

补全文件

由 Docker 生成数据卷下,一般无文件。需要补全文件才能顺利操作。

复制wget https://github.com/juanfont/headscale/raw/main/config-example.yaml -O /home/docker/headscale/config/config.yaml
touch /home/docker/headscale/config/db.sqlite
wg genkey > /home/docker/headscale/config/private.key

配置文件

/home/docker/headscale/config/config.yaml 文件是主要配置文件。

nano /home/docker/headscale/config/config.yaml

复制server_url: http://<DOMAIN or IP>:<PORT>
......

listen_addr: 0.0.0.0:<PORT>
......

ip_prefixes:
  - fd7a:115c:a1e0::/48
  - 100.64.0.0/10
......

unix_socket: /var/run/headscale/headscale.sock
......

randomize_client_port: true
  • server_url :设为 域名/IP:port 的形式。与 listen_addr 没啥关系。

  • listen_addr :原为 listen_addr: 127.0.0.1:8080 ,须改为 listen_addr: 0.0.0.0:<port> 对外进行监听。

  • ip_prefixes :目前 IP 前缀只能设置为 - fd7a:115c:a1e0::/48 - 100.64.0.0/10

    根据 Suspected bug with ip_prefixes · Issue #1050update ip_prefixes docs by kradalby · Pull Request #1135 中更新的结果来看:由于使用的是 Tailscale 的开源客户端,其源码中明确写道:

    CGNATRange returns the Carrier Grade NAT address range that is the superset range that Tailscale assigns out of. See https://tailscale.com/kb/1015/100.x-addresses. Note that Tailscale does not assign out of the ChromeOSVMRange.

    CGNATRange (函数)返回运营商级的NAT地址范围,也是 Tailscale 分配的超集范围。见https://tailscale.com/kb/1015/100.x-addresses。注意:Tailscale 不会分配到 ChromeOSVMRange 之外。

  • unix_socket :原为 unix_socket: ./headscale.sock ,更改为 unix_socket: /var/run/headscale/headscale.sock

  • randomize_client_port :原为 false ,须改为 true 。否则客户端端点访问互相干扰,无法访问服务。

HTTP 示例

config.yaml

复制server_url: http://example.com:8080
......

listen_addr: 0.0.0.0:8080
......

ip_prefixes:
  - fd7a:115c:a1e0::/48
  - 192.168.64.0/24
......

unix_socket: /var/run/headscale/headscale.sock
......

randomize_client_port: true

HTTPS 示例(Nginx+SSL)

Headscale

config.yaml

需要将 server_url 变更为最后对外提供服务的地址

复制server_url: https://<www.example.com>:8443
......

listen_addr: 0.0.0.0:8080
......

ip_prefixes:
  - fd7a:115c:a1e0::/48
  - 192.168.64.0/24
......

unix_socket: /var/run/headscale/headscale.sock
......

randomize_client_port: true
Nginx

docker-compose.yml

复制version: '3.1'

services:
  nginx:
    restart: always
    image: nginx:latest
    container_name: nginx
    ports:
      - 8443:8443
    volumes:
      - /home/docker/nginx/conf.d:/etc/nginx/conf.d

/home/docker/nginx/conf.d/nginx.conf

复制map $http_upgrade $connection_upgrade { 
    default keep-alive;
    'websocket' upgrade;
    '' close;
}

server {
    listen 8443 ssl http2;
    listen [::]:8443 ssl http2;
    server_name <example.com> <www.example.com>;

    ssl on;
    ssl_certificate /etc/nginx/conf.d/ssl/<www.example.com.pem>;
    ssl_certificate_key  /etc/nginx/conf.d/ssl/<www.example.com.key>;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;

   location / {
        proxy_pass http://<www.example.com>:8080;
        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 $http_x_forwarded_proto;
        add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
    }
}

测试功能

访问 http://<www.example.com>:8080/metricshttps://<www.example.com>:8443/metrics (若设置了反向代理),正常显示:

metrics测试

创建命名空间

在 Headscale 服务器 Docker 内,创建命名空间。

复制docker exec -it headscale /bin/bash

headscale namespaces create <NAMESPACE>

可以通过 headscale namespaces list 查看。

添加端点

根据 官方文档

OSSupports headscale
Linux Yes
OpenBSD Yes
FreeBSD Yes
macOS Yes (see on your headscale for more information)/apple
Windows Yes docs
Android Yes docs
iOS Not yet

Docker(Linux、NAS)

为便于软件管理和稳定性更新,我依旧使用开源的 tailscale Docker 客户端添加端点。

docker-compose.yml :

复制version: '3.1'

services:
  Headscaled:
    container_name: Headscaled_Client
    image: tailscale/tailscale
    network_mode: host
    privileged: true
    restart: always
    cap_add: 
      - net_admin
      - sys_module
    volumes:
      - /mnt/user/appdata/Headscaled_Client/lib:/var/lib
      - /dev/net/tun:/dev/net/tun
    command: sh -c "mkdir -p /var/run/tailscale && ln -s /tmp/tailscaled.sock /var/run/tailscale/tailscaled.sock && tailscaled"

注意:数据卷中 /dev/net/tun:/dev/net/tun 不得更改,否则容器缺少设备、无法启动。

docker exec -it Headscaled_Client /bin/sh 进入容器内部,向 Headscale 服务器发出客户端端点申请,显示:

复制tailscale up  --login-server=https://<www.example.com>:8443 --accept-routes=true --accept-dns=false --advertise-routes=192.168.64.0/24

显示:
To authenticate, visit:

        https://<www.example.com>:8443/register?key=222222xxxx222xxxxxxxxxxxee222xxxxxxx2xxxxxxxx

客户端端点申请

通过浏览器访问下方链接验证功能,显示:

客户端端点申请2

将显示的命令中 NAMESPACE 修改为此前明明的命名空间:

复制headscale -n <NAMESPACE> nodes register -k 222222xxxx222xxxxxxxxxxxee222xxxxxxx2xxxxxxxx

显示:
Machine registered

此时可以通过 headscale nodes list 查看 docker 服务器上所有节点客户端。

Android

安卓端使用官方 APP 即可:Tailscale | F-Droid

  • 初次进入主界面如图:

    APPSettings
  • 点击右上角竖状三点,再点击弹出菜单中的 Tailscale 1.xx.x 。往复循环 3 到 5 次,即显示 Change server

    APPSettings2
  • 点击 Change server ,输入服务器地址,点击 save ,返回 Sign in 界面。

    APPSettings3
  • 接下来按照 Docker(Linux、NAS) 后续步骤依葫芦画瓢即可。

Windows

  1. 安装官方客户端:Download · Tailscale

  2. 终端打开客户端安装目录:

    复制tailscale up --accept-dns=false --accept-routes --login-server=https://<www.example.com>:8443 --unattended
    
    To authenticate, visit:
    
            https://<www.example.com>:8443/register?key=0zcxzczxczxcvreerywrtjrukulikutyujtryyntynhtgrvfynhbtgvrfcedtvrfc30e
    
  3. 后续服务器上注册就不说了。

其他

其他平台客户端、更多进阶功能请参考:

开始使用

各平台客户端启用 Active ,即可通过 Headscale 分配的 IP 地址访问服务。

 

【出处】:https://www.cnblogs.com/Yogile/p/17064031.html

=======================================================================================