前言

Zerotier 和 Tailscale 是目前很流行易用的内网穿透解决方案,对个人用户来说,它们官方免费提供的中转服务已是十分甚至九分可用,我过去深蒙其惠。然而,大半年未用后,我惊讶地发现因为某某原因,官方服务器在国内已经是半死不活,zerotier 官方的 moon 节点和 planet 服务器均阵亡,tailscale 倒还勉强可连通,但至多称得上应急,要应付我的主要场景——远程桌面,就显得捉襟见肘了。

当然,除了远程桌面我自然也有异地组网的需求,更何况 RDP 才是最优秀的远程桌面协议,向日葵之流是上不了我的台面的(当然也可以应急,当然向日葵昂贵的 RDP 支持我是不可能选的)。不过除了自建,市场上也有其他提供异地组网的服务,价格相对合理,为免广告嫌疑就不赘述了。

那么自建选什么呢?笔者已经部署了 RustDesk,还支持 RDP 打洞,不过延迟还是稍稍令人遗憾。zerotier 自建 moon 是不够的,因为官方 planet 已经连不上了,要自建 planet,不过用下来不尽如人意。

Headscale 是 Taiscale 的开源替代方案,目标是为自托管者和爱好者提供可用于其项目和实验室的开源服务器。它实现了一个狭窄的范围,一个单一的 Tailnet,适合个人使用,或小型开源组织。

总而言之,一台带公网 ip 的服务器,一些需要组网的客户端,我们就可以开始自建 Headscale 了。

服务端搭建

安装

  1. 下载二进制文件

官方release 选择最新的、适合自己的发行版,运行

wget --output-document=/usr/local/bin/headscale https://github.com/juanfont/headscale/releases/download/v<VERSION>/headscale_<VERSION>_linux_<ARCH>

例如我是wget --output-document=/usr/local/bin/headscale https://github.com/juanfont/headscale/releases/download/v0.22.3/headscale_0.22.3_linux_amd64

如果你的服务器在国内,连接 github 有问题,可以选择在客户端下载然后上传,mv <FILE_PATH> /usr/local/bin/headscale ,或者替换 URI 为临时文件床的 URI 等等,办法不一而足

  1. 创建配置目录
mkdir -p /etc/headscale
  1. 创建目录用来存储数据与证书
mkdir -p /var/lib/headscale
  1. 创建空的 SQLite 数据库文件
touch /var/lib/headscale/db.sqlite
  1. 下载官方 Headscale 配置文件
wget https://github.com/juanfont/headscale/raw/main/config-example.yaml -O /etc/headscale/config.yaml

这里如果你在第一步下载的不是最新版的 release,请务必把链接换成 repo 里对应的版本号的 yaml 的 Uri,例如我的可以换成https://github.com/juanfont/headscale/raw/1e22f17/config-example.yaml,当然因为我下载的就是最新的,1e22f17就是最新的版本号

  1. 修改config.yaml
vi /etc/headscale/config.yaml

同样,代码可能有变化,具体以官方文档和yaml内注释为准。

  • server_url改为你自己服务器的公网 ip 或者域名: http://<YOUR_PUBLIC_IP>:8080

  • 如果暂时用不到 DNS 功能,可以先将 magic_dns 设为 false。

  • listen_addr改为http://0.0.0.0:8080

  • 可自定义私有网段,也可同时开启 IPv4 和 IPv6:

 ip_prefixes:
   # - fd7a:115c:a1e0::/48
   - 100.64.0.0/16
  1. 创建 SystemD service 配置文件
vi /etc/systemd/system/headscale.service

填入内容

# /etc/systemd/system/headscale.service
[Unit]
Description=headscale controller
After=syslog.target
After=network.target

[Service]
Type=simple
User=headscale
Group=headscale
ExecStart=/usr/local/bin/headscale serve
Restart=always
RestartSec=5

# Optional security enhancements
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/lib/headscale /var/run/headscale
AmbientCapabilities=CAP_NET_BIND_SERVICE
RuntimeDirectory=headscale

[Install]
WantedBy=multi-user.target

运行

  1. 创建 headscale 用户
useradd headscale -d /home/headscale -m
  1. 修改 /var/lib/headscale 目录的 owner
chown -R headscale:headscale /var/lib/headscale
  1. Reload SystemD 以加载新的配置文件
systemctl daemon-reload
  1. 启动 Headscale 服务并设置开机自启
systemctl enable --now headscale
  1. 查看运行状态
systemctl status headscale
  1. 查看端口占用
ss -tulnp|grep headscale
  1. 创建用户
headscale namespaces create <USERNAME>

随便填个你喜欢的名字,如:

headscale namespaces create default
  1. 查看命名空间
headscale namespaces list

返回形如以下

xxxx-xx-xxTxx:xx:xx+xx:xx TRC DNS configuration loaded dns_config={"Nameservers":["1.1.1.1"],"Resolvers":[{"Addr":"1.1.1.1"}]}
ID | Name    | Created
1  | default | xxxx-xx-xx xx:xx:xx

最后,别忘了放行相关端口

客户端接入

先安装 Tailscale,尽量下载最新版

macOS/iOS

访问 http://<YOUR_PUBLIC_IP>:8080/apple,里面会有指引

Windows

访问 http://<YOUR_PUBLIC_IP>:8080/windows,里面会有指引

他们 Markdown 格式可能有点问题,请忽略……

<USERNAME> 换成你之前定义的名称即可。

如果运行命令后没有反应,可能是需要管理员权限启动。

Android

点击右上角更多 ,点击Change server,填入http://<YOUR_PUBLIC_IP>:8080,点击Save and restart App 重启,点击 Sign in with other即可。

如果没有Change server的选项,反复点开关闭几次。

如果你已经登入了官方的,Log out 即可。

Linux

步骤略多且不同发行版可能不同,请参考其他文章。