OpenWrt上使用Tailscale
前言
之前在OpenWrt系统使用一文中介绍了Tailscale,今天有重新提起,是因为Stash更新了重磅功能,支持Tailscale类型的节点,并且可以配置Exit Node。这意味着完全可以把 Stash 作为 Tailscale 的客户端使用,并且可以和官方客户端有同样的使用体验。
为了实现利用出口节点访问内网,可以有多种方式安装 Tailscale:在 Openwrt 中安装、在 Docker 中安装、在任一台设备上安装。当然,安装了Tailscale 这个客户端必须得处于内网中,最好是 7*24 小时运行。那最好的方式就是安装在软路由或者Nas中。
今天主要记录在 OpenWrt 中安装并使用 Tailscale。
1. 最小化安装
访问small-tailscale-openwrt,这是一个在 OpenWrt 上最小化安装的方式,支持自动更新。
- 优点:仅内核运行,资源占用小。
- 缺点:无界面,操作不友好。
2. 带界面安装
2.1 luci-app-tailscale
luci-app-tailscale是之前介绍过的,不过仓库已经归档了,不再更新。但是这仅仅是不更新界面了,可以自己手动更新内核。更新内核可以看这个仓库openwrt-tailscale。
- 优点:支持界面上启动/停止。
- 缺点:界面配置项较少。
对于新手还是推荐这个插件,配置方便,使用简单。
2.2 luci-app-tailscale-community
luci-app-tailscale-community原本是一个开源的社区插件,但是已经合并到了 OpenWrt 上,因此如果用的是 OpenWrt 系统,可以直接在软件包内搜索luci-app-tailscale-community并安装。
对于其他分支的如:ImmortalWrt,可以选择添加源或者手动上传软件包安装。而这同样也只是一个界面,同样需要额外案例内核使用。
- 优点:界面配置项比较多,展示信息丰富度高于 luci-app-tailscale。
- 缺点:界面目前不支持启动/停止,需要通过终端执行命令启停。
首页选项较多,这里说一下各选项的意思:
防火墙模式:看你的防火墙类型,通常默认用的是iptables,如果你安装了nftables防火墙,那么就选这个。
必选:
可选:
注意:通过界面做的一些设置即使保存了,也只是把配置值写入到了文件,实际上并没有生效,还需要重启 Tailscale 才行。可界面上没有操作按钮,只能通过终端执行如下命令:
# 列出所有的服务
service
# 启动 tailscale
service tailscale start
# 停止 tailscale
service tailscale stop
# 重启 tailscale
service tailscale restart注意事项
使用luci-app-tailscale-community时,会看到最下面的说明: 
接受路由可以不勾选,它的含义是,当 Tailscale 网络中存在其他节点暴露出子网(subnet,即内网)时,本节点是否接受。在当前内网穿透场景下,是否自选都无影响。
通告出口节点被勾选后,表示暴露出整个子网(如 192.168.0.0/24)。但是需要注意在这里勾选后还没生效,只是相当于发起了一个申请,还需要去 Tailscale 控制台在Machines栏下点击属于 OpenWrt 上运行的那个节点设备,在Subnets下的Awaiting Approval点击Edit,做如下勾选以批准才生效: 
自动配置防火墙被点击后,可能会出现一种情况,其它节点从本节点出口时,只能访问到内网,无法从内网出去。这其实是防火墙配置的问题,少了tailscale ⇒ wan的区域转发。
OpenWrt 的防火墙视图把多种权限策略集成到一起展示了,就会显得很绕,不容易理解。以下是一个正常的防火墙配置:
防火墙有 3 行配置:①、②、③,我把它划分为三个区域:z1(zone,区域)、z2、z3,其中 z1 分为:左、右,两边。
区域间转发(看 z1 区域):
| 行 | 流量转发 | 场景 |
|---|---|---|
| ① | 允许 lan ⇒ wan | 流量从 lan 网卡到 wan 网卡。内网设备发起到公网的请求(baidu.com),流量路径:device -> lan -> wan -> baidu。 |
| ① | 允许 lan ⇒ tailscale | 流量从 lan 网卡到 tailscale 网卡。Tailsclae 网络中的 OpenWrt 节点下的内网设备,请求 Tailsclae 网络中的其他节点设备,流量路径:device0 -> lan -> tailscale -> device1。 |
| ① | 拒绝 lan ⇒ other | 流量从 lan 网卡到 其他网卡。因为暂无其他网卡配置,所以默认会有这一项拒绝其他区域。 |
| ② | 拒绝 wan ⇒ other | 流量从 wan 网卡到 其他网卡。为了安全,从公网主动发过来的请求统统被拒绝,不会到达任一网卡,防止被人恶意扫描和爆破。 |
| ③ | 允许 tailscale ⇒ lan | 流量从 tailscale 网卡到 lan 网卡。Tailsclae 网络中的其他节点访问 OpenWrt 节点下的子网设备,流量路径:device0 -> tailscale -> lan -> device1。 |
| ③ | 允许 tailscale ⇒ wan | 流量从 tailscale 网卡到 wan 网卡。Tailsclae 网络中的其他节点通过 OpenWrt 节点出口访问到公网(baidu.com),流量路径:device -> tailscale -> wan -> baidu。 |
| ③ | 拒绝 tailscale ⇒ other | 流量从 tailscale 网卡到 其他网卡。因为暂无其他网卡配置,所以默认会有这一项拒绝其他区域。 |
前面说的自动配置防火墙后无法通过出口节点访问公网,就是缺少了 ③ 中允许 tailscale ⇒ wan这项配置。
网卡出入站(看 z1 和 z2 区域):
站是数据交换中心,这里指的就是路由器。
input(入站)、output(出站)、forward(转发),这里都是以z1左的视角来看待的。
| 行 | z1(左) | z2(input) | z2(output) | z2(forward) |
|---|---|---|---|---|
| ① | lan | accept。允许流量从lan网卡入站到路由器。场景:内网设备发起请求。流量经过:device -> lan -> 站 - - > wan/tailscale | accept。允许流量从路由器出站到lan网卡。场景:请求到达内网设备。流量经过:wan/tailscale - - > 站 -> lan -> device | accept。允许流量在 lan 网卡自身转发,即内网中的设备互相访问,数据只在内网交互,只会经过 lan 网卡。流量经过:device0 -> lan -> device1 |
| ② | wan | reject。拒绝流量从wan网卡入站到路由器。场景:阻挡所有从公网的主动请求。流量经过:wan -❌-> 站。 | accept。允许流量从路由器出站到wan网卡。场景:设备要访问公网(baidu.com)时。流量经过:tailscale/lan - - > 站 -> wan - - > baidu | reject。拒绝流量在lan网卡自身转发。场景:设备直接通过 wan 网卡与公网中其他设备互相访问。流量经过:device0 -❌-> wan -❌-> device1 |
| ③ | tailscale | accept。允许流量从tailscale网卡入站到路由器。场景:Tailscale 网络下的设备发起请求到达路尊起。流量经过:device -> tailscale -> 站 - - > lan/wan | accept。允许流量从路由器出站到tailscale网卡。场景:请求到达Tailscale 网络下的设备。流量经过:lan/wan - - > 站 -> tailscale -> device | accept。允许流量在 tailscale 网卡自身转发,即 Tailscale 网络中的设备互相访问,数据只在 Tailscale 网卡交互,只会经过 Tailscale 网卡。流量经过:device0 -> Tailscale -> device1 |
动态伪装(看 z1 和 Z3 区域):
首先需要知道什么是动态伪装,动态伪装(Masquerading)说白了就是 NAT 动态地址转换。
当内网设备(192.168.0.8)要访问百度(baidu.com)时,如果不开启动态伪装,那么源IP 就是内网IP,当百度响应请求时根本找不到这个内网IP 设备在哪。所以,必须得把内网IP 转换成公网IP(在路由器处转换),这样百度响应时才能找到路由器的公网,然后路由器再根据自身的映射找到内网中对应的设备。
什么时候需要动态伪装呢?就是数据包从某个网卡发出去后离开了路由器,就需要开动态伪装。
举例:
- lan(192.168.0.8) -> 路由器 -> wan(220.202.110.232),因为从 wan 网卡出去就到了公网,所以从 wan 网卡出去就需要开启
动态伪装。 - lan(192.168.0.8) -> 路由器 -> tailscale(100.64.0.88),因为从 tailscale 网卡出去就到了 Tailscale 的网络,所以从 tailscale 网卡出去就需要开启
动态伪装。
所以总结起来就一点,看 z1 的 左 边,只要最终从这个网卡离开路由器,就需要开启动态伪装。因此,第 ②、③ 两行需要勾选Masquerading。
其他仓库
还有一些相关仓库可以看看:luci-app-tailscale、openwrt-tailscale-enabler。
