finch-remote-host 0.0.0-stage → 1.0.0
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 +175 -2
- package/dist/index.js +1645 -0
- package/finch.json +39 -0
- package/i18n/zh-CN.json +34 -0
- package/icon.png +0 -0
- package/package.json +24 -5
- package/skills/remote-host/SKILL.md +66 -0
- package/ui/panel.html +1361 -0
package/finch.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"manifestVersion": 1,
|
|
3
|
+
"name": "远程主机",
|
|
4
|
+
"miniToolType": "local",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"activationEvents": ["onStartup"],
|
|
7
|
+
"systemPrompt": "在用户配置的远程服务器上跑命令、查日志、看服务状态时用 remote_host。",
|
|
8
|
+
"contributes": {
|
|
9
|
+
"tools": true,
|
|
10
|
+
"skills": true,
|
|
11
|
+
"settingsMenu": {
|
|
12
|
+
"icon": "square-terminal",
|
|
13
|
+
"tooltip": "远程主机与策略"
|
|
14
|
+
},
|
|
15
|
+
"composerActions": [
|
|
16
|
+
{
|
|
17
|
+
"id": "host",
|
|
18
|
+
"icon": "square-terminal",
|
|
19
|
+
"tooltip": "远程主机"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"appPanel": {
|
|
23
|
+
"icon": "square-terminal",
|
|
24
|
+
"viewType": "remote-host.manager",
|
|
25
|
+
"instanceMode": "single",
|
|
26
|
+
"showInLauncher": true,
|
|
27
|
+
"source": {
|
|
28
|
+
"type": "local",
|
|
29
|
+
"path": "ui/panel.html"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"permissions": {
|
|
34
|
+
"filesystem": "readwrite",
|
|
35
|
+
"network": false,
|
|
36
|
+
"shell": true,
|
|
37
|
+
"secrets": ["host.*"]
|
|
38
|
+
}
|
|
39
|
+
}
|
package/i18n/zh-CN.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "远程主机",
|
|
3
|
+
"description": "在 Finch 里管理远程主机,让 Agent 通过 SSH 执行命令,危险操作先经用户确认,全部动作留审计。",
|
|
4
|
+
"systemPrompt": "在用户配置的远程服务器上跑命令、查日志、看服务状态时用 remote_host。",
|
|
5
|
+
"menu": {
|
|
6
|
+
"count": "{count} 台主机",
|
|
7
|
+
"empty": "还没有配置主机",
|
|
8
|
+
"ok": "上次成功",
|
|
9
|
+
"failed": "上次退出码 {code}",
|
|
10
|
+
"panel": "打开主机面板",
|
|
11
|
+
"noHosts": "还没配置主机",
|
|
12
|
+
"clear": "清除本会话的选择"
|
|
13
|
+
},
|
|
14
|
+
"badge": {
|
|
15
|
+
"pick": "选主机"
|
|
16
|
+
},
|
|
17
|
+
"confirm": {
|
|
18
|
+
"title": "在 {host} 上执行?",
|
|
19
|
+
"description": "目标:{target}\n判定:{hits}\n\n{command}",
|
|
20
|
+
"submit": "确认执行",
|
|
21
|
+
"cancel": "取消",
|
|
22
|
+
"tick": "我已看清命令与目标机"
|
|
23
|
+
},
|
|
24
|
+
"progress": {
|
|
25
|
+
"running": "正在 {host} 上执行…",
|
|
26
|
+
"streaming": "{host} · {seconds}s · {lines} 行 · {last}",
|
|
27
|
+
"waiting": "还没输出"
|
|
28
|
+
},
|
|
29
|
+
"panel": {
|
|
30
|
+
"needPassword": "密码认证需要先填密码",
|
|
31
|
+
"testOk": "连上了",
|
|
32
|
+
"testFail": "连不上,看下面的输出"
|
|
33
|
+
}
|
|
34
|
+
}
|
package/icon.png
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "finch-remote-host",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "在 Finch 里管理远程主机,让 Agent 通过 SSH 执行命令,危险操作先经用户确认,全部动作留审计。",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"devops",
|
|
7
|
+
"finch",
|
|
8
|
+
"finch-minitool",
|
|
9
|
+
"remote-host",
|
|
10
|
+
"server",
|
|
11
|
+
"ssh"
|
|
12
|
+
],
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"files": [
|
|
15
|
+
"finch.json",
|
|
16
|
+
"dist/",
|
|
17
|
+
"i18n/",
|
|
18
|
+
"skills/",
|
|
19
|
+
"ui/",
|
|
20
|
+
"icon.png",
|
|
21
|
+
"README.md"
|
|
22
|
+
],
|
|
23
|
+
"type": "module",
|
|
24
|
+
"main": "dist/index.js"
|
|
25
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: remote-host
|
|
3
|
+
description: 远程主机的操作手册。用 remote_host 在用户已配置的服务器上读文件、查状态、跑命令之前先读它,尤其是四种策略模式的差别、只读判定的边界、规则写 glob 时的匹配方式,以及命令被拒绝或需要确认时怎么处理。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 远程主机
|
|
7
|
+
|
|
8
|
+
`remote_host` 操作的是用户在面板里手工添加过的主机:认证用磁盘上的私钥或系统安全存储里的密码,Agent 既不接触凭据,也不能新增或修改主机。
|
|
9
|
+
|
|
10
|
+
## 心智模型
|
|
11
|
+
|
|
12
|
+
- **主机是用户给的权限,不是 Agent 的资源。** 没有 `hosts` 里出现的主机,就是不存在。
|
|
13
|
+
- **认证方式不用关心。** 密钥机与密码机对你完全一样;密码机若没存密码,`exec` 会直接报错,让用户去面板补。
|
|
14
|
+
- **每条命令都过一次分类器。** 结论只有三种:直接跑、等用户确认、拒绝。
|
|
15
|
+
- **一切留痕。** 每次执行都写审计,包括被拒绝和用户取消的那些。
|
|
16
|
+
|
|
17
|
+
## 四种策略
|
|
18
|
+
|
|
19
|
+
| 模式 | 只读命令 | 写操作 | 读凭据文件 | 典型场景 |
|
|
20
|
+
| ---------- | -------- | ------ | ---------- | ------------------------ |
|
|
21
|
+
| `query` | 直接跑 | 拒绝 | 拒绝 | 只要看得出状态的监控机 |
|
|
22
|
+
| `readonly` | 直接跑 | 拒绝 | 确认 | 生产库、核心网关,只许看 |
|
|
23
|
+
| `confirm` | 直接跑 | 确认 | 确认 | 默认值,日常运维 |
|
|
24
|
+
| `trusted` | 直接跑 | 直接跑 | 直接跑 | 自己的跳板机、一次性环境 |
|
|
25
|
+
|
|
26
|
+
硬拒清单不看模式,也不给确认按钮:删根目录、删任何一级目录(含 `rm -rf /var/*` 这种清空)、不带路径的通配删除(`rm -rf *`)、`mkfs`、`dd` 写裸盘、重定向写块设备、fork 炸弹、关机重启、`chmod 777 /`。
|
|
27
|
+
|
|
28
|
+
判硬拒时先去掉引号再按段扫,`sudo rm -rf /var`、`sh -c "rm -rf /var"` 同样拦下;二级以下路径(`rm -rf /var/log/nginx`)归模式管。
|
|
29
|
+
|
|
30
|
+
### 保护路径
|
|
31
|
+
|
|
32
|
+
这些位置被删除、清空、截断、重定向写入时直接拒绝,不看模式:
|
|
33
|
+
|
|
34
|
+
- 整棵子树:`/etc`、`/boot`、`/bin`、`/sbin`、`/lib*`、`/usr`、`/root`、`/var/www`、`/var/spool`、任何位置的 `.ssh`
|
|
35
|
+
- 只到直属子目录:`/home`、`/opt`、`/srv`、`/var/lib`(`/var/lib/mysql` 拒,`/var/lib/apt/lists/*` 只要求确认)
|
|
36
|
+
- 名单只收 Linux 通用路径:业务目录(如 `/wwwroot`)删里面只确认,但目录本身是一级目录,`rm -rf /wwwroot` 仍硬拒
|
|
37
|
+
|
|
38
|
+
拦截的命令:`rm`、`rmdir`、`unlink`、`shred`、`truncate`、`dd of=`、`>`/`>>`、`find -delete`。
|
|
39
|
+
|
|
40
|
+
`cp`、`mv`、`sed -i`、`tee` 不拦,它们改配置与部署照常走模式。
|
|
41
|
+
|
|
42
|
+
## 标准节奏
|
|
43
|
+
|
|
44
|
+
1. `hosts` —— 先看有哪些主机、什么模式、上次结果。标着「当前会话」的那台就是用户已经选好的。
|
|
45
|
+
2. 用户在输入框下方选过主机时,`exec` 可以不传 `hostId`,直接落到那台;没选又没传就会报错,让用户去选。
|
|
46
|
+
3. 第一次连某台机器,先跑 `whoami` 或 `uname -a` 验证连通性(只读,不会弹确认)。
|
|
47
|
+
4. 摸清目录结构再动手:`ls`、`df -h`、`systemctl status <服务>`。
|
|
48
|
+
5. 需要写入的命令一次说清楚:确认卡片显示的就是最终要执行的那一条,所以别把多条命令拼成一个字符串去"试探",用户看到的越长越容易点取消。
|
|
49
|
+
6. 长任务给 `timeoutSeconds`(默认 120,最大 600),执行期间进度会自己刷秒数、行数与最新一行,不用中途打断去问。输出正文仍是一次性返回,会被截断到头 6 KB + 尾 3 KB。
|
|
50
|
+
7. 预计超过 10 分钟的任务(大构建、全量备份)用 `start` 起后台任务,别硬跑 `exec`:拿到 taskId 后用 `status` 轮询,别再起第二遍。
|
|
51
|
+
8. 后台任务结束前不要凭空猜测进度,`status` 会给行数、日志尾巴和退出码;用户说要停就 `stop`,需要清远端日志再加 `clean`。裸 `nohup` 会让进程失控,不要用。
|
|
52
|
+
|
|
53
|
+
## 命令怎么写
|
|
54
|
+
|
|
55
|
+
- 判定按命令拆开后的每一段做:`ls -l` 直跑;`ls && rm -rf x` 里的 `rm` 那段不在白名单,整条走确认;`df -h > /tmp/a` 因为重定向不算只读。
|
|
56
|
+
- 管道会逐段判定,任何一段不过就升级为确认。
|
|
57
|
+
- 读 `.env`、`id_rsa`、`*.pem`、`/etc/shadow` 这类文件,即使只读也要确认——那是凭据。
|
|
58
|
+
- 用户配了放行规则时,规则是 glob,整段匹配:`systemctl restart nginx` 不会放过 `systemctl restart nginx-backup`;`*` 不跨 `/`,跨层级用 `**`。
|
|
59
|
+
- 不要用交互式命令(`vim`、`top`、`less`、`sudo -S`):没有终端,它们会卡住直到超时。
|
|
60
|
+
- 需要 root 就写 `sudo -n <命令>`,准备好免密;`-n` 让它在没权限时立刻失败而不是等密码。
|
|
61
|
+
|
|
62
|
+
## 被拒绝或取消时
|
|
63
|
+
|
|
64
|
+
- 「策略拒绝执行」:这条命令在当前模式下不允许。不要改写绕过(换写法、拆开、编码),直接告诉用户当前模式是什么、要做什么,让用户决定是否调策略。
|
|
65
|
+
- 「用户没有确认」:就是不执行。不要重复发起同一条命令;确有必要,先说清楚为什么要这条命令。
|
|
66
|
+
- 「后台会话没人确认」:任务跑在后台或远程通道上,危险命令必须放弃,改让用户在前台会话里操作。
|