前言

Tailscale是一个基于WireGuard虚拟组网工具,在功能和易用性上非常不错。

但Tailscale是商业软件,它的协调服务器是不开源的,免费版本也有一些限制,例如个人用户最多可以邀请2人加入网络,最多能使用100台设备。

而Headscale则是Tailscale协调服务器的开源版本,能实现Tailscale服务器的所有主要功能,所有的网络流量都由自己控制,也能解决部分地区对官方的协调服务器连通性的问题。

而DERP服务器则是用于帮助进行NAT穿透,在穿透失败后使用DERP服务器进行流量中继。

Tailscale官方的DERP虽然分布于全球各地,但不包含中国大陆,因此使用官方DERP服务器进行中继的,不仅延迟高,并且由于用户数目庞大,使用体验是十分糟糕的。

综上所述,我选择了自建Headscale和DERP服务器的方案。

(其实对绝大部分用户来说,自建DERP服务器已经足够了。)

解决方案

我选择了使用Docker部署derper,使用Nginx对headscale和headscale-ui进行反代并使用自签名证书,原因将在后文解释。

准备工作

  • 一台国内的云服务器

安装Tailscale

为了在后续derper设置中防止知道你服务器IP地址的用户对derper进行白嫖,我们需要现在云服务器安装Tailscale,下面演示Debian 12系统,其他系统请自行参考官网的安装说明。

因为官方PKG地址连接实在太慢,因此使用USTC的镜像源(注意:以下操作都在root用户下进行):

curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.noarmor.gpg | tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.tailscale-keyring.list | tee /etc/apt/sources.list.d/tailscale.list
sed -i 's,pkgs.tailscale.com/stable,mirrors.ustc.edu.cn/tailscale,g' /etc/apt/sources.list.d/tailscale.list
apt update
apt install tailscale -y

然后进行登录:

tailscale up

按照提示在浏览器中打开链接并登录,完成后会提示Success!

DERP Server

使用Docker部署

我推荐使用Docker部署,因为已经有大佬写好了纯IP的derper镜像,每天自动更新构建,我们只需拉取并使用这个镜像并创建容器就可以了,省去了自己安装环境,编译derper二进制文件的麻烦。

解释一下为什么不能使用官方的derper二进制文件:因为中国大陆地区搭建网站必须备案,而DERP协议运行在HTTP上,官方derper要求必须使用域名,因此官方的derper无法在中国大陆的服务器正常部署。 使用docker compose 进行部署:

mkdir -p /opt/derper && cd /opt/derper
vim compose.yaml
services:
  derper:
      image: 'ghcr.ly7ngf.top/yangchuansheng/ip_derper:latest'
      network_mode: bridge
      environment:
        - DERP_VERIFY_CLIENTS=true
        - DERP_CERTS=/app/certs
        - 'DERP_ADDR=:12345'
      volumes:
        - '/var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock'
      ports:
        - '3478:3478/udp'
        - '12345:12345'
      container_name: derper
      restart: always

添加volumes这一行的目的是为了让容器内的derper获取宿主机tailscaled服务的运行信息,从而防止其他人白嫖你的derper。

建议根据自己的需求修改配置后启动。

docker compose up -d

修改ACL配置

如果使用官方的协调服务器,则在WebUI的ACL处进行更改,注意修改RegionCodeRegionNameIPv4DERPPort的值,因为我的服务器没有IPV6,因此没有禁用默认的DERP服务器。

	"derpMap": {
		"Regions": {
			"901": {
				"RegionID":   901,
				"RegionCode": "xxxx",
				"RegionName": "xxxx",
				"Nodes": [
					{
						"Name":             "901a",
						"RegionID":         901,
						"DERPPort":         12345,
						"IPv4":             "yourip",
						"InsecureForTests": true,
					},
				],
			},
		},
	},

Headscale的操作会在后续进行说明。

Headscale

安装Headscale

Github Release下载deb包并使用SFTP上传到服务器,使用以下命令安装:

dpkg -i headscale_*_linux_amd64.deb

配置Headscale

编辑配置

vim /etc/headscale/config.yaml

修改server_urlhttps://yourip:54321

randomize_client_port设置为true

我个人用不到Magic DNS,因此将magic_dns设置为false

关于ACL,我使用远程的json格式设置derpmap,因为本地yaml格式不支持InsecureForTests选项

我选择在Github Gist上创建一个名为derpmap的Gist,然后写入如下内容:

{
  "Regions": {
    "901": {
      "RegionID": 901,
      "RegionCode": "xxxx",
      "RegionName": "xxxx",
      "Nodes": [
        {
          "Name": "901a",
          "RegionID": 901,
          "DERPPort": 12345,
          "IPv4": "yourip",
          "InsecureForTests": true
        }
      ]
    }
  }
}

随后在Headscale配置文件中引用这个文件的raw链接即可。

调整完配置后启动:

systemctl enable --now headscale

Nginx反代

签发证书

由于使用HTTP连接到Headscale总是会在服务器重启后无法登录,因此我使用自签名SSL证书实现HTTPS。

签发证书我推荐使用mkcert这个命令行工具,操作简单方便:

apt install libnss3-tools
curl -JLO "https://dl.filippo.io/mkcert/latest?for=linux/amd64"
chmod +x mkcert-v*-linux-amd64
cp mkcert-v*-linux-amd64 /usr/local/bin/mkcert

如果连接有问题可以现在本地下载完成再用SFTP上传到服务器。

使用这条命令安装CA证书:

mkcert -install

然后使用如下命令为你的IP创建一张证书:

mkcert yourip

应该会得到两个文件:yourip-key.pemyourip.pem,把它们移动到/opt/ssl这个目录:

mkdir -p /opt/ssl
mv yourip-key.pem /opt/ssl/key.pem
mv yourip.pem /opt/ssl/cert.pem

下载WebUI

为了方便配置,我们使用WebUI,从Realease下载最headscale-ui.zip,上传到服务器后解压并移动:

apt install unzip -y
unzip headscale-ui.zip
mkdir -p /var/www
mv web /var/www/headscale-ui

安装Nginx并配置

我是用的是N.WTF这个Nginx版本,安装命令如下:

apt install -y lsb-release ca-certificates apt-transport-https curl gnupg dpkg
curl -sS https://n.wtf/public.key | gpg --dearmor > /usr/share/keyrings/n.wtf.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/n.wtf.gpg] https://mirror-cdn.xtom.com/sb/nginx/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/n.wtf.list
apt update
apt install -y nginx-extras

修改刚刚的证书目录权限:

chown -R www-data:www-data /opt/ssl

然后新建一个Nginx配置文件:

vim /etc/nginx/conf.d/headscale.conf

写入如下内容

server {
    server_name yourip;
    location /web {
        alias /var/www/headscale-ui;
        index index.html;
    }
    location / {
        proxy_pass http://127.0.0.1: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;
    }
    listen 54321 ssl;
    ssl_certificate /opt/ssl/cert.pem;
    ssl_certificate_key /opt/ssl/key.pem;
}

然后启动Nginx:

systemctl enable --now nginx

使用Headscale

现在WebUI还不能访问,因为我们没有信任证书,在每台要使用Tailscale的设备上安装刚刚生成的CA证书,先用SFTP下载rootCA.pem,证书路径可以用mkcert -CAROOT找到。

各平台安装并信任CA证书的流程各不相同,在此不多赘述,(注意:Windows不支持安装.pem扩展名的证书,需要手动把扩展名改为.crt)。

然后使用Headscale生成一个apikey,用于WebUI:

headscale apikeys create

访问https://yourip:54321/web/settings.html,填入正确的apikey后点击Save API Key即可完成配置。

User View中点击New User新建一个用户,名称随意,保存即可。

Device View中选择New Device,按照Headscale 官方文档中的说明,在所有机器上重新登录Tailscale客户端,在打开的网页中复制mkey:xxxxxx的内 容,粘贴到Device Key中,Select User选择刚才创建的用户,点击对勾符号,等待终端出现Suceess!提示就算是完成了登录。