前言:被校园网逼出来的需求
这傻逼校园网 TCP、UDP 双双 NAT-4,打洞是别想了;给的 IPv6 还是 fe80 开头的,既没有入站也没有出站,不理解这 IPv6 给的有什么意义。这学期新的无线网甚至还做了 LAN 隔离,内网都不让我按 IP 直接访问自己的设备,怎会如此!
旧的无线网目前还在,但不知道什么时候会被关掉,所以我迫切需要新的办法来访问自己的设备。以前没有异地组网的需求,早就听说 Tailscale 很好用,只是一直没机会试,现在正好来尝尝咸淡 😋。
为什么直接用 sing-box 的 Tailscale
因为我本来就在用 sing-box 的 tun 入站,而 sing-box 从 1.12 起就支持 tailscale endpoint 了,那就直接用它,没必要再装一遍官方客户端——多出来一个 tun 代理,冲突也不好解决。
我说 sing-box tun 无敌有没有懂的?自 1.15.0 起,sing-tun 用上了自研的 TCP/IP stack,极限性能、能效和内存占用都大幅领先所有旧实现。Android 侧也完整支持 auto_redirect 了:以前在 root 过的安卓上跑 sing-box 裸核、开 tun 入站,热点流量会被直接 drop,现在热点流量也能转发,就很……

sing-box 玩家的福报
咳,扯远了,回正题。
配置
一、加一个 endpoint
简单翻了翻文档,接入 Tailscale 出乎意料地简单。Tailscale 本身就是 WireGuard 的下游产品,密钥、身份认证、访问控制这些统统不用自己操心,只要在配置里加上这么一段:
"endpoints": [
{
"type": "tailscale",
"tag": "ts-ep",
"hostname": "Laptop"
}
]
没错,这就加完了。之后在 sing-box 的 API dashboard 里就能登录、查看状态了。

dashboard 里的 Tailscale 工具页:状态、本机设备名,以及在线设备列表

点开设备还能看到 MagicDNS 域名、主机名、双栈地址,以及 PING 和 TAILDROP 的入口
二、补上出站和 MagicDNS
不过上面只解决了入站,出站和 DNS 还得再配一下,同样很简单。
dns.servers 里加:
{
"type": "tailscale",
"tag": "ts",
"endpoint": "ts-ep",
"accept_search_domain": true
}
accept_search_domain 是为了能直接解析单标签主机名。
dns.rules 里加:
{
"preferred_by": "ts",
"server": "ts"
}
route.rules 里加:
{
"preferred_by": "ts-ep",
"outbound": "ts-ep"
}
以上就是全部配置。
实际效果
Tailscale 真的相当好用:面板里能看在线设备信息,能 ping 测试,还能用 Taildrop 直接发文件。
设备都在旧的校园网里时,它直接走内网:

内网直连,33.4 ms
换到新的校园网(LAN 隔离 + NAT-4)时,打洞就别想了,但还能走 DERP 中继服务器兜底:

DERP 中继连接,550.5 ms,区域是 sfo
550 毫秒确实称不上快,不过能用就行。总的原则是:只要两边不都是完全对称的 NAT-4,Tailscale 就会尝试借助 STUN 服务器打通 P2P 直连,直连不通再回退到 DERP 中继,可用性还是有保证的。
还有主机名解析:

直接 ssh 主机名 -p 8022 就能连上手机,不用记那个会变的 10.x 内网 IP
再也不用记动态内网 IP 了。