feat: 维护页 Tailscale 管理(设备列表/改名/授权/密钥不过期/设置IP/auth key,独立模块 core/tailscale_client.py)+ 密钥迁移 .env(STF_TOKEN/WEB_SECRET_KEY/TAILSCALE_API_KEY 不再入库)+ 修复设备更新端点(/device/{id} 405,改用 /name /authorized /key 专属端点)+ auth key description 仅 ASCII

This commit is contained in:
2026-08-11 09:06:59 +08:00
parent a48032da23
commit de66c6194b
8 changed files with 547 additions and 9 deletions
+72
View File
@@ -667,3 +667,75 @@ adb 远程终端:用平台 adb 二进制执行任意 adb 命令(20s 超时
```
`result`:`命中` / `未找到` / `已执行`(无选择器命中语义的步骤)。
无"设备控制"权限返回 403。
---
## 15. Tailscale 管理(仅管理员)
维护页"Tailscale 管理"分区,调用 Tailscale 官方 API v2。所有接口仅管理员可用。
前置:`.env` 配置 `TAILSCALE_API_KEY`(Settings → API Access Tokens)与
`TAILSCALE_TAILNET`(tailnet 名,个人账号一般为邮箱前缀);未配置返回 502 并附提示。
设备 IP 由 tailnet 分配,API 不可修改,列表只读展示。
### GET /api/tailscale/status
配置状态检查。
**响应**:
```json
{"ok": true, "configured": false, "hint": "TAILSCALE_API_KEY(...);TAILSCALE_TAILNET(...)"}
```
### GET /api/tailscale/devices
列出 tailnet 全部设备。
**响应**:
```json
{"ok": true, "devices": [
{"id": "d1", "name": "dev-a", "hostname": "dev-a", "os": "linux",
"addresses": ["100.100.10.11"], "authorized": true,
"key_expiry_disabled": false, "online": true, "last_seen": "...", "tags": []}
]}
```
### POST /api/tailscale/devices/:device_id
更新设备(按传入字段分发到 Tailscale 专属端点,`POST /device/{id}` 本身是 405):
`name` → `/name` 显示名;`authorized` → `/authorized` 授权开关;
`key_expiry_disabled` → `/key`(true=密钥永不过期,即关闭设备密钥验证,恢复后按原定过期时间执行)。
**请求**(JSON):
```json
{"key_expiry_disabled": true}
```
### POST /api/tailscale/devices/:device_id/ip
设置设备的 Tailscale IPv4 地址(未公开端点,实测可用)。
**请求**(JSON):
```json
{"ipv4": "100.100.10.16"}
```
⚠ 改 IP 会断开设备当前 tailscale 会话;平台设备池 serial 随之变化,需同步更新 STF 设备池/分组/任务目标。
### DELETE /api/tailscale/devices/:device_id
从 tailnet 移除设备(下次上线需重新授权)。
### POST /api/tailscale/authkey
生成设备接入 auth key(key 只返回一次)。
**请求**(JSON):
```json
{"description": "新设备接入", "reusable": false, "ephemeral": false,
"preauthorized": true, "expiry_seconds": 3600}
```
**响应**:
```json
{"ok": true, "key": "tskey-auth-...", "id": "k1", "expires": "2026-08-11T01:00:00Z"}
```
+16 -2
View File
@@ -79,11 +79,20 @@ pip install -r requirements.txt
### 2.3 修改配置
编辑 `config.py`,**必须修改**以下两项:
**密钥类配置统一放项目根目录 `.env`**(已被 `.gitignore` 排除,不会提交到 git;
`config.py` 不再内置任何密钥):
```ini
# .env 示例
STF_TOKEN=你的STF_API_Token
WEB_SECRET_KEY=随机字符串(会话密钥,python -c "import secrets;print(secrets.token_hex(32))" 生成)
TAILSCALE_API_KEY=你的Tailscale_API_key
```
`config.py` 只改非密钥项,如 `STF_URL`:
```python
STF_URL = "http://你的STF地址:端口"
STF_TOKEN = "你的STF_API_Token"
```
其他配置按需调整:
@@ -95,6 +104,11 @@ STF_TOKEN = "你的STF_API_Token"
| `ADB_PATH` | 自动识别 | 用自定义 adb 时修改 |
| `STF_SSH_TARGET` | `[email protected]` | 维护页"一键重启 STF 容器"的 SSH 目标(需免密登录) |
| `STF_DOCKER_CONTAINER` | `stf` | 220 上 STF Docker 容器名(`docker ps` 查看) |
| `TAILSCALE_TAILNET` | 按邮箱前缀 | tailnet 名称/ID(个人账号一般为登录邮箱前缀) |
> **未配置 `WEB_SECRET_KEY`**:启动时随机生成(每次重启登录态失效,生产务必配置固定值)。
> **维护页 Tailscale 前置**:`.env` 写入 `TAILSCALE_API_KEY` 后重启服务;
> 未配置时管理分区显示明确提示,不影响其他功能。
> **维护页 STF 重启前置**:本机需能免密 SSH 到部署机(把本机公钥加入目标机 `authorized_keys`),
> 且 `STF_DOCKER_CONTAINER` 与真实容器名一致;未配置好时按钮会返回明确错误。