---
url: /article/vyunvvy3/index.md
---
## 前言

之前在[OpenWrt系统使用](/article/0be86xd9/#_2-1-tailscale)一文中介绍了`Tailscale`，今天有重新提起，是因为`Stash`更新了[重磅功能](https://stash.wiki/proxy-protocols/proxy-types#tailscale)，支持`Tailscale`类型的节点，并且可以配置`Exit Node`。这意味着完全可以把 Stash 作为 Tailscale 的客户端使用，并且可以和官方客户端有同样的使用体验。\
为了实现利用出口节点访问内网，可以有多种方式安装 Tailscale：在 Openwrt 中安装、在 Docker 中安装、在任一台设备上安装。当然，安装了Tailscale 这个客户端必须得处于内网中，最好是 7\*24 小时运行。那最好的方式就是安装在软路由或者Nas中。\
今天主要记录在 OpenWrt 中安装并使用 Tailscale。

## 1. 最小化安装

访问[small-tailscale-openwrt](https://github.com/CH3NGYZ/small-tailscale-openwrt)，这是一个在 OpenWrt 上最小化安装的方式，支持自动更新。

* 优点：仅内核运行，资源占用小。
* 缺点：无界面，操作不友好。

## 2. 带界面安装

### 2.1 luci-app-tailscale

[luci-app-tailscale](https://github.com/asvow/luci-app-tailscale)是之前介绍过的，不过仓库已经归档了，不再更新。但是这仅仅是不更新界面了，可以自己手动更新内核。更新内核可以看这个仓库[openwrt-tailscale](https://github.com/GuNanOvO/openwrt-tailscale)。

* 优点：支持界面上启动/停止。
* 缺点：界面配置项较少。

对于新手还是推荐这个插件，配置方便，使用简单。

### 2.2 luci-app-tailscale-community

[luci-app-tailscale-community](https://github.com/Tokisaki-Galaxy/luci-app-tailscale-community)原本是一个开源的社区插件，但是已经合并到了 OpenWrt 上，因此如果用的是 OpenWrt 系统，可以直接在软件包内搜索`luci-app-tailscale-community`并安装。

对于其他分支的如：ImmortalWrt，可以选择添加源或者手动上传软件包安装。而这同样也只是一个界面，同样需要额外案例内核使用。

* 优点：界面配置项比较多，展示信息丰富度高于 luci-app-tailscale。
* 缺点：界面目前不支持启动/停止，需要通过终端执行命令启停。

首页选项较多，这里说一下各选项的意思：

**防火墙模式**：看你的防火墙类型，通常默认用的是`iptables`，如果你安装了`nftables`防火墙，那么就选这个。

**必选**：

* \[x] 通告出口节点
* \[x] 允许局域网访问

**可选**：

* \[ ] 接受路由
* \[ ] 启用Web界面

**注意**：通过界面做的一些设置即使保存了，也只是把配置值写入到了文件，实际上并没有生效，还需要重启 Tailscale 才行。可界面上没有操作按钮，只能通过终端执行如下命令：

```bash
# 列出所有的服务
service
# 启动 tailscale
service tailscale start
# 停止 tailscale
service tailscale stop
# 重启 tailscale
service tailscale restart
```

## 注意事项

使用`luci-app-tailscale-community`时，会看到最下面的说明：
![PixPin\_2026-03-28\_06-33-28](https://cdn.jsdelivr.net/gh/mayeona/picx-images-hosting@master/20260328/PixPin_2026-03-28_06-33-28.7pv4wxlf9.webp)

**接受路由**可以不勾选，它的含义是，当 Tailscale 网络中存在其他节点暴露出子网（subnet，即内网）时，本节点是否接受。在当前内网穿透场景下，是否自选都无影响。

**通告出口节点**被勾选后，表示暴露出整个子网（如 192.168.0.0/24）。但是需要注意在这里勾选后还没生效，只是相当于发起了一个申请，还需要去 Tailscale 控制台在`Machines`栏下点击属于 OpenWrt 上运行的那个节点设备，在`Subnets`下的`Awaiting Approval`点击`Edit`，做如下勾选以批准才生效：
![PixPin\_2026-03-28\_06-59-28](https://cdn.jsdelivr.net/gh/mayeona/picx-images-hosting@master/20260328/PixPin_2026-03-28_06-59-28.4joochd50r.webp)

**自动配置防火墙**被点击后，可能会出现一种情况，其它节点从本节点出口时，只能访问到内网，无法从内网出去。这其实是防火墙配置的问题，少了**tailscale ⇒ wan**的区域转发。\
OpenWrt 的防火墙视图把多种权限策略集成到一起展示了，就会显得很绕，不容易理解。以下是一个正常的防火墙配置：
![PixPin\_2026-03-28\_06-40-32](https://cdn.jsdelivr.net/gh/mayeona/picx-images-hosting@master/20260328/PixPin_2026-03-28_06-40-32.6f19530zi8.webp)
防火墙有 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（在路由器处转换），这样百度响应时才能找到路由器的公网，然后路由器再根据自身的映射找到内网中对应的设备。

什么时候需要动态伪装呢？就是数据包从某个网卡发出去后离开了路由器，就需要开动态伪装。\
举例：

1. lan(192.168.0.8) -> 路由器 -> wan(220.202.110.232)，因为从 wan 网卡出去就到了公网，所以从 wan 网卡出去就需要开启`动态伪装`。
2. lan(192.168.0.8) -> 路由器 -> tailscale(100.64.0.88)，因为从 tailscale 网卡出去就到了 Tailscale 的网络，所以从 tailscale 网卡出去就需要开启`动态伪装`。

所以总结起来就一点，看 z1 的 左 边，只要最终从这个网卡离开路由器，就需要开启动态伪装。因此，第 ②、③ 两行需要勾选`Masquerading`。

## 其他仓库

还有一些相关仓库可以看看：[luci-app-tailscale](https://github.com/whzhni1/luci-app-tailscale)、[openwrt-tailscale-enabler](https://github.com/adyanth/openwrt-tailscale-enabler)。
