headscale私有部署
需求
办公需求:
设备:
1、synology DS918+
2、macbook pro m1
3、mac mini
问题:访问家里nas慢的问题,及工作效率能快速访问的问题公司跨机房需求:
1、erp金蝶系统-sqlServer服务-公司内部机房
2、采购系统-mongodb服务-阿里云服务器
问题:采购系统上访问ERP速度慢的问题,及双流cdc的需求
设想这样一个问题:在北京和上海各有一台局域网的机器
(例如一台是家里的台式机,一 台是连接到星巴克 WiFi 的笔记本),二者都是私网 IP 地址,但可以访问公网, 如何让这两台机器通信呢
?
既然二者都能访问公网,那最简单的方式当然是在公网上架设一个中继服务器: 两台机器分别连接到中继服务,后者完成双向转发。这种方式显然有很大的性能开销,而 且中继服务器很容易成为瓶颈。
有没有办法不用中继,让两台机器直接通信呢
?
那就是:跨过公网(互联网)实现端到端
直连。
TailScale 是什么, Headscale又是什么
TailScale
TailScale 你可以理解为 VPN,或者说 Wireguard 外面包了一层壳子。它可以将一些设备连接起来,形成一个虚拟局域网。一个很简单的例子,你可以在星巴克里,读取家里任意电脑上的文件。
比如最常见的需求就是,公司有一个内网办公环境,当你外出办公时,也希望你的电脑能够接入办公网络。 因为外网的机器和内网的机器不能互联,所以一般会有一个中心服务器, 所有的子节点都和中心服务器相连,然后中心服务器转发所有的流量。
这样做的缺点显而易见,首先是中心服务器(hub)会成为瓶颈
。 其次,某种极端情况下,如果节点 A 和 节点 B 距离非常近,但是都离 hub 很远, 这样就会导致非常高的延迟。
那么我们就会想,能不能让节点间直接互联呢? 这就是 mesh VPN,其实现就是 wireguard。
wireguard 的每一个节点都会存储其他所有节点的信息,并且和其他所有的节点都建立 tls 连接。 如果涉及到内网穿透的话,那么你需要找到一台处于网关位置的节点(内外网都可达),将其设置为 coordinator, 扮演类似于 hub 的角色, 分发穿透内外网的流量。
wireguard 的缺点在于:
- 配置比较繁琐
- 维护也比较困难,增删节点都需要改动所有节点的配置
基于上述这些痛点,TailScale 做了一些改进:
1、在原有的 ICE、STUN 等 UDP 协议外,实现了 DERP TCP 协议来实现 NAT 穿透
2、基于公网的 coordinator 服务器下发 ACL 和配置,实现节点动态更新
3、通过第三方(如 Google) SSO 服务生成用户和私钥,实现身份认证
对我来说 Tailscale 相对于 Wireguard 最大的优势有 3 点:
1、配置简单
2、支持 P2P 和中继自动切换
3、支持自建中继节点
作为一种搭建虚拟局域网的工具,相比于传统VPN而言,所有节点之间都可以进行P2P连接,也就是全互联模式,效率更高。
为了基于wireguard实现更完美的VPN工具,现在已经出现了很多项目,如Netmaker,通过可视化界面来配置全互联模式,并支持UDP打洞、多租户等高端功能,几乎适配所有平台。然而现实世界是复杂的,无法保证所有的NAT都能打洞成功,而且Netmaker目前不支持fallback机制,如打洞失败,无法fallback中继节点。而Tailscale支持fallback,可以尽最大努力实现全互联模式,部分节点即使打洞不成功,也可通过中继节点在虚拟局域网内畅通无阻。
简而言之,我们可以认为 TailScale 是更为易用版的、功能封装更为完善的 wireguard。
Headscale
Headscale看名字就知道是和 Tailscale 对着干的,Tailscale 的客户端是不收费的,服务端是不开源的,超过 20 个设备就需要付费了,并且Tailscale的服务不在国内,我们不可能把服务端安全的交给Tailscale,私有自建才是出入。Headscale 是个第三方开源版本的 Tailscale 的服务端,除了「网站界面」之外该有的功能都有,因此我们使用Headscale自建私有服务。
解决方案
所以本次的方案:
1、阿里云服务器 部署 Headscale 服务端
2、自己的 Mac 和 Nas 上,使用 Tailscale 作为客户端
或公司,mongodb所在的服务器与sqlServer所在的服务器组网
服务端
Docker 部署
1 | version: '3.5' |
手动新建一下配置文件,放入./config
1 | wget https://github.com/juanfont/headscale/raw/main/config-example.yaml -O config.yaml |
编辑一下它:
- server_url 这个东西是一个简单的「HTTP 设备认证页面」,后面需要暴露在公网上,其他设备如果想加入到你的网络里面,需要访问这个地址,拿到一个 Token。有域名的话推荐用域名+nginx/caddy 反向代理没域名的话用 ip+端口。
- ip_prefixes 可以根据自己喜好来改,留默认的当然也行
docker-compose up -d
启动 docker
下一步,创建一个「租户」,你可以理解为一个用户。进到 headscale 的 docker 里面,执行
1 | headscale namespaces create SOME_NAME |
SOME_NAME随意替换
客户端
并非全部客户端都支持(或全部支持)将 Headscale 作为后端,目前适配情况如下:
操作系统 | 支持情况 | 解决方案 |
---|---|---|
Linux | ✅ | 原生支持 |
Windows | ✅ | 修改注册表 |
macOS | ✅ | 需要添加描述文件 |
Android | ✅ | |
iOS | ❌ | 目前不支持 |
Mac 端:AppStore 版客户端
由于是使用的「非官方版控制器」,所以我们需要稍微 hack 一下,将软件里面默认的「tailscale 官方控制服务器地址」改为我们自己搭建的 Headscale 地址。
访问 http://server_url/apple
,下载并安装一个描述文件。
然后打开 Tailscale,点击登录,会看到一个英文界面,里面有一行命令
1 | headscale -n NAMESPACE nodes register --key SOME_HEX_VALUE |
将里面的 NAMESPACE 换成你创建的租户名称,然后去服务端 docker 里面,执行它。你就会发现,你的 mac 已经登录成功了。
Linux端:Docker 版客户端
1 | version: '3.3' |
启动容器后,需要进入容器,输入这个东西进行登录:
1 | tailscale up --login-server=http://server_url --accept-routes=true --accept-dns=false |
如果没问题,那么会提示你访问一个网址,拿到 Token,回到 Server 端进行登录就好。
synology
Access Synology NAS from anywhere
Tailscale Packages
tailscale up 参数
- –hostname
设置名称 - –accept-routes 接受服务端配置的路由
- –accept-dns 推荐将 DNS 功能关闭,因为它会覆盖系统的默认 DNS
- –advertise-routes
申请路由到该节点,Tailscale 实现「出口节点」,即打通局域网内部的路由访问,这个网段的所有设备都可以被访问 - –advertise-exit-node 可以建立数据导向节点exit node,即本机访问互联网皆通过此节点 bolean
- –exit-node
指定出口节点,导向所有流量经这出口节点
headscale命令
通过服务端授权客户端
1 | headscale -n default nodes register --key 905cf165204800247fbd33989dbc22be95c987286c45aac3033937041150d846 |
查看注册的节点
1 | headscale nodes list |
通过 Pre-Authkeys 接入
前面的接入方法都需要服务端同意,步骤比较烦琐,其实还有更简单的方法,可以直接接入,不需要服务端同意。
首先在服务端生成 pre-authkey 的 token,有效期可以设置为 24 小时:
1 | headscale preauthkeys create -e 24h -n default |
查看已经生成的 key:
1 | headscale -n default preauthkeys list |
现在新节点就可以无需服务端同意直接接入了:
1 | tailscale up --login-server=http://<HEADSCALE_PUB_IP>:8080 --accept-routes=true --accept-dns=false --authkey $KEY |
打通局域网
假设你的家庭内网有一台 Linux 主机(比如 Nas)安装了 Tailscale 客户端,我们希望其他 Tailscale 客户端可以直接通过家中的局域网 IP(例如 192.168.100.0/24) 访问家庭内网的任何一台设备。
官方文档:Subnet routers and traffic relay nodes
群辉具体操作见:headscale组网打通群辉局域网内部访问
linux 配置方法很简单,首先需要设置 IPv4 与 IPv6 路由转发:
1 | echo 'net.ipv4.ip_forward = 1' | tee /etc/sysctl.d/ipforwarding.conf |
客户端修改注册节点的命令,在原来命令的基础上加上参数 --advertise-routes=192.168.100.0/24
。
1 | tailscale up --login-server=http://<HEADSCALE_PUB_IP>:8080 --accept-routes=true --accept-dns=false --advertise-routes=192.168.100.0/24 |
在 Headscale 端查看路由,可以看到相关路由是关闭的。
1 | headscale nodes list|grep nas |
开启路由:
1 | headscale routes enable -i 6 -r "192.168.100.0/24" |
其他节点查看路由结果:
1 | ip route |
现在你在任何一个 Tailscale 客户端所在的节点都可以 ping 通家庭内网的机器了
为了能让headscale稳定,我们可以自建中继服务器
headscale之DERP中继服务器自建