diff --git a/skills/host-sec-check/README.md b/skills/host-sec-check/README.md new file mode 100644 index 0000000..74dd52a --- /dev/null +++ b/skills/host-sec-check/README.md @@ -0,0 +1,41 @@ +# host-sec-check + +对一台 Linux/VPS 做入侵取向的安全检查:先取证,再给你一份结论和处置清单。默认不改机器。 + +## 什么时候用 + +- 「这台机做一次安全检查」 +- 「好像被黑了 / 有矿机 / 服务无故 OOM」 +- 「看看哪些端口对公网开着」 +- 检查另一台机器时,直接点名主机:`对 vvps4 跑 /host-sec-check` + +适用于单台 Linux(systemd + 常见 Docker/k3s)。不是应用代码审计,也不是云账号合规审计。 + +## 使用前准备 + +- SSH 能上(别名或 `user@host`) +- 尽量有 sudo 或 docker 组(没有也能做浅查) +- 告诉 Agent 哪张 IP 是公网,方便从外面探测 +- 若要清理、关端口、重启:明确说「同意处置」 + +## 使用示例 + +```text +对 ace@vvps2 做 host-sec-check,只出报告先不要改。 +``` + +```text +用 host-sec-check 查 vora3,公网 IP 是 x.x.x.x,发现未授权的就列处置项问我。 +``` + +## Agent 会做什么 + +1. 采集账号、监听端口、cron/systemd、Docker/k3s、`ld.so.preload`、内存/hugepage。 +2. 怀疑进程隐藏时,用容器读宿主机,避免被矿机库骗过。 +3. 从另一台机器探测公网端口(含 IPv6,如果有)。 +4. 给出结论:是否沦陷、入口、对外端口、建议处置。 +5. 你点头后才停容器、占位矿机文件、收端口或重启。 + +## 如何判断完成 + +报告里有结论表;若做了处置,公网已关端口连不上,业务域名仍可用。密钥、token 不应出现在完整原文里。 diff --git a/skills/host-sec-check/SKILL.md b/skills/host-sec-check/SKILL.md new file mode 100644 index 0000000..220698b --- /dev/null +++ b/skills/host-sec-check/SKILL.md @@ -0,0 +1,130 @@ +--- +name: host-sec-check +description: >- + Linux/VPS 主机安全检查与入侵取证:先取证再处置。覆盖矿机、ld.so.preload 进程隐藏、带宽挂机容器、对外端口、SSH/Docker/k8s 入口、cron/systemd 持久化、hugepage/OOM。 + Use when: 安全检查, 被黑, 入侵, 矿机, 排查端口, 对公网放开, rpcbind, 挂机赚钱, Portainer, 安全审计, host security, compromise, cryptominer, exposure, /host-sec-check. +--- + +# host-sec-check + +对一台 Linux 主机做安全检查。默认 **只读取证 + 出报告**。清理、关端口、重启、轮换密钥必须用户明确同意后再做。 + +需要:SSH 目标(`user@host` 或 ssh config 别名)、哪张网卡/IP 算公网。没有公网 IP 就只报「监听面」,并标明未做外部探测。 + +## 不适用 + +- Web 应用代码审计、依赖 CVE 扫描(可在报告里列为后续) +- 云厂商安全组控制台(能查就查,查不到就写「未验证」) +- 未获准的破坏性操作(`rm -rf`、整盘 wipe、强制重启) + +## 铁律 + +1. **先取证,后动手。** 重启、删文件、停服务会毁掉证据。 +2. **不要把密钥打进对话。** token、密码、authorized_keys、kubeconfig 只写「存在/已轮换/路径」,不贴原文。 +3. **sudo 失败不要停。** 用户在 `docker` 组时,用特权容器 `nsenter` 看宿主机(见 [references/access.md](references/access.md))。 +4. **怀疑进程隐藏时,不要只信宿主机 `ps`。** 从**不加载宿主机 `ld.so.preload` 的容器**读 `/proc` 和文件。 +5. 宿主机 `chattr` 可能被隐藏库挡住;改 immutable 文件用 **Ubuntu/Alpine 自带 chattr** 操作 bind-mount 的 `/host/...`。 + +收集脚本(可选,先跑再解读): + +```bash +bash /scripts/collect.sh USER@HOST +``` + +`` 是本 skill 目录。脚本只采集,不修改系统。 + +## 流程 + +按顺序做。每步记下「正常 / 可疑 / 未查到」。完整项见 [references/checklist.md](references/checklist.md)。 + +### 1. 快照 + +- 主机名、发行版、uptime、负载、`free -h`、`df -h`、公网/内网/Tailscale IP +- `ss -lntup`(最好 root) +- `docker ps -a`、compose 项目 +- 若有 k3s/k8s:agent 是否在跑、能否 `kubectl get pods -A` + +### 2. 入口 + +- sshd:`Port`、`PermitRootLogin`、`PasswordAuthentication`、`authorized_keys`(root 与所有 UID≥1000) +- `last` / `lastb` / `journalctl -u ssh`:异常登录;**无交互登录却出现 docker run 也是入口信号** +- sudoers、`docker` 组(= root)、NOPASSWD +- 对公网的管理面:Portainer / Cockpit / 面板 / k8s apiserver / Docker 端口,尤其 `-p 0.0.0.0:…` 且挂了 `docker.sock` 或 `/:/host` +- 单元文件或 compose 里的明文 token(k3s `--token`、agent secret) + +### 3. 持久化 + +读 [references/persistence.md](references/persistence.md)。至少查: + +- crontab(root 与所有用户)、`/etc/cron.*` +- `/etc/systemd/system/*.service`、timers +- `/etc/ld.so.preload`(用**外部** cat/hexdump,宿主机 cat 可能被藏空) +- `chattr +i` 的异常二进制(`lsattr`) +- 隐藏 Docker 数据根(非 `/var/lib/docker` 的 dockerd `--data-root`) + +### 4. 进程与隐藏库 + +- 从特权容器列 `/proc/*/cmdline`(绕过 preload) +- 对照宿主机 `ps`:只在容器视角出现的进程 = 隐藏 +- `/proc/*/maps` 是否映射陌生 `.so`(`libgcwrap`、`libprocesshider`、随机名) +- 矿机常见名:`perfcc`、`xmrig`、`kdevtmpfsi`、`javavm64`;同体积多副本(例如都是 11MB) +- hugepage:`grep Huge /proc/meminfo`。`nr_hugepages>0` 且进程列表对不上,多半是矿机预留 + +### 5. 容器与编排 + +- `docker ps -a`:镜像名含 earnfm / packetstream / repocket / traffmonetizer / honeygain / proxyrack / bitping / antgain 等挂机池 +- inspect:`Privileged`、Binds(`docker.sock`、`/:/host`)、Ports 是否 `0.0.0.0` +- 第二套 dockerd / 异常 `--bridge` +- k8s:节点上是否有与 Git 仓库无关的 workload;控制面不健康时从 kubelet `pods/*/etc-hosts` 读 Pod 名 + +### 6. 对外暴露 + +- 本机 `0.0.0.0` / `[::]` 监听 +- **从另一台机器探测公网 IP**(含 IPv6)。只看 `ss` 会漏安全组,只看安全组会漏「监听但没防火墙」 +- 高危:`rpcbind :111`、明文 HTTP 应用端口、Docker/Portainer、k8s 6443、数据库 +- 管理 SSH 若可走 Tailscale,公网 SSH 算多余攻击面 + +### 7. 资源与日志 + +- 无 swap + 高 hugepage → 应用易 OOM +- `journalctl` / `auth.log` 在处置时间点附近;日志空也要记 +- 出站连接:`ss -tp` 看陌生 IP(不要把结果里的密钥打出来) + +### 8. 补漏(本次 vvps2 没做或做得浅的) + +见 checklist 后半:补丁、SUID、世界可写、意外用户、IPv6、定时器、内核模块、出站 C2、云安全组、备份是否可用。 + +## 报告格式 + +先给结论(是否沦陷、最可能入口、对外还开着什么),再给证据表,最后给 **需用户点头的处置清单**。不要默默清理。 + +``` +结论: 沦陷 / 可疑 / 未见异常 +最可能入口: … +对外端口: … +持久化: … +隐藏/矿机: … +容器/编排: … +未查项: … +建议处置: (等确认) +``` + +## 处置(仅在用户同意后) + +原则见 [references/cleanup.md](references/cleanup.md)。 + +- 停并删除未授权容器;镜像也删 +- 矿机二进制:删掉后用 **空文件 + `chattr +i` 占路径** +- 清空并锁定 `/etc/ld.so.preload` +- 关公网绑定:改成 `127.0.0.1` 或 Tailscale IP(若回源走 Tailscale 主机名,必须绑 TS IP,不能只绑 loopback) +- 停无用服务(如 `rpcbind.socket` + `rpcbind.service`,必要时 mask) +- 重启才能卸掉仍映射已删 `.so` 的老进程(sshd/dockerd)。先取证再重启 +- 轮换:暴露过的 token、面板、k3s bootstrap。控制面 API 不通就不要假轮换,写阻塞原因 + +## 验证 + +- 公网探测:已关端口失败;该留的业务域名仍 200 +- `ss`:无 `0.0.0.0:已关端口` +- `grep -l libgcwrap /proc/*/maps`(或同类库)重启后为 0 +- 占位文件仍在且 immutable +- 业务容器 `restart: always` 仍在 diff --git a/skills/host-sec-check/references/access.md b/skills/host-sec-check/references/access.md new file mode 100644 index 0000000..bc0a6de --- /dev/null +++ b/skills/host-sec-check/references/access.md @@ -0,0 +1,48 @@ +# 取证入口(无 sudo 时) + +目标用户常见情况:`sudo` 要密码,但在 `docker` 组。Docker 组等价于 root。 + +## 读宿主机(绕过 preload) + +容器用自己的 libc,**不会**加载宿主机 `/etc/ld.so.preload`。 + +```bash +docker run --rm -i --privileged --pid=host --net=host -v /:/host alpine:latest \ + cat /host/etc/ld.so.preload +hexdump -C /host/etc/ld.so.preload # 在容器内 +``` + +列隐藏进程: + +```bash +docker run --rm --privileged --pid=host alpine:latest sh -c \ + 'for d in /proc/[0-9]*; do + pid=${d#/proc/} + cmd=$(tr "\0" " " < "$d/cmdline" 2>/dev/null) || continue + [ -n "$cmd" ] && echo "$pid $cmd" + done' +``` + +## 改宿主机(systemctl / chattr) + +`chroot /host /usr/bin/chattr` 会加载宿主机 preload,可能 **stat 不到** 被藏文件。 + +用发行版自带 chattr 操作 `/host/...`: + +```bash +docker run --rm -i --privileged --pid=host --net=host -v /:/host ubuntu:latest bash -s <<'SH' +chattr -i /host/etc/ld.so.preload +: > /host/etc/ld.so.preload +chattr +i /host/etc/ld.so.preload +lsattr /host/etc/ld.so.preload +SH +``` + +systemctl / reboot: + +```bash +docker run --rm --privileged --pid=host --net=host alpine:latest \ + nsenter -t 1 -m -u -i -n -- systemctl disable --now UNIT +``` + +不要用业务容器当跳板;用 `alpine`/`ubuntu` 临时 `--rm`。查到一半时 `docker ps` 里出现的随机名容器就是这个跳板。 diff --git a/skills/host-sec-check/references/checklist.md b/skills/host-sec-check/references/checklist.md new file mode 100644 index 0000000..433cd75 --- /dev/null +++ b/skills/host-sec-check/references/checklist.md @@ -0,0 +1,75 @@ +# 检查项 + +每项:做了 / 跳过(原因) / 可疑。 + +## A. 快照 + +- [ ] 主机名、OS、内核、uptime +- [ ] CPU/负载、内存(含 hugepage、swap)、磁盘 +- [ ] 网卡:公网 v4/v6、内网、Tailscale/VPN +- [ ] 监听端口 + 进程(root `ss -lntup`) +- [ ] 本机防火墙:nft/iptables/ufw;INPUT 策略 +- [ ] 云安全组(做不到就写未查) + +## B. 身份与入口 + +- [ ] sshd 配置:端口、root、密码、Pubkey +- [ ] 所有 `authorized_keys`(含 `/root`、`/home/*`、git 用户) +- [ ] `last` / `lastb` / ssh journal +- [ ] `/etc/passwd` 里 UID 0、系统外用户、登录 shell +- [ ] sudoers、NOPASSWD、docker/lxd/libvirt 组 +- [ ] 对公网的面板:Portainer/Cockpit/宝塔/1Panel/k8s/Docker TCP +- [ ] 单元或 compose 里的明文 bootstrap token + +## C. 持久化 + +- [ ] 用户与系统 crontab、`/etc/cron.*` +- [ ] systemd 服务与 timer(非发行版默认) +- [ ] `ld.so.preload` + 对应 `.so`(容器视角 hexdump) +- [ ] `lsattr` 发现的 immutable 异常文件 +- [ ] rc.local、profile.d、bashrc 后门 +- [ ] 第二套 container runtime + +## D. 进程 + +- [ ] 容器视角 vs 宿主机 `ps` 差集 +- [ ] maps 里的陌生 so +- [ ] 矿机/挖矿/proxy 客户端特征名与同体积副本 +- [ ] hugepage 预留但无对应进程 +- [ ] 高 CPU 且不在业务名单里的进程 + +## E. 容器 / k8s + +- [ ] `docker ps -a` 与 inspect(privileged、sock、`/:/host`、`0.0.0.0`) +- [ ] 挂机赚钱镜像名单 +- [ ] k8s/k3s:节点 Ready、该节点 Pod 列表 +- [ ] API 不通时:kubelet `pods/*/etc-hosts`、crictl +- [ ] 工作负载是否能在 Git/编排仓库里对上 + +## F. 暴露 + +- [ ] `0.0.0.0` 与 `[::]` 监听清单 +- [ ] **从外部**扫公网 IPv4(和 IPv6) +- [ ] rpcbind :111、DB、Redis、应用明文端口 +- [ ] 管理 SSH 是否可收到 VPN +- [ ] 证书/域名入口是否可被 IP:端口绕过 + +## G. 补漏(容易漏) + +- [ ] IPv6 公网地址同样在听 +- [ ] 世界可写目录、异常 SUID +- [ ] 未装补丁 / `apt` 过期很久 +- [ ] 出站长连接(C2) +- [ ] 内核模块 `lsmod` 异常 +- [ ] 时间偏移(影响日志) +- [ ] 备份是否还能用(清理前不要删数据盘) +- [ ] 日志被清空或 journal vacuum +- [ ] Web 根目录 webshell(若有 nginx/caddy/apache) +- [ ] `.git` 或备份文件可下载 +- [ ] 云 metadata 是否对容器开放 + +## H. 报告与处置确认 + +- [ ] 结论表 +- [ ] 用户确认后再改 +- [ ] 改完公网+域名双侧验证 diff --git a/skills/host-sec-check/references/cleanup.md b/skills/host-sec-check/references/cleanup.md new file mode 100644 index 0000000..4fddd1c --- /dev/null +++ b/skills/host-sec-check/references/cleanup.md @@ -0,0 +1,59 @@ +# 处置(用户同意之后) + +## 顺序 + +1. 证据已落盘(collect 输出、关键 ls/hexdump/docker inspect) +2. 停进程 / 停容器 +3. 删或占位文件 +4. 关公网端口 +5. 最后才重启(卸已加载的隐藏库) + +## 占位 + +对矿机路径(`/usr/bin/perfcc`、`/tmp/javavm64`、隐藏 docker 根名等): + +```bash +chattr -i "$path" 2>/dev/null +rm -f "$path" +: > "$path" +chmod 000 "$path" +chattr +i "$path" +``` + +`/etc/ld.so.preload` 占空文件,权限 `644` + immutable,让动态链接器能读到「没有库」。 + +目录型隐藏根:停进程并卸挂载后删除,再在同名路径放 immutable 空文件,阻止再 `mkdir`。 + +改 immutable 时用容器自带 `chattr` 操作 `/host/...`,不要 `chroot` 到宿主机再跑 chattr。见 access.md。 + +## 容器 + +```bash +docker stop NAME && docker rm NAME +docker rmi IMAGE +``` + +不要 `docker system prune -a`。 + +## 端口 + +- 入口在本机 loopback → `127.0.0.1:PORT:CONTAINER` +- 入口走 Tailscale 主机名 → 必须绑 **当前 Tailscale IPv4**,不能只绑 127.0.0.1 +- 可同时绑 loopback + Tailscale,禁止 `0.0.0.0` / `[::]` + +改 compose 后 force-recreate,再从公网 IP 和业务域名两边探测。 + +## rpcbind + +```bash +systemctl disable --now rpcbind.socket rpcbind.service +systemctl mask rpcbind.socket rpcbind.service +``` + +无对外 NFS 再做。确认 `:111` 消失。 + +## 重启 + +重启前确认业务是 `restart: always`,并告知会短暂中断。 + +重启后:`grep -l /proc/*/maps` 为 0;若已清 hugepage 则 `HugePages_Total` 为 0;域名 200。 diff --git a/skills/host-sec-check/references/persistence.md b/skills/host-sec-check/references/persistence.md new file mode 100644 index 0000000..3e94a90 --- /dev/null +++ b/skills/host-sec-check/references/persistence.md @@ -0,0 +1,40 @@ +# 持久化位置 + +按这个名单扫。出现「刚被排查时时间戳又刷新」= 仍有 watchdog。 + +## 定时 + +- `crontab -u root -l` 以及 `/var/spool/cron/crontabs/*` +- `/etc/cron.d/` `/etc/cron.hourly/` `/etc/cron.daily/` `/etc/cron.weekly/` +- systemd timers:`systemctl list-timers --all` + +## 服务 + +- `/etc/systemd/system/*.service`(尤其非发行版默认的) +- `ExecStart` 指向 `/tmp`、`/dev/shm`、`/root/.config`、随机短名 +- `Restart=always` 的陌生服务 + +## 动态链接器 + +- `/etc/ld.so.preload`:内容常是 `/lib/libXXX.so`(约十几字节)。宿主机 `cat` 可能显示空,用容器 hexdump +- 对应 `.so` 可能 `chattr +i`、setgid +- 常见名:`libgcwrap.so`、`libpprocps.so`、`libfsnldev.so`、`libprocesshider.so` + +## 二进制与分身 + +- `/usr/bin` `/bin` `/usr/local/bin` `/tmp` 下刚改过的可执行文件 +- 同字节大小的多份拷贝(矿机改名) +- 占位对抗:空文件 `chmod 000` + `chattr +i`(见 cleanup.md) + +## 隐藏运行时 + +- 第二套 dockerd:`--data-root` 不在 `/var/lib/docker`,`--host unix://` 异常路径 +- 混淆文件名(把 docker 子命令拼进无关单词) +- k3s 的 `containerd-shim` 被借去跑 **moby** namespace + 异常 `--address` + +## 登录与启动 + +- `~/.bashrc` / `/etc/profile.d` 里 curl|bash +- `/etc/rc.local` +- SSH `authorized_keys` 多出来的 key +- 意外用户、UID 0 非 root diff --git a/skills/host-sec-check/scripts/collect.sh b/skills/host-sec-check/scripts/collect.sh new file mode 100755 index 0000000..4a5aa96 --- /dev/null +++ b/skills/host-sec-check/scripts/collect.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +# 只采集,不修改。用法: collect.sh [user@]host +# 输出写到 stdout;完整日志建议重定向到文件。 +set -euo pipefail +HOST="${1:?usage: collect.sh user@host}" +SSH=(ssh -o BatchMode=yes -o ConnectTimeout=15 "$HOST") + +echo "===== host-sec-check collect $(date -u +%Y-%m-%dT%H:%M:%SZ) host=$HOST =====" + +remote() { + "${SSH[@]}" bash -s <<'EOS' +set +e +echo "----- id / os / uptime -----" +id; hostname; uname -a +. /etc/os-release 2>/dev/null; echo "$PRETTY_NAME" +uptime +echo "----- mem / hugepage / disk -----" +free -h +grep -E "MemAvailable|HugePages_|Hugetlb|SwapTotal" /proc/meminfo +df -h +echo "----- addresses -----" +ip -4 addr; ip -6 addr show scope global +echo "----- listen (may miss pid without root) -----" +ss -lntup 2>/dev/null || netstat -lntup 2>/dev/null +echo "----- docker -----" +docker ps -a --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}" 2>/dev/null || echo "no docker" +echo "----- preload (host cat; may be hidden) -----" +ls -la /etc/ld.so.preload 2>/dev/null +echo "preload_host=[$(cat /etc/ld.so.preload 2>/dev/null)]" +echo "----- cron files -----" +ls -la /etc/cron.d /etc/cron.hourly /etc/cron.daily 2>/dev/null +echo "----- systemd extras -----" +ls /etc/systemd/system/*.service 2>/dev/null +echo "----- users uid0 / human -----" +awk -F: '$3==0 || ($3>=1000 && $3<65534) {print}' /etc/passwd +echo "----- sshd -----" +grep -E "^(Port|PermitRootLogin|PasswordAuthentication|PubkeyAuthentication)" /etc/ssh/sshd_config /etc/ssh/sshd_config.d/* 2>/dev/null +echo "----- last -----" +last -a | head -15 +EOS +} + +remote + +# docker 组:从容器读 preload 真值 +if "${SSH[@]}" "groups | grep -qw docker" 2>/dev/null; then + echo "----- preload via alpine (bypass host libc) -----" + "${SSH[@]}" "docker run --rm --privileged -v /:/host alpine:latest hexdump -C /host/etc/ld.so.preload" 2>/dev/null \ + || echo "alpine hexdump failed" +fi + +echo "===== collect done =====" +echo "下一步: 按 SKILL.md 解读;不要把本输出里的密钥贴进聊天。" diff --git a/skills/note-style/SKILL.md b/skills/note-style/SKILL.md new file mode 100644 index 0000000..b981c5a --- /dev/null +++ b/skills/note-style/SKILL.md @@ -0,0 +1,89 @@ +--- +name: note-style +description: 将现有材料整理、压缩或改写为可长期查阅的知识笔记,采用教科书、技术手册或标准说明文风格,并保留事实、公式、适用条件、安全警告和参考资料。适用于用户要求整理 Obsidian 笔记、消除聊天或 AI 写作痕迹、减少重复和空话、统一术语与技术表达,或将技术原理、操作方案改写为结构化知识文档的任务。 +--- + +# 整理知识笔记 + +## 工作流程 + +1. 识别材料的核心问题、目标读者和材料类型。 +2. 提取事实、定义、公式、条件、因果关系、步骤、例证、边界、安全警告和参考资料。 +3. 删除与核心问题无关的铺垫,并合并重复内容。 +4. 按材料类型选择结构并重写全文。 +5. 检查技术准确性、术语、格式、重复和表达密度。 +6. 输出完整笔记;存在事实或技术疑点时,追加“待核实项”。 + +## 保留与删减 + +- 保留原文中的事实、公式、适用条件、例外、安全限制和参考资料。 +- 不自行补充没有依据的结论,也不为缩短篇幅而删除必要条件或公式推导。 +- 围绕核心问题组织内容,删除无关铺垫。 +- 使每句话至少承担一种功能:定义概念、说明条件、解释因果、给出步骤、提供例证或指出边界。 +- 使同一知识点只完整解释一次。避免在摘要、正文、表格、总结和检查表之间复述。 +- 在不损失必要信息的前提下,默认将篇幅压缩约 30%;若用户另有篇幅要求,以用户要求为准。 + +## 语言规范 + +- 使用中性、准确、简洁的书面语。 +- 直接陈述内容,不添加聊天式过渡、开场铺垫、段末复述或写作过程说明。 +- 删除情绪化、评价性、劝导性、宣传性和表演式表达,如“非常美妙”“加分项”“更稳妥”“请仔细看”。 +- 不使用反问、口号、拟人化表达或用感叹号制造重点。 +- 减少“通常、可能、建议、优先、具体来看”等模糊限定词。确有不确定性时,明确不确定性的来源和适用条件。 +- 每段只表达一个主题;能用一句话说明的内容不扩写成多句。 +- 将评价句改写为“条件、机制、结果”或“对象、操作、限制”。 + +## 技术表达 + +- 首次出现专业术语时给出简短定义,后文统一名称。 +- 明确符号、变量、单位、对象类型、参考系、输入输出和变换方向。 +- 区分严格定义、直观解释和示例,不用比喻替代定义。 +- 每个概念最多保留一个必要的例子或比喻;使用比喻后,以正式术语重述结论。 +- 检查概括的适用范围,将无条件的“X 代表 Y”改为带条件的准确表述。 +- 不擅自修正不确定或可能有误的技术内容,将其列入“待核实项”。 + +## 结构选择 + +根据材料类型采用下列骨架,并按实际内容删去不需要的章节。 + +### 技术原理类 + +1. 问题或目标 +2. 符号与定义 +3. 原理或推导 +4. 示例 +5. 适用条件与限制 +6. 简短结论 + +### 操作与方案类 + +1. 目标与适用范围 +2. 基本原则 +3. 操作步骤 +4. 分类处理 +5. 安全边界 +6. 检查表 + +不要同时保留内容重复的“摘要”“重新解释”“具体调整”和“总结”。摘要已经给出结论时,正文只提供依据和展开。 + +## 格式规范 + +- 使用描述性标题,避免“到底是什么”“究竟该怎么做”等口语化标题。 +- 保持标题编号连续、层级一致。 +- 仅对首次定义的术语、关键条件和禁止事项使用粗体。 +- 减少引号和括号,统一数学符号、变量格式和单位格式。 +- 保留适合 Obsidian 的 Markdown、YAML frontmatter、Wiki-links、表格、公式和代码块;除非用户要求,不改变其语义。 + +## 完成检查 + +- 检查同一结论是否出现在两个以上位置,只保留信息最完整且位置最合适的一处。 +- 检查相邻段落能否分别用一句话概括;含义相同时合并。 +- 检查所有评价句是否已改为可验证的条件、机制、结果、操作或限制。 +- 检查技术概括、符号定义、事实和适用条件是否成立。 +- 检查内部链接、表格、公式、代码块、安全警告和参考资料是否完整保留。 + +## 输出 + +1. 先输出整理后的完整笔记。 +2. 仅在存在技术或事实疑点时追加“待核实项”,逐条列出疑点。 +3. 不解释改写过程,不输出修改心得,不复述本技能的要求。 diff --git a/skills/note-style/agents/openai.yaml b/skills/note-style/agents/openai.yaml new file mode 100644 index 0000000..d9caa6b --- /dev/null +++ b/skills/note-style/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "教科书式笔记整理" + short_description: "将材料压缩并改写为准确、简洁的结构化知识笔记" + default_prompt: "使用 $note-style 将这份材料整理为可长期查阅的知识笔记。"