前言
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处进行更改,注意修改RegionCode
、RegionName
、IPv4
、DERPPort
的值,因为我的服务器没有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_url
为https://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.pem
和yourip.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!提示就算是完成了登录。