【Tailscale】自建境内Headscale实现点对点直连异地组网

发布于 / 信息应用 / 13 条评论

Tailscale是一个与ZeroTier、Netbird等工具类似的异地组网工具,支持通过STUN打洞实现客户端点对点直连,互联协议基于go实现的WireGuard,兼具高效与安全的特性。

简单而言,Tailscale可以不受限于服务器带宽,使位于不同的网络环境下的设备获得类似于同一局域网下的体验。

Headscale是Tailscale的一个开源服务端,通过go语言完整地支持了绝大多数Tailscale的基础功能,使Tailscale能够完全工作于独立自建的服务端之上。近期恰逢Parsec受到干扰,对未来ZeroTier官方服务在大陆的稳定性有了一些担忧,于是研究了一下自建Headscale服务器的流程。整个过程都是手动安装,在此做一些简单的记录。

小提示:无论上述哪一种异地组网工具,官方均有商业化的服务器提供,并且有25设备的免费额度。官方服务器除国际链路导致的中继不够稳定外其他功能均可正常使用,因此轻度的使用博主并不推荐盲目自建服务器,请根据个人需求进行权衡,毕竟官方服务器+自建转发也是一种很好的选择。


原理概述

Tailscale服务器端分为两部分,包括负责通信与认证的Headscale服务器负责打洞和转发的DERP服务器,其工作模式细节可以参考官方博客(点击前往)。以两台计算机为例,它们首先分别通过Tailscale客户端注册至Headscale服务器,在建立通信时先通过Headscale服务器交换握手信息,随后分配到合适的DERP服务器进行中继连接和STUN打洞。若打洞成功,两端将在Headscale服务器引导下绕过服务器建立点对点的直连隧道;若打洞失败,两端将保持通过DERP服务器中继的互联模式。

Tailscale、ZeroTier和Netbird都是功能相似的优秀异地组网工具,且均支持自建服务器。与ZeroTier相比,Tailscale功能更丰富、自建更为简便,同时WireGuard效率更高;缺点是Tailscale客户端资源占用略高(要求RAM>512M)。与Netbird相比,Tailscale起步较早实践资料和可用插件更多(如OpenWRT Luci-UI,点击前往),并且不强制要求独占80与443端口;缺点是WireGuard在go下性能略逊于内核态,同时Headscale并非Netbird一样由官方支持。权衡之下,博主认为Headscale是目前自建比较简单、易用的选择。


环境准备

Tailscale在端对端通信中会通过STUN打洞建立基于UDP的WireGuard通讯链路,虽然并不需要公网IP,但需要上级路由器开启upnp以允许UDP隧道建立和维持,流量穿透原理可以参考官方博客(点击前往)。在国内的家庭网络中,NAT类型主要为Full Cone(NAT1)、Port Restricted Cone(NAT3)和Symmetric(NAT4),打洞难度从依次递增,可以通过NatTypeTester这个工具(点击前往)进行测试。在博主实测中,办公室校园网(NAT3)与中国电信5G(NAT3)能够正常打洞直连,而办公室校园网(NAT3)与某园区网(NAT4)无法打洞直连,完全通过中继连接,只有对端为中国移动(NAT1)时成功打洞直连。

综合目前博主自己的测试结果,只要两端NAT类型在NAT3及以上,打洞直连对Tailscale而言并不困难;但若一端为NAT4,则除对端为NAT1外Tailscale均无法打通直连。NAT4即对称型NAT,是NAT四种类型中最为严格的一种,其从原理上阻止了打洞的可能性,因此Tailscale在这类网络下只能提供基于服务器中转的连接。在部署Tailscale前,应提前评估在个人使用场景中的可行性,并且尽量改善网络NAT类型(如开启upnp、设置DMZ主机、开启IPv6等)。因为博主对打洞的原理了解浅薄,这段文字可能并不严谨,欢迎补充和指正~

在优化点对点互联质量的方法中最为触手可得的就是IPv6,虽然部分地区的IPv4环境较为恶劣,但目前政府主导以去NAT化为目标部署的IPv6(点击前往)大大改善了这一现状。Headscale能够完整地支持IPv6服务,但需要DERP节点同样具有IPv6地址。如果自建的DERP节点不配置IPv6,只能通过官方的海外节点进行IPv6 STUN打洞。

【Tailscale】自建境内Headscale实现点对点直连异地组网

腾讯云轻量应用服务器目前成都地域已全量开放IPv6支持,北京、上海已在国庆前开放内测,非常符合博主的需要。腾讯轻量IPv6无需额外付费,点击开启、简单易用(可以戳图片从博主之前的文章了解),并且工程师们也在积极地为目前诟病的IPv4-IPv6带宽包合并努力。博主此次就是将Headscale和其DERP搭建在了腾讯云双栈的轻量应用服务器上,国内的互联互通效果非常不错。若大家有类似的需求,可以随时到腾讯云官网选购轻量应用服务器,即开即用、方便快捷。


程序准备

我们用到的项目主要为本体Headscale(点击前往)和其WebUI之一的Headscale-admin(点击前往)。其中Headscale是一个go的二进制可执行文件,Headscale-admin是一个静态的网页程序,所以从博主的角度觉得直接配合NGINX本地运行比docker更为轻量简便。如果倾向于使用docker,可以按照它们的文档中提供的流程进行部署。

在此分享一个博主验证过自用的包,其内容与本文一致,供大家参考:

下载地址:蓝奏云

因为Headscale-admin本质上只是个静态站点,所有的请求均通过浏览器发起,所以在实际使用中只需要注意Headscale-admin页面与Headscale API之间跨域的问题即可。有一点需要注意,Headscale 0.23.0版本中将增加设备的nodekey字段改为了mkey,导致Headscale-admin中无法新建设备(详见issue),在分享的版本中博主对此进行了修改。


配置文件

标准化的安装和具体的参数解释请参考Headscale官网(点击前往)和Github(点击前往),在此不再赘述。以下是一个带有注释的完整headscale 0.23.0版本配置文件,从个人用户手动维护的角度出发,博主建议不遵循Linux社区的配置规范,将所有相关的文件安放于同一目录下(如配置中的/home/headscale目录),以便备份和迁移。

而在单机部署中,需要修改的内容主要如下:

① 第02行:Headscale服务域名
② 第15行、36行、69行:密钥和数据库路径
③ 第17行:虚拟局域网IP段
④ 第33行:DERP STUN服务端口
⑤ 第38行:DERP服务器IP
⑥ 第82行:虚拟局域网MagicDNS域名


用于引入其他自建DERP服务器的derp.yaml示例如下,请根据实际修改并在上方Headscale配置文件对应位置引入。


自启动配置

如下将文件路径修改正确后,在systemd目录下创建headscale.service,即可通过service headscale start|stop|restart管理进程状态,确认无误后使用systemctl enable headscale允许开机自启。因为是自用,博主直接使用root用户启动进程,若对安全有额外的需求请新建一个headscale用户进行运行。


NGINX配置

Headscale仅从/key/ts2021/derp/api四个路径进行数据交换,但鉴于官方并未明确说明,博主还是推荐对Headscale全局/路径进行反向代理。其中,要单独为headscale-admin静态站点进行排除和指向,若全局反向代理影响证书签发可使用相同的方法。


防火墙配置

在以上的配置中,Headscale进程启用了HTTP协议监听本地的主服务(8080)、Mertics(9090)和grpc(50443)三个端口,在需要时均可以通过NGINX转发至标准端口并绑定域名,无需单独对外放通。唯一需要额外放通的是转发服务DERP STUN的UDP端口3478端口(或设定的端口号),基本满足了简单、安全和与其他服务共存的需要。


若使用云服务器搭建,则要额外注意在安全组中放通IPv4和IPv6的端口(图中为腾讯云控制台)


客户端配置

按照博主的方法自建Headscale完成后,在运行命令时要先cd /home/headscale进入Headscale目录下,再通过./headscale执行命令,比如通过./headscale apikeys create --expiration 9999d创建一个9999天的密钥(默认为30天)。然后进入https://xxx.web/admin进入headscale管理页面,取消勾选Legacy API并填入API密钥即可登陆管理页面。注意,管理页面Headscale-admin所有信息均储存在本地浏览器中,且仅通过本地浏览器与API通讯,请在可信的设备上进行操作。

登陆成功后可以在Users中新建一个用户,随后即可向用户添加设备。在认证之前先可以通过Deploy页面勾选需要的功能生成指令,用于引导客户端登陆Headscale服务器并开启相应的功能。

电脑端可以从官网下载(点击前往),安装完成后使用配置好的命令直接cmd运行进行认证登陆即可,弹出的mkey则需要从Nodes页面Create设备,若使用PreAuthkey进行无交互认证则需先从Users下创建再进行选择。此外内网Advertise Routes网段在路由后,需要从Headscale-Admin的Routes页面进行放通以开放内网广播。以下是几个简单的实例:


手机端同样可以从Google Play或官网下载(点击前往),随后可以从右上角设置Accounts右上角菜单Alternate Server进入设置,其余操作大同小异。路由器端需要从OpenWRT源(点击前往)下载对应架构较新的最小化构建.ipk包,同时下载Luci App及语言包(点击前往)两个.ipk包,将三个文件置于路由器同一个文件夹下使用opkg install *安装即可。如果内存不宽裕,可以添加go的GOMEMLIMIT=100MiB环境变量,以约束Tailscale使用的内存。客户端的使用这部分网络上有大量的资料可供参考,三言两语很难说得清楚,在此不再过多赘述。


结语

结尾没什么好说的,刚刚告别了国庆假期,祝大家在一年之末工作顺利、生活愉快吧~

整个折腾过程就是让异地组网合规风险小了一些,别的也没有什么实质性的改变。博主在这方面属实了解甚少,有不足的地方,欢迎大家在评论区补充和指正,谢谢大家~


*原创文章,转载请注明出处

转载原创文章请注明,转载自: Luminous' Home » 【Tailscale】自建境内Headscale实现点对点直连异地组网

  1. 我想问一下 ,没有https证书和密钥指向的地址吗

    1. @luci 我是配合NGINX反代在使用的,所以证书配置不需要在headscale里管理。如果你直接暴露headscale的话,那是需要添加证书相关配置的。
  2. 牛啊,最近刚有这个需求,马上实践一下,有结果了过来反馈!

  3. derper 还需要配置https证书吗

    1. @bdser 独立的DERPER最好是配置一下,不配置应该也能用,只是一个信息交换的API
  4. 博客逛多了,发现个有趣的事,技术流的博客搭配二次元的主题和配图

    1. @ccbbp 哈哈哈,应该都是个人爱好了~
  5. 博主,您好,蓝奏云盘的链接失效啦,能再分享一下不?谢谢

    1. @boris 不好意思粘错链接了,已经更新了~
  6. 4m小水管服务器,跑tailscale带宽受限么?

    1. @pace哈哈 如果打洞不通走了中继,会非常受限
  7. 话说在大陆服务器上跑https,域名不用备案的嘛?

    1. @lynaste 啊,我用了备案的域名……