aio-plugin-portal 0.3.1-dev.12.g8cb41e6ffd09 → 0.3.1-dev.27.gc2f2c4fd9356

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -27,9 +27,79 @@ aio-plugin-portal plan # 只出计划,不写任何东西
27
27
  aio-plugin-portal sync # 渲染产物 + 执行 provider + 校验
28
28
  aio-plugin-portal sync --apply # 允许 provider 真实写入
29
29
  aio-plugin-portal doctor
30
+ aio-plugin-portal speed # 一键测速:对登记域名逐段计时,越慢越红
30
31
  aio-plugin-portal remove tc
31
32
  ```
32
33
 
34
+ ## 一键测速(登记处直接看快慢)
35
+
36
+ 登记表只说明「配置成什么样」,不说明「现在通不通、有多慢」。`speed` 从门户所在主机按用户真实路径
37
+ 逐段计时,是判断「这个域名是不是有问题」的第一现场。
38
+
39
+ ```sh
40
+ aio-plugin-portal speed # 全部启用条目,终端真彩色:绿→黄→橙→红
41
+ aio-plugin-portal speed tc dics --timeout 3000 # 只测指定别名
42
+ aio-plugin-portal speed --json # 结构化结果,给脚本/CI
43
+ aio-plugin-portal speed --no-color # 关掉 ANSI(重定向时自动关)
44
+ ```
45
+
46
+ 分段计时:`dns`(解析)→ `tcp`(建连)→ `tls`(握手)→ `ttfb`(首字节)。总耗时决定颜色,
47
+ 对数刻度映射 80ms→1500ms 到 绿→红;超过 800ms 加粗,异常固定深红。
48
+
49
+ 判定口径(不要只看「有没有响应」):
50
+
51
+ | 观察 | 结论 |
52
+ |---|---|
53
+ | DNS 解析失败、连接被拒绝、超时、5xx | **异常**,`speed` 退出码 1 |
54
+ | 证书过期 / 域名串名 / 证书链不完整 | **异常**(浏览器会直接拦) |
55
+ | 自建 CA(`UNABLE_TO_GET_ISSUER_CERT_LOCALLY`) | 正常,只标注「内网 CA 签发」 |
56
+ | 401 / 403 / 404 | 正常,标注「需鉴权」/`HTTP 404`:入口活着 |
57
+ | 443 根本没起,80 有响应 | 正常但明确标注「443 未启动,已退回 80」 |
58
+ | 已停用条目 | 不探测,标「跳过」;不算异常 |
59
+
60
+ 结果落盘 `<portal.root>/speedtest.json`(0600),设置界面刷新后仍按上次结果上色。
61
+
62
+ ## 设置界面(表格 + 云凭据)
63
+
64
+ ```sh
65
+ aio-plugin-portal serve # 默认 127.0.0.1:8120
66
+ aio-plugin-portal serve --listen 0.0.0.0:8120 # 显式绑定内网地址(凭据明文,谨慎)
67
+ aio-plugin-portal creds # 命令行的明文凭据视图
68
+ aio-plugin-portal creds set --provider huawei --keys <AK,SK> [--zone <ZoneID>] [--allow-public-write]
69
+ aio-plugin-portal creds probe --provider huawei
70
+ ```
71
+
72
+ 界面做两件事,都有 JSON 接口,便于以后接进 AIO:
73
+
74
+ - **服务登记表**:检索/可见性筛选/排序/分页/新增/编辑/停用/删除;删除走 `remove` 同一条链路,
75
+ 连带清理 Caddy 站点、解析覆盖与映射产物并反向校验。
76
+ - **一键测速**:页头按钮跑全部启用条目,每行「测速」只跑这一条;「延迟」列按同一套判据上色
77
+ (绿→黄→橙→红,越慢越红,异常深红),点表头按「异常优先、其次最慢」排序。悬停看分段耗时、
78
+ 解析地址与完整错误。接口:`GET /api/speed`(上次缓存)、`POST /api/speed {aliases?, timeoutMs?}`。
79
+ - **云凭据**:华为云 AK/SK、Cloudflare Token、DNSPod Token 直接编辑,按用户要求**明文展示**。
80
+ 华为云可「测试连接」列出可见 Zone 并自动填 Zone ID。
81
+
82
+ 凭据落盘在 `<portal.root>/cloud-credentials.json`(**0600**,明文),**不写进 `aliases.json`**;
83
+ 保存 key 不等于授权写公网记录,`allowPublicWrite` 是独立开关,默认关闭。
84
+
85
+ 华为云 AK/SK 使用 SDK-HMAC-SHA256 签名(`src/portal/providers/huawei-sign.ts`,金标对照官方
86
+ `huaweicloudsdkcore` 3.1.x 的输出)。不要照 AWS SigV4 的直觉改:canonical URI 必须补尾斜杠、
87
+ canonical query 的键值整串排序、空格编码 `%20`。
88
+
89
+ ## 唯一注册表(与 tunnel 控制台共用)
90
+
91
+ `aliases.json` 现在是**唯一一份**:`tunnel.addzero.site` 控制台与 `aio-portal` 读写同一文件,
92
+ 每条登记用 `edges` 声明归属入口,避免同一条别名在两处各登记一次:
93
+
94
+ - `localmesh`:本工具负责(182 的 localmesh Caddy 片段 + dnsmasq 解析 + 证书/策略校验);
95
+ - `home-edge`:tunnel 控制台负责(自己那台 Caddy + 公网 DNS + 证书)。
96
+
97
+ `plan` / `sync` / `render` 只处理 `edges` 含 `localmesh` 且未停用的条目;`list` 会显示全部条目,
98
+ 只归控制台的条目标成 `[外部入口]`。历史条目没有 `edges` 字段时仍按本地处理,行为和收敛前一致。
99
+
100
+ 本工具写入时只改自己管的字段,控制台写进来的 `domain`、`deviceId`、`accountId`、`dnsMode`、
101
+ `transport`、`tlsServerName`、`edges` 一律原样保留;反过来控制台保存也不会抹掉 `suffix`/`stream`/`tls`。
102
+
33
103
  ## 域名后缀
34
104
 
35
105
  `settings.suffix` 是默认后缀;单条记录可用 `--suffix` 覆盖,因此**同一套门户可以同时管理多个域**,
@@ -56,6 +126,25 @@ aio-plugin-portal remove tc
56
126
  - 只删除首行带 `# generated by aio-plugin-portal` 标记的文件;人工维护的同名站点既不删除,也不计入残留。
57
127
  - 反向:`add` / `render` 遇到同名但没有标记的文件会**拒绝覆盖**,不会悄悄顶掉手工配置。
58
128
 
129
+ ## 流式上游
130
+
131
+ 大屏推送、SSE、长轮询、WebSocket 上游被反代缓冲后会攒批甚至超时。登记时用 `--stream`:
132
+
133
+ ```sh
134
+ aio-plugin-portal add scene --host 192.168.31.133 --port 8993 --stream
135
+ aio-plugin-portal update gitlab --stream # 已有记录补上
136
+ aio-plugin-portal update gitlab --no-stream # 普通静态站可关掉
137
+ ```
138
+
139
+ 渲染结果是在 `reverse_proxy` 里加 `flush_interval -1`。
140
+
141
+ ## 落盘权限与生效方式(踩过的坑)
142
+
143
+ - 解析片段一律写成 **0644**;dnsmasq 以非 root 用户运行,0600 的文件会被**静默忽略**——
144
+ 语法检查通过、进程健康、解析却完全不生效。`sync` 刷新前会检查权限并报错。
145
+ - `systemctl reload dnsmasq` 只发 SIGHUP(重读 hosts),**新增或删除 conf-dir 片段不会生效**,必须 restart。
146
+ - 不要在同一个 dnsmasq 里给同一个域写 `server=/<域>/<上游>`:整域转发会让 `address=/<fqdn>/` 覆盖全部失效。
147
+
59
148
  ## 内网 / 公网边界
60
149
 
61
150
  每条登记都有 `visibility`,它是安全边界而不是展示字段:
@@ -82,9 +171,14 @@ aio-plugin-portal remove tc
82
171
  | `certificate` | `internal-ca`、`acme` | `internal-ca` 由本地 Caddy internal issuer 签发;`acme` 需外部可达,未授权即 blocked |
83
172
  | `policy` | `lan-allowlist`、`aio-auth`、`public` | `lan-allowlist` 生成 `remote_ip` 白名单;`aio-auth` 交给应用自身 |
84
173
 
85
- 云 DNS 凭据只从环境变量读取(`credentialsEnv` 指向变量名),不写进注册表或配置。
86
- 腾讯云 DNSPod 用 `Record.List/Create/Modify`;华为云使用 Zone ID + IAM `X-Auth-Token`,
87
- **长期 AK/SK 签名尚未实现**,未配置 token 时只会给出可审计的计划。
174
+ 云 DNS 凭据在设置界面里**明文**维护,落在 `$AIO_PORTAL_HOME/cloud-credentials.json`(0600,不进
175
+ `aliases.json`);环境变量(`credentialsEnv`)只作兜底。界面上可「测试连接」验证凭据。
176
+
177
+ - 华为云:AK/SK 走 SDK-HMAC-SHA256 签名(canonical URI 补尾斜杠、query 键值整串排序),
178
+ 列 Zone 验证可用性;已配 Zone ID 时不再查列表。
179
+ - Cloudflare / 腾讯云 DNSPod:沿用 Token / ID+Token,暂未实现「测试连接」。
180
+ - `allowPublicWrite` 默认关:全局 `providers.dns` 仍是 `local-dnsmasq`,云 provider 只服务显式
181
+ `visibility=public` 的登记项,避免整域切到云上覆盖现网真实记录。
88
182
 
89
183
  ## 让整片局域网无感走内网
90
184
 
@@ -107,5 +201,11 @@ aio-plugin-portal warden --password '<网关密码>' --restore # 回滚
107
201
 
108
202
  发布与市场配置见 [AIO 自动发布说明](AIO.md)。
109
203
 
204
+ ## 现网登记(182)
205
+
206
+ 设置界面本身也登记成一条内网站点:`https://portal-settings.lyokm.cn/`(`visibility=internal`,
207
+ 上游 `127.0.0.1:8120`,由 `aio-portal-ui.service` 托管)。改动登记后先在界面点「同步」,
208
+ 再确认 dnsmasq 已重启、Caddy 已热加载,最后用 `--resolve` 打到本机验证页面 200。
209
+
110
210
  `skills/aio-plugin-portal/SKILL.md` 是随包的 AI 使用指南;使用 AIO 2026.9.18+ 从市场安装后会进入
111
211
  `~/.agents/skills/aio-plugin-portal/`。