# 蜜罐(多家族伪装 / 取证 / 封禁) ## 结构 - `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` 连坐。