前言
由于国内的网络状况,连接tailscale官方的服务器不稳定,延迟很高,所以像zerotier一样,自建Moon服务器是比较好的。
但是Tailscale 的控制服务器是不开源的,而且对免费用户有诸多限制。好在目前有一款开源的实现叫 Headscale。
服务器端搭建
你需要:一台有公网IP的服务器
访问Github页面下载安装文件,我的服务器系统为Ubuntu20.04LTS,所以选择deb格式的安装包,当然,直接下载二进制文件自己配置也是一样的。
wget --output-document=headscale.deb \
https://github.com/juanfont/headscale/releases/download/v0.22.3/headscale_0.22.3_linux_amd64.deb
安装headscale
sudo dpkg --install headscale.deb
出现这个页面就安装成功了
设置开机自启动
sudo systemctl enable headscale
编辑配置文件
vim /etc/headscale/config.yaml
按照你自己的需求更改,如果你不懂每一项的意思,先修改以下的选项
server_url: http://1.1.1.1:8080
listen_addr: 0.0.0.0:8080
grpc_listen_addr: 0.0.0.0:50443
ip_prefixes:
- 192.168.100.0/24
server_url改为你自己的服务器IP地址或者域名。
ip_prefixes在示例中的配置文件是分配ipv6的,但是我不需要,就删除了,同时,将100网段改为10或192网段,这是tailscale获取到的IP地址,在国内,100网段被运营商用来分配大内网IP了,所以不改的话会出现很多问题
headscale 启动!!!
sudo systemctl start headscale
查看运行状态
systemctl status headscale
运行成功
一些可能的问题:
推荐使用一台全新的服务器来安装headsscale,90%以上的问题是由于你的服务器本身安装的软件有冲突
headscale官方团队是不建议使用反向代理软件,如nginx、caddy等,但是实际上使用起来并不会有太大的问题,你可以参考这篇文章
补充
这里补充一下使用nginx反向代理时的配置方法:
nginx的配置文件
map $http_upgrade $connection_upgrade {
default keep-alive;
'websocket' upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
ssl_certificate <PATH_TO_CERT>;
ssl_certificate_key <PATH_CERT_KEY>;
ssl_protocols TLSv1.2 TLSv1.3;
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;
}
}
headscale配置文件
server_url: https://example.com
listen_addr: 0.0.0.0:8080
grpc_listen_addr: 0.0.0.0:50443
ip_prefixes:
- 192.168.100.0/24
将上述的example.com换成你自己的域名就可以了,假设你的nginx listen的是8081端口,headscale配置文件中的server_url也要加上8081端口,不用ssl的话,server_url也要用http代替https,并且,下面所有的login_server应该与你的server_url一样。
客户端搭建
openwrt
由于openwrt涉及一个本地路由的问题,所以我们先配置openwrt。
安装软件
opkg update
opkg install libustream-openssl ca-bundle kmod-tun
opkg install tailscale
注册tailscale
tailscale up --login-server=https://example.com:8080 --accept-routes=true --accept-dns=false
这里的login-server后也可换成你的ip
初始化成功后会出现URL,复制nodekey后的密钥
登录安装headscale的服务器
headscale users create admin # 创建一个用户
headscale --user admin nodes register --key nodekey:<YOUR_MACHINE_KEY> # <YOUR_MACHINE_KEY>换成你的密钥
注册成功,查看节点
headscale nodes list
设置 openwrt的tailscale 开机自启动
/etc/init.d/tailscale enable
接下来我们启用本地路由
先配置ipv4和ipv6的路由转发
echo 'net.ipv4.ip_forward = 1' | tee /etc/sysctl.d/ipforwarding.conf
echo 'net.ipv6.conf.all.forwarding = 1' | tee -a /etc/sysctl.d/ipforwarding.conf
sysctl -p /etc/sysctl.d/ipforwarding.conf
这里需要注意,一旦你对openwrt的接口进行过修改,包括但不限于多拨等操作,你需要重新运行以上代码,不然会出现节点列表显示在线,但是无法连上的情况
客户端修改注册节点的命令,在原来命令的基础上加上参数 –advertise-routes=192.168.1.0/24,告诉 Headscale 服务器 “我这个节点可以转发这些地址的路由”。
tailscale up --login-server=http://<HEADSCALE_PUB_IP>:8080 --accept-routes=true --accept-dns=false --advertise-routes=192.168.1.0/24 --reset
查看openwrt的路由
headscale nodes list
# 找到openwrt对应的id,查看它的路由
headscale routes list -i 1
可以看到enabled为False,改为True
headscale routes enable -r 1
这样就开启成功了,其他节点启动时需要增加 --accept-routes=true
选项来声明 “我接受外部其他节点发布的路由”。现在你在任何一个 tailscale 客户端所在的节点都可以 ping 通 openwrt 路由器所在内网的机器了。
Windows
接下来我们在windows上安装tailscale
在tailscale官网上下载安装包,安装好后先退出tailscale。
以管理员权限启动终端,输入以下命令,记得改为你自己的服务器地址
New-ItemProperty -Path 'HKLM:\Software\Tailscale IPN' -Name UnattendedMode -PropertyType String -Value always
New-ItemProperty -Path 'HKLM:\Software\Tailscale IPN' -Name LoginURL -PropertyType String -Value https://YOUR-HEADSCALE-URL
然后启动tailscale,点击log in你应该就会被重定向到自己的服务器,但是我运行后并不成功,所以采用另一种方法
仿照Linux,打开终端,输入
tailscale up --login-server <YOUR_HEADSCALE_URL> --accept-routes=true
运行后会出现一条URL,复制nodekey,按照上述同样的方法注册,注册成功后再启动tailscale程序,就登录成功了
安卓
下载并安装安卓端的tailscale程序,打开后点击右上角的三个点,一开始只会有版本号和About,然后再点击空白处,重复上述步骤,直到出现了Change Server选项
点击Change Server,改为自己的服务器地址,点击Save,回到程序主页面,不要用Google登录,点击sign in with other,会打开一个浏览器页面,复制node key,然后在服务器上注册,注册完成后回到程序就可以了
安卓端会自动允许route,不需要而额外操作
ios
没有ios设备,跳过
linux
Linux设备直接使用以下命令安装
curl -fsSL https://tailscale.com/install.sh | sh
默认该脚本会检测相关的 Linux 系统发行版并使用对应的包管理器安装 Tailscale, 安装完成后使用以下命令启动
tailscale up --login-server https://your.domain.com --accept-routes=true --accept-dns=false
启动完成后复制node key注册
常见问题
1、ERR error getting routes error="sql: database is closed"
问题现象:在修改过配置文件后重启服务,会卡在重启页面,查看systemctl status headscale
日志时出现下图的错误
解决方案:ps -ef|grep headscale
找到对应的pid,直接kill就行了,后续建议通过先stop,再restart来重启服务就不会卡住了
2、卸载headscale
sudo apt-get purge headscale
sudo apt-get autoremove
sudo apt-get clean
补充
headscale常用命令
headscale namespace list # 查看所有的namespace
headscale namespace create default # 创建namespace
headscale namespace destroy default # 删除namespace
headscale namespace rename default myspace # 重命名namespace
headscale node list # 列出所有的节点
headscale node ls -t # 列出所有的节点,同时显示出tag信息
headscale -n default node ls # 只查看namespace为default下的节点
headscale node delete -i<ID> # 根据id删除指定的节点,这里面的id是node list查询出来的id
headscale node tag -i=2 -t=tag:test # 给id为2的node设置tag为tag:test
headscale routes list -i=9 # 列出节点9的所有路由信息
headscale routes enable -i=9 -r=192.168.10.0/24 #将节点9的路由中信息为192.168.10.0/24的设置为true
# preauthkeys主要是方便客户端快速接入,创建了preauthkeys后客户端直接使用该key就可以直接加入namespace
headscale -n default preauthkeys list # 查看名称为default的namespace中已经生成的preauthkeys
headscale preauthkeys create -e 24h -n default # 给名称为default的namespace创建preauthkeys
# apikeys是为了客户端和headscale做http鉴权用的,http请求的时候需要设置头部authorization
# 值为固定的字符串"Bearer "加apikeys创建的key
headscale.exe apikeys create # 创建apikeys,在创建的时候需要记录下完整的值,后续查询出来的都是prefix
# 值类似于zs3NTt7G0w.pDWtOtaVx_mN9SzoM24Y02y6tfDzz5uysRHVxwJc1o4
headscale.exe apikeys list -o=json #查询headscale的apikeys,并将结果输出成json格式