Tailscale接入Headscale及DERP中继服务器的搭建配置和使用
Headscale 是 Tailscale控制端的开源实现,Tailscale控制端是不开源的,用户可免费使用添加20个节点,但不支持自定义网段,还需要邮箱登陆!Headscale的出现完美解决了这一切,下面来记录下搭建过程及注意事项。
Headscale服务器搭建:
从作者github下载最新版本的二进制文件
wget https://github.com/juanfont/headscale/releases/download/v0.15.0-beta5/headscale_0.15.0-beta5_linux_amd64 -O /usr/local/bin/headscale &&chmod +x /usr/local/bin/headscale
创建配置目录:
mkdir -p /etc/headscale
创建目录用来存储数据与证书:
mkdir -p /var/lib/headscale
创建空的 SQLite 数据库文件:
touch /var/lib/headscale/db.sqlite
创建 headscale 用户:
useradd headscale -d /home/headscale -m
更改 /var/lib/headscale 目录的所有者为headscale:
chown -R headscale:headscale /var/lib/headscale
修改/var/lib/headscale/db.sqlite文件所有者为headscale
chown -R headscale:headscale /var/lib/headscale/db.sqlite
创建 SystemD 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
下载 Headscale 示例配置文件
wget https://github.com/juanfont/headscale/raw/main/config-example.yaml -O /etc/headscale/config.yaml
修改配置文件中的 unix_socket:
unix_socket: /var/lib/headscale/headscale.sock
- server_url 设置为 http://<PUBLIC_IP>:8080,将 <PUBLIC_IP> 替换为公网 IP
或者域名。如果是国内服务器,域名必须要备案。没备案的,直接填公网 IP 。 - DNS默认会覆盖客户端dns设置,所以需要把nameservers:1.1.1.1这里的全局DNS服务器设置为国内可用的.或者注册节点时–accept-dns=false命令关闭
restricted_nameservers:为拆分dns设置,用来给下面设置的域名指定dns解析服务器,为内网dns服务器时要启用routes确认可达
domains:为搜索域,例如填入 .co,浏览器直接输入 go 访问时为其查询go.co
的dns记录(内网查询需配合拆分dns域名设置使用) 把magic_dns 为
true是自动给客户端分配域名,base-domain为自定义域名后缀,分配格式为,主机名+namespaces+basedomain - ip_prefixes:自定义私有网段,可同时开启 IPv4 和 IPv6地址分配
启动 Headscale 服务并设置开机自启:
systemctl enable --now headscale
查看运行状态:
systemctl status headscale
查看占用端口:
ss -tulnp|grep headscale
创建一个 namespace,类似用户组
headscale namespace create ceshi
查看命名空间:
headscale namespaces list
Tailscale接入篇
目前除了 iOS 客户端,其他平台的客户端都有办法自定义 Tailscale 的控制服务器。
Linux
Tailscale 官方提供了各种 Linux 发行版的软件包,还提供了静态编译的二进制文件,我们可以直接下载。
wget https://pkgs.tailscale.com/stable/tailscale_1.22.2_amd64.tgz
解压
tar zxvf tailscale_1.22.2_amd64.tgz
将二进制文件复制到官方软件包默认的路径下:
cp tailscale_1.22.2_amd64/tailscaled /usr/sbin/tailscaled
cp tailscale_1.22.2_amd64/tailscale /usr/bin/tailscale
将 systemD service 配置文件复制到系统路径下:
cp tailscale_1.22.2_amd64/systemd/tailscaled.service /lib/systemd/system/tailscaled.service
将环境变量配置文件复制到系统路径下:
cp tailscale_1.22.2_amd64/systemd/tailscaled.defaults /etc/default/tailscaled
启动 tailscaled.service 并设置开机自启:
systemctl enable --now tailscaled
接入headscale命令
tailscale up --login-server=http://127.0.0.1:8080 --accept-routes=true --accept-dns=false
将http://127.0.0.1换成你的 Headscale 公网 IP或域名 –accept-dns=false 拒绝配置dns到客户端
执行上面的命令后,会出现类似下面的信息:
To authenticate, visit:
http://xxxxxx:8080/register?key=905cf165204800247fbd33989dbc22be95c987286c45aac303393704
1150d846
复制 key= 后面的内容到headscale所在服务器终端中输入下面的命令注册
headscale -n ceshi nodes register --key 905cf165204800247fbd33989dbc22be95c987286c45aac3033937041150d846
ceshi 要更换为你上面自己创建的namespaces名称
Android
Android平台接入需要编译apk有点麻烦,好在有大神在github有项目可以在线自动编译,只需要 fork 他的GitHub 仓库 tailscale-android,然后在你的仓库中点击 Settings 标签,找到 Secrets 下拉框中的 Actions 选项,选择 New repository secret 添加一个 secret 叫 HEADSCALE_URL,将你的 Headscale 服务公网地址填入其中,然后点击 Actions 标签,选择 Release Workflow。你会看到一个 Run workflow 按钮,点击它,然后在下拉框中点击 Run workflow。然后流水线就会开始执行,执行成功后就会在 Release 页面看到编译好的 apk,编译过程会持续几分钟耐心的等哈,下载编译好的apk安装到手机,打开点击Sign in with other就会弹出包含key的链接,复制key到服务器注册Ok(步骤同上),android接入成功。
Windows
Windows Tailscale 客户端想要使用 Headscale 作为控制服务器,只需在浏览器中打开 URL:http://<HEADSCALE_PUB_IP>:8080/windows,便会出现如下的界面:
按照其中的步骤操作即可。
其他 Linux 发行版
除了常规的 Linux 发行版之外,还有一些特殊场景的 Linux 发行版,比如 OpenWrt、威联通(QNAP)、群晖等,这些发行版的安装方法已经有人写好了,这里就不详细描述了,我只给出相关的 GitHub 仓库,大家如果自己有需求,直接去看相关仓库的文档即可。
OpenWrt:https://github.com/adyanth/openwrt-tailscale-enabler
群晖:https://github.com/tailscale/tailscale-synology
威联通:https://github.com/ivokub/tailscale-qpkg
iOS
Tailscale iOS 客户端源代码没有开源,目前还无法破解使其使用第三方控制服务器,遗憾~~
进阶玩法
打通内网
假设你的家庭内网有一台 Linux 主机(比如 OpenWrt)安装了 Tailscale 客户端,我们希望其他 Tailscale 客户端可以直接通过家中的局域网 IP(例如 192.168.100.0/24) 访问家庭内网的任何一台设备。
配置方法很简单,首先需要设置 IPv4 与 IPv6 路由转发,并关闭防火墙(也可以添加某些规则放行,但是我不会,直接关闭简单粗暴),在安装了 Tailscale 客户端的Linux主机上执行如下命令:
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
修改客户端注册节点的命令,在原来命令的基础上加上参数 –advertise-routes=192.168.100.0/24
tailscale up --login-server=http://<HEADSCALE_PUB_IP>:8080 --accept-routes=true --accept-dns=false --advertise-routes=192.168.100.0/24
在 Headscale 端查看路由,这时可以看到相关路由是关闭的。
– i ID 为节点ID序号 nodes list 命令
headscale routes list -i $NODE_ID
开启路由命令:
headscale routes enable -i 6 -r "192.168.100.0/24"
在节点查看路由
ip route show table 52|grep "192.168.100.0/24"
可能你会在节点上看不到上述路由,不用担心,你只要在任意一个客户端上可以ping通内网主机,那么你的路由配置正确的,否则你需要检查headscale端对应节点的路由是否启用,如果可以ping通但不能访问内网服务,你需要关闭tailscale所在linux主机的防火墙,OK你现在可以在任何一个 Tailscale 客户端所在的节点访问家庭内网的机器了,就像在家里一样用同样的 IP 访问家中的任意一个设备。
好了完成上面这些,基本就可以不用登陆不受限制的白嫖使用Tailscale节点组建虚拟内网了,无奈tailscale的官方节点都在国外(原因你懂的),访问速度感人……
搭建私有中继节点DERP server
Headscale 0.15.0版本已内置derp server,这样headscale既做为控制器也做为一个derp节点,省去了derp的搭建。步骤与单独搭建类似,在配置里启用derp,内置derp转发工作在443端口,stun监听在3478端口,直接搭建在443未占用情况下应该会自动申请证书部署https访问,如果需要与nginx整合,在nginx配置文件内添加
derp代理
location / {
proxy_pass http://127.0.0.1:8080; # headscale listen_addr
proxy_read_timeout 6m;
proxy_ignore_client_abort off;
proxy_request_buffering off;
proxy_buffering off;
proxy_no_cache "always";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Websockets
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
SSL证书
listen 443 ssl http2;
ssl_certificate /etc/nginx/ssl/headscale.domain.com/fullchain.crt;
ssl_certificate_key /etc/nginx/ssl/headscale.domain.com/key;
}
如果有多站点就复制内容到对应站点nginx配置文件内,端口修改为headscale监听端口,证书修改为你的证书所在路径,如果有bt面板之类的可以直接部署证书开启https后,再添加以上配置,重启nginx即可开启内置derp server,注意与nginx整合后客户端访问地址即为https://你的域名,不用加端口号,另外location / 路径不能更改,经测试改了以后客户端无法注册!
安装golang环境
部署最新的derper服务,要求golang版本为最新1.18版本,不想装go环境,可以下载编译好的二进制文件
下载
wget https://golang.google.cn/dl/go1.18.linux-amd64.tar.gz
解压Go目录到/usr/local
tar -xvf go1.18.linux-amd64.tar.gz -C /usr/local
修改环境变量
vi /etc/profile
// 在最后一行添加
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin
source命令使变量生效
source /etc/profile
go -version 看下go是否安装成功
安装derper
go install tailscale.com/cmd/derper@main
默认使用443端口,会自动申请3个月的Let’sSSL的免费证书,derper服务域名是必须的,所以这里 –hostname=your-hostname.com 填写的域名要正确解析到derper所在服务器
sudo derper --hostname=your-hostname.com
加入 –verify-clients 命令验证防止被白嫖(要安装tailscale,未验证)
sudo derper --hostname=your-hostname.com --verify-clients
自定义端口运行
使用自定义端口需要自有域名做好解析,并申请SSL证书,准备好申请好的域名和对应的证书,并把证书重命名为:your-hostname.crt 和 your-hostname.key
在/usr/local/go/bin目录下编写如下启动脚本 保存为runderper.sh
cd /usr/local/go/bin
nohup ./derper -hostname your-hostname -c derper.conf -a :8082 -http-port -1 -certdir /cert -certmode manual -stun-port 8087 &
echo $! > app.pid # 其中your-hostname 替换为你的域名/cert 替换为你证书存放路径,8082为更改的derp端口,8087为更改的stun端口,这两个端口添加到防火墙放行
在/usr/local/go/bin目录下编写如下停止脚本 保存为stopderper.sh
!/bin/sh
kill cat app.pid
rm -rf app.pid
/etc/systemd/system目录中添加服务脚本 derper.service 内容如下
Description=derper服务
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/gopath/bin/runderper
ExecStop=/usr/local/gopath/bin/stopderper.sh
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now headscale
浏览器访问https://域名:自定义端口,能正常访问且有加锁标志即为derper成功运行
在Headscale中加入derper中继节点
部署好 derper 之后,就可以修改 Headscale 的配置来使用自定义的 DERP 服务器了。Headscale 可以通过两种形式的配置来使用自定义 DERP:
一种是在线 URL,格式是 JSON,与 Tailscale 官方控制服务器使用的格式和语法相同。
另一种是本地文件,格式是 YAML。
我们可以直接使用本地的 YAML 配置文件,内容如下:
/etc/headscale/derp.yaml
regions:
900:
regionid: 900
regioncode: thk
regionname: Tencent Hongkong
nodes:
- name: 900a
regionid: 900
hostname:
ipv4:
stunport: 8087
stunonly: false
derpport: 8088
- name: 900b
regionid: 900
hostname:
ipv4:
stunport: 8087
stunonly: false
derpport: 8088
901:
regionid: 901
regioncode: hs
regionname: Huawei Shanghai
nodes:
- name: 901a
regionid: 901
hostname: xxxx
ipv4:
stunport: 8087
stunonly: false
derpport: 8088
配置说明:
- regions 是 YAML 中的对象,下面的每一个对象表示一个可用区,每个可用区里面可设置多个 DERP 节点,即 nodes。
- 每个可用区的 regionid 不能重复。
- 每个 node 的 name 不能重复。
- regionname 一般用来描述可用区,regioncode 一般设置成可用区的缩写。
- ipv4 字段不是必须的,如果你的域名可以通过公网解析到你的 DERP
服务器地址,这里可以不填。如果你使用了一个二级域名,而这个域名你并没有在公共 DNS server
中添加相关的解析记录,那么这里就需要指定 IP(前提是你的证书包含了这个二级域名,这个很好支持,搞个泛域名证书就行了)。 - stunonly: false 表示除了使用 STUN 服务,还可以使用 DERP 服务。
修改 Headscale 的配置文件,引用上面的自定义 DERP 配置文件。需要修改的配置项如下:
paths:
- /etc/headscale/derp-example.yaml
paths:
- /etc/headscale/derp.yaml
可以把 Tailscale 官方的 DERP 服务器禁用,来测试自建的 DERP 服务器是否能正常工作。
重启 headscale 服务生效:
systemctl restart headscale
在 Tailscale 客户端上使用以下命令查看目前可以使用的 DERP 服务器:
tailscale netcheck
此命令实际上只检测stun 3478/udp 的端口, 就算 netcheck 显示能连,也不一定代表 8088 端口可以转发流量。最简单的办法是直接打开 DERP 服务器的 URL:https://xxxx:8088,如能打开页面,且地址栏的 SSL 证书标签显示正常可用,那才是真没问题了。
其他命令
预生成 authkey 减少服务端同意环节
生成key(有效期24小时)
headscale --namespace namespaces preauthkeys create --reusable --expiration 24h
查看已生成的key
headscale preauthkeys -n NAMESPACE list
节点用--authkey 接入
tailscale up --login-server https://headscale.domain.com --accept-routes=true --accept-dns=true --authkey $KEY
tailscale status
tailscale ping 100.64.0.1