diff --git a/.workbuddy/memory/2026-10-23.md b/.workbuddy/memory/2026-10-23.md index 86cc83f..6ef5653 100644 --- a/.workbuddy/memory/2026-10-23.md +++ b/.workbuddy/memory/2026-10-23.md @@ -98,3 +98,18 @@ IPv6 丢掉了精确地址(IPv4 无损);邮件里也只给键,运维会 不是代码问题;判断这类"看不见的字符"一律用 `od -c`,别靠终端渲染。 测试环境服务是**前台跑在 /dev/pts/1**,日志不在文件里 —— 拿日志要 `tmux capture-pane` 或 下次启动加 `>> logs/tamabox.log 2>&1`。 + +### 蜜罐升级为 9 个伪装家族 + +新增 `family.go`(皮肤表)/ `asset.go`(静态资源占位)/ 重写 `page.go`: +- 按路径分发:wordpress / phpmyadmin / tomcat(401+Basic) / jenkins / grafana / gitlab / + luci / joomla / generic;每类独立字段名、配色、指纹响应头、Set-Cookie; +- `credentialKeys` 扩 `pma_*` / `j_*` / `luci_*` / `user[login]`; + `token` 只用于判 HadFields,**不进 isPasswordKey**(否则 PMA 的 hidden token 会随机顶掉真密码); +- 静态资源(`/wp-admin/css/…` 等)回占位内容,**不落库不计数** —— 一次页面加载 5–10 个请求; +- `honeypot paths` 加家族汇总(实测 110 条:generic 84 / wordpress 10 / tomcat 6 / gitlab 3 / pma 3 …); +- 性能:RenderFamily 12µs→3.7µs、22→2 allocs、19.5KB→5.2KB(禁 `"a"+b+"c"`、Replacer 提包级)。 + +**新工具** `dev/preview-honeypot`:渲染 9 个家族到 `outputs/honeypot-preview/index.html`, +配 chrome headless 截图核对外观。靠它发现两处「源码看不出、截图一眼假」: +Tomcat 的 skin 忘了 css(按钮白字无底色)、WP 登录页底部挂着 404 文案。 diff --git a/.workbuddy/memory/MEMORY.md b/.workbuddy/memory/MEMORY.md index 4767cb3..5039bd3 100644 --- a/.workbuddy/memory/MEMORY.md +++ b/.workbuddy/memory/MEMORY.md @@ -2,7 +2,8 @@ 明细已拆分到 `topics/*.md`(按需 Read 全文): `coop` 协作 / `build` 构建测试 / `embed` 行尾·模板·embed / `review` 审核处置举报 / -`gorm` GORM / `style` 前端样式 / `theme` 主题 / `builder` 主题生成器 / `share` 分享卡 / `misc` 其它约定。 +`gorm` GORM / `style` 前端样式 / `theme` 主题 / `builder` 主题生成器 / `share` 分享卡 / +`honeypot` 蜜罐多家族伪装 / `misc` 其它约定。 ## 协作 diff --git a/.workbuddy/memory/topics/honeypot.md b/.workbuddy/memory/topics/honeypot.md new file mode 100644 index 0000000..9cee1b1 --- /dev/null +++ b/.workbuddy/memory/topics/honeypot.md @@ -0,0 +1,34 @@ +# 蜜罐(多家族伪装 / 取证 / 封禁) + +## 结构 + +- `internal/security/honeypot/family.go` 是**唯一皮肤表**:9 个 Family + (wordpress / phpmyadmin / tomcat / jenkins / grafana / gitlab / luci / joomla / generic)。 + 每个 skin 自带 routes、title、brand、tagline、css、fields、hidden、failure、headers、cookies。 +- `FamilyOf(path)` 按 segments 前缀判定(`.` 也算边界,兼容 `/adminer.php`)。 + 新增路径必须**同时**进 `honeypotPrefixes`,否则 `Match` 根本不接管。 +- `asset.go`:`/wp-admin/css/…`、`/wp-includes/js/…` 这类资源回占位内容, + **不落库、不计数** —— 一次页面加载会打 5–10 个资源请求。 +- `page.go`:一次 `strings.Builder` 拼接,禁用 `"a" + b + "c"`(每个 + 一次分配); + `fieldIDReplacer` 必须包级,别在循环里 `NewReplacer`。 +- `route/honeypot.go` 的 Serve 顺序:cleanPath → **资源短路** → 家族 → 诊断日志 → 回环告警 → 提凭据 → 封禁 → 响应 → 落库。 + +## 性能基线(谁改慢了谁负责) + +- `RenderFamily` ≈ 3.7 µs / 2 allocs / 5.2 KB;`AssetFor` ≈ 55 ns / 0 alloc。 +- 单页体积上限 4 KB,由 `TestRenderIsCheap` 守。 +- 预览:`go run ./dev/preview-honeypot` → `outputs/honeypot-preview/index.html`(9 个 iframe)。 + 改皮肤后务必跑一次并截图,上一版就是靠它发现 Tomcat 按钮没背景色。 + +## 坑 + +- **hidden CSRF token 不能算密码键**:PMA / GitLab 的表单带 `token`,而 map 遍历无序, + 一旦 token 进 `isPasswordKey`,真密码会被随机覆盖成 token 值。 + 所以 `credentialKeys` 收 token(只用于判 `HadFields`),`isPasswordKey` 不收。 +- **Tomcat 家族 = 401 + `WWW-Authenticate`**,凭据从 `Authorization` 头取; + 给它一个 HTML 表单反而不像。 +- 页面里不能出现 `TamaBox` / `honeypot` 字样;canary 只放 HTML 注释, + `` 必须伪装成真实产品(扫描器必查)。 +- WP 登录页底部不能挂 404 文案(真实页没有,挂上一眼就假)。 +- 新增诱饵前缀前先核对业务路由(`/user`、`/login`、`/api`、`/_/`…); + `forbiddenPrefixes` 按 `/xxx` 段边界判断,所以 `/users/sign_in` 不会被 `/user` 连坐。