Headscale 端到端直连
说明
Tailscale 终究是第三方平台,如该平台发生数据泄露、异常崩溃、服务终止等,就无能为力。或许,我们可以自己建一个类似的私有平台?
Headscale 旨在实现一个自托管、开源的Tailscale控制服务器替代方案,可以实现较小范围内和实现单个Tailnet的功能,通常可用于设置为单个组织、家庭或个人使用。
实际上,我们可以将之看作一个备案,或者是特殊信息链路,避免由其他第三方中继。
前文: Tailscale 端到端直连 。
注意:
-
Headscale 需要有公网IP服务器,作为客户端端点彼此确认位置的锚点。
-
相较于 Tailscale 个人免费版, Headscale 取消了设备连接等限制:
项目 Headscale Tailscale 个人免费版 Devices 无限制(默认:100.64.0.0/10) 20 个 IP Address 可自行更改网段 不同网段,地址定死 Admin users 1 个 1 个 -
Headscale 没有账户管理机制,没有 UI 界面,登录授权需要在服务器命令行中登记。
结果测试
先把测试结果摆在这里吧。
Headscale 与 Tailscale 其实原理相同,主要是提供服务的平台是否私有的区别。相比 600Kb/s 的中继服务,直连的优势一览无余。
可道云 5G 环境下载 200M 视频文件,30+M/s:
同时刻,Headscale 服务器网络流量只有 47Kbit/s 左右的出站:
搭建服务器
下载 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 #1050 和 update 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
- Nginx 更多配置参见: Nginx 容器反向代理和 SSL 配置 。
/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/metrics
和 https://<www.example.com>:8443/metrics
(若设置了反向代理),正常显示:
创建命名空间
在 Headscale 服务器 Docker 内,创建命名空间。
docker exec -it headscale /bin/bash
headscale namespaces create <NAMESPACE>
可以通过 headscale namespaces list
查看。
添加端点
根据 官方文档 :
OS | Supports 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
通过浏览器访问下方链接验证功能,显示:
将显示的命令中 NAMESPACE
修改为此前明明的命名空间:
headscale -n <NAMESPACE> nodes register -k 222222xxxx222xxxxxxxxxxxee222xxxxxxx2xxxxxxxx
显示:
Machine registered
此时可以通过 headscale nodes list
查看 docker 服务器上所有节点客户端。
Android
安卓端使用官方 APP 即可:Tailscale | F-Droid 。
-
初次进入主界面如图:
-
点击右上角竖状三点,再点击弹出菜单中的
Tailscale 1.xx.x
。往复循环 3 到 5 次,即显示Change server
。 -
点击
Change server
,输入服务器地址,点击save
,返回Sign in
界面。 -
接下来按照
Docker(Linux、NAS)
后续步骤依葫芦画瓢即可。
Windows
-
安装官方客户端:Download · Tailscale 。
-
终端打开客户端安装目录:
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
-
后续服务器上注册就不说了。
其他
其他平台客户端、更多进阶功能请参考:
- 基本全覆盖:Headscale搭建P2P内网穿透 - 腾讯云开发者社区-腾讯云 (tencent.com)
- 局域网路由: headscale私有部署 | 俊瑶先森 (junyao.tech)
- 包含 TLS:「教程」使用 Headscale 的简单教程 | 粥盐籽 (posase.im)
- 开源版tailscale,headscale搭建 - DongVPS
开始使用
各平台客户端启用 Active
,即可通过 Headscale 分配的 IP 地址访问服务。