最近有远程组网的需求。一个月,尝试了FRP,使用60秒断连2分钟;尝试了Wireguard,家里NAS和路由器死活连不上。@Holegots 推荐了Tailscale和它的开源版本控制器Headscale,试了一下,真的丝滑。
啥是Tailscale
你可以理解为VPN,或者说Wireguard外面包了一层壳子。它可以将一些设备连接起来,形成一个虚拟局域网。一个很简单的例子,你可以在星巴克里,读取家里任意电脑上的文件。
为啥要用Tailscale?Wireguard它不香么?是啊,Wireguard很香,配置很简单(么?),但是我尝试了整整一个月都没组网成功,还要各种配置防火墙啥的。还有就是,如果需要访问其他设备,Wireguard需要你自己在本地将所有设备添加到列表里面。虽然我只有有限个设备(手机,Mac,NAS,路由器),但是添加一个设备就需要全部配置一遍IP列表,这个事儿十分不爽。加上我是强迫症,手动分配ip简直要了老命。Tailscale就方便多了:你只需要登录,就完事儿了,它会自动把节点信息下发给所有设备。
OpenVPN之类的东西也成,ZeroTire之类的东西也成,但,如果用TailScale的话,应该是目前见过的最简单有免费的异地组网了:20个设备,各个设备上登录一下,完。并且还能直接访问其他内网短,十分顺滑。
啥是Headscale
饿,看名字就知道是和Tailscale对着干的。
Tailscale的客户端是不收费的,服务端是不开源的,超过20个设备就需要付费了(毕竟大家都不是做慈善的)。Headscale是个第三方开源版本的Tailscale的服务端,除了「网站界面」之外该有的功能都有。
所以,行动方案是?
- 先能最简单地使用TailScale
- 自己的Mac和Nas上,使用Tailscale作为客户端
- 找个地方部署Headscale服务端,然后切换到自己的服务上
那我们开始吧
Tailscale注册和登录
额,这个,没啥难度,就不表了
Mac端:AppStore版客户端
也没啥难的。从AppStore里面下载出来,登录账号,完事儿。
iPhone端:AppStore版客户端
也没啥难的。从AppStore里面下载出来,登录账号,完事儿。
但是如果你的手机不能魔法上网的话……有很小概率会不能登录。所以先有鸡还是先有蛋呀?
Linux端:物理机部署
来这个网址,照着教程做就好了。就几句话。
Linux端:Docker部署
首先我们创建一个 docker-compose.yaml
配置文件,大概写成这样:
version: "3.3"
services:
tailscaled:
container_name: tailscaled
image: tailscale/tailscale
network_mode: host
privileged: true
restart: always
devices:
- "/dev/net/tun:/dev/net/tun"
cap_add:
- NET_ADMIN
- NET_RAW
volumes:
- "path/to/config/folder:/var/lib"
- "/lib/modules:/lib/modules"
command: sh -c "mkdir -p /var/run/tailscale && ln -s /tmp/tailscaled.sock /var/run/tailscale/tailscaled.sock && tailscaled"
如果不加最后那个command,可能会报错。
部署完后,Linux端需要自行登录。如果是docker,需要先使用 docker exec -it headscaled /bin/sh
进入容器。
- 如果只是想访问这一个设备,并不想访问子网:
tailscale up
- 如果还想访问子网中的所有设备:
tailscale up --accept-routes=true --accept-dns=true --advertise-routes=192.168.1.0/24
然后去网页版里面,允许一下这个设备的子网即可。
哦对了,主机上还需要稍微做一下处理:
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
自建Headscale服务端
服务端:Docker部署
作为一个洁癖,我选择了来无影去无踪的Docker。
version: "3.6"
services:
headscale:
image: headscale/headscale:latest-alpine
container_name: headscale
volumes:
- path/to/config:/etc/headscale/
- path/to/data:/var/lib/headscale
ports:
- 8080:8080 # 如果用nginx反代,那么可以不暴露这个
command: headscale serve
restart: unless-stopped
cap_add:
- CAP_NET_BIND_SERVICE
除此之外,我们还需要手动新建一下配置文件:
wget https://github.com/juanfont/headscale/raw/main/config-example.yaml -O config.yaml
把它放到上面提到的config文件夹里。然后编辑一下它:
server_url
这个东西是一个简单的「HTTP设备认证页面」,需要暴露在公网上,其他设备如果想加入到你的网络里面,需要访问这个地址,拿到一个Token。有域名的话推荐用域名+nginx/caddy反向代理(于是这里写成实际访问的域名,反代的时候上了https的话就写https),没域名的话用ip+端口凑合凑合也成。listen_addr
这个东西是实际监听的地址,推荐保持默认metrics_listen_addr
这个东西是监控指标用的,保持默认,或者监听0.0.0.0
都可以ip_prefixes
可以根据自己喜好来改,留默认的当然也行randomize_client_port
这个东西,开不开都可以
其他就没啥好改的了,然后我们启动docker。
下一步,创建一个「租户」,你可以理解为一个用户。使用docker exec -it headscale /bin/sh
进到headscale的docker里面,执行
headscale namespaces create SOME_NAME
最后那个SOME_NAME自己随意替换,记得住就好。
如果你需要使用域名,那么用nginx/caddy反代一下容器的8080口就好了。
不过官方使用教程里面我有一点没看懂:它说默认的private_key_path
是不可写的,我不知道是不是也要把这个目录给映射到磁盘上。
哦对了,防火墙:
- 如果你只想「安安静静地做个用户」,那么放行一下nginx反代时候的端口就好了。
- 如果你没用反代,那么放行
listen_addr
里面的端口 - 如果你用了监控面板,那么放行
metrics_listen_addr
里面的端口 - 如果你用了远程控制,那么放行
grpc_listen_addr
里面的端口 - 如果你还用到了EDRP这个高级功能,那么放行
stun_listen_addr
里面的端口,注意这个是UDP的
Mac端:AppStore版客户端
由于是使用的「非官方版控制器」,所以我们需要稍微hack一下,将软件里面默认的「tailscale官方控制服务器地址」改为我们自己搭建的Headscale地址。
访问 http://server_url/apple
,下载并安装一个描述文件。
然后打开Tailscale,点击登录,会看到一个英文界面,里面有一行命令
headscale -n NAMESPACE nodes register --key SOME_HEX_VALUE
将里面的NAMESPACE换成你创建的租户名称,然后去服务端docker里面,执行它。你就会发现,你的mac已经登录成功了。
Linux端:Docker版客户端
和上面基本一样。
- 如果只是想访问这一个设备,并不想访问子网:
tailscale up --login-server=http://server_url
- 如果还想访问子网中的所有设备:
tailscale up --login-server=http://server_url --accept-routes=true --accept-dns=true --advertise-routes=192.168.1.0/24
会提示你访问一个网址,拿到Token,回到Server端进行登录就好。
然后,登录过后,去服务端,找到对应的设备,并开启路由
headscale nodes list
headscale routes enable -i X -r "192.168.1.0/24"
第二条命令里面的 X
是第一条命令里面查询到的设备的id,后面子网范围和登录时候的子网范围一致。
会有啥问题么
额,还是有的……
- 可能是我的设置不对还是咋的,我本来我想要个「双保险」,把树莓派和NAS都设置了可以访问内网
192.168.1.0/24
网段,于是好像流量成环了😭不知道「双保险」应该怎样配置。 - 我没允许dns,于是在外面访问的时候,各种内网的
.local
和.lan
域名都用不了,需要强行记IP,或者去路由器上查IP,不太爽。 - 不要在Docker里搞子网。各种报错,速度巨慢,原因不明。人生苦短,别为难自己
参考资料
- 官方手册:如何在Linux下部署HeadScale
- 官方手册:如何在Docker里运行HeadScale
- 官方手册:如何反代HeadScale
发表回复