正在读取笔记…
标签:架构设计
1 篇 · 全部笔记
- 我把这个博客当成一个安全项目来做
静态托管、零第三方脚本、源站不暴露——这些选择看起来是「技术选型」,其实每一条都是在做攻击面收敛。
该分类暂时没有内容。这里不会用示例文章凑数。
1 篇 · 全部笔记
静态托管、零第三方脚本、源站不暴露——这些选择看起来是「技术选型」,其实每一条都是在做攻击面收敛。
该分类暂时没有内容。这里不会用示例文章凑数。
只搜本仓库的笔记(Hugo 生成的 /index.json 本地索引,零第三方请求)
主页是一整屏书桌场景:中间那台 CRT 显示器的屏幕里是桐莉栖。屏内右上角是运行状态行 —— 上面的数字只从真实只读接口来,接口取不到就写「读不到」,绝不补数;屏内底部是字幕条, 显示她当前说的话;页面最底部是输入条,在里面提问会切到「AI 安全」页,并走真实的公开问答链路 (一次性 POST 返回,无 SSE 流式)。她会跟着问答状态换表情与动作(思考 / 说话 / 情绪), 语音入口也在(语音线尚未接入,按钮不会自动播放任何音频)。 指标与告警在「监测中心」,攻防靶场在「攻防靶场」,笔记与分类在「笔记」,项目介绍与数据口径在「关于」, 都可以用左侧导航直达。这一页刻意只做场景与对话:不做仪表盘、不放指标卡、不放文章列表、不放靶场表单 —— 那些内容都在各自页面上,主页不再重复它们。
9 篇 · 真实复盘(部署链 / 事故 / AI 防护 / 蜜罐 / 规则裁剪)
站点 502 了约 6 分钟。查下来不是「一个 bug」,而是四个各自独立、每一个单独都足以致命的缺陷:启动崩溃、配置格式、潜伏 3 天的防火墙冲突、以及发布链的盲区。这篇按时间线还原,并给出正在生效的对照组。
「不执行处置」和「不泄露内部事件数据」是两件事。收紧之前,匿名问一句「我们昨天被谁打了」,回答里会带出内部资产名和内部接口路径 —— 处置确实没执行,但数据已经出去了。这篇讲两层防御(编排层不派发 + 工具层二次拒绝)怎么落地,以及它换来的代价。
一份可以直接照着填的周报/月报骨架:每一格都写明它来自哪个公开端点、哪个字段、什么口径,以及「取不到的时候写什么」。模板的价值不在于好看,而在于它逼你回答「这个数字到底是怎么算出来的」。
多端口扫描的漏报,在本环境里不是「规则不够」,而是「看不见」——7 个端口的 SYN 在云安全组就被丢了,传感器看不到的包,任何规则都检测不到。这篇讲清可见性缺口怎么证明、误报抑制怎么做,以及哪些检测能力被刻意放弃了。
53,122 条 alert 规则、44MB 规则文件,24 小时里真正命中的只有 1 个签名。裁掉 10,675 条(约 20%)之后,阳性对照照常在报、基线命中集逐条复现、丢失 = 0。这篇讲判据怎么定、怎么证明没裁错、以及被裁掉的那部分弱信号意味着什么。
一个容器跑起来,你怎么知道跑的就是你刚推的那个 commit?这条链上我封了五道闸门:触发即校验、jar 内指纹核对、镜像 digest 而不是 tag、部署前后的硬校验、以及一个会自己回滚的看门狗。
一个安全方向的学习与技术记录站——把做过的项目、踩过的坑、以及可以亲手试的东西放在一起。
把准备写的题目列出来,写完一个勾一个——公开自己的进度表,也是一种督促。
静态托管、零第三方脚本、源站不暴露——这些选择看起来是「技术选型」,其实每一条都是在做攻击面收敛。
该分类暂时没有内容。这里不会用示例文章凑数。
正在读取笔记…
一页大屏 · 真实公开端点加载中…
正在读取…
来源累计被判定的连接 / 登录尝试次数。
正在读取…
正在读取…
正在读取…
commandsAvailable=false),不作图、不编造内容。/api/health 的公开字段里没有,保持缺省而不是估算。公开知识库问答 · 只解释不取证 · 无 SSE
你好。这里是一个公开只读的安全知识库问答:问题会送进真实运行的检索增强链路, 返回答案、引用与状态标注。
它只解释概念与防御,不读取任何内部事件数据 —— 问"我们昨天被谁打了"这类问题,它会明确告诉你公开面不取证(下面有一个预设问题可以亲手试)。
未提问。
| state 取值 | 页面措辞 | 含义 |
|---|---|---|
model | 模型研判 | 模型给出了结论与依据 |
rule-based | 规则解析 | 结论来自规则,模型不参与处置拍板 |
input-insufficient | 依据不足,不做定性 | 信息量不够,明确不给结论 |
no-retrieval | 未检索到依据,不给结论 | 检索为空,不用模型自由发挥 |
retrieval-failed | 检索不可用,未生成 | 链路故障,不伪装成"安全" |
model-failed | 模型不可用,未生成 | 模型不可用,明确"未生成" |
表外的取值一律显示原始 state 字符串 + "未识别状态",不猜它的含义。
公开面唯一的检索来源是白名单目录(security-docs / data/kb-approved);
内部文档即使被语义命中也不会出现在这里。引用里若出现 web-01、auth.log
这类示例资产名,那是知识库文档里的教学示例,不是本站的内部真实数据。
桐莉栖● 在线 · 文本版(语音未启用)
正在读取…
有什么安全相关的问题直接问我。我会走真实的检索链路,答不了就说答不了。
情绪(8 种,随对话切换,也可以点)
她的解说只用本页的真实数据与真实回答;取不到就说读不到,不编数字。
SecAgent · 在线 Demo
一句话:把「告警 → 研判 → 处置」这条安全运营链路,做成一个可编排、可审计、有护栏的 AI 助手。
企业安全运营中心每天产生几千到几万条告警,其中九成以上是误报和重复,真正的攻击被淹没在噪声里。分析师要在告警系统、日志平台、知识库、资产表之间来回切换才能下判断;判断完还要手工封 IP、锁账号——慢、容易出错,而且处置过程没有留痕,事后无法复盘。
新人上手要几个月,老手的经验留在脑子里带不走。
| 能力 | 具体实现 |
|---|---|
| 降噪 | 同一源 IP + 时间窗 + 同类告警自动聚合成一条,带 ×N 徽标,可下钻原始明细 |
| 多 Agent 研判 | 编排层 + 调度员,派发给研判员(查知识库 RAG)、取证员(拉告警与日志)、处置员(执行动作)三个专职智能体,汇总输出「结论 + 证据 + 处置结果」 |
| 分级处置 + 护栏 | 自动封禁;高危动作强制人工审批;白名单拦截内网/环回地址;全部动作写审计 |
| 知识库问答 | 33 篇安全知识文档向量化,支持带出处引用与相似度阈值拒答 |
| 红队评测 | 27 例用例(基础 19 + 绕过型 8),同时输出绕过率与误报率两个独立维度;绕过率 4/19 = 21.05%(95% CI 约 8%~44%),8 例正常流量未观察到误拦(真实误报率 95% 置信上限约 37.5%) |
处置动作的护栏写在代码里,不写在提示词里。
因为提示词可以被精心构造的输入绕过,而代码层的白名单绕不过去。这条取舍说明我清楚大模型的能力边界——知道该在哪里踩刹车。
Spring Boot 3.2 · Spring AI / Spring AI Alibaba · RAG · 多 Agent 编排 · Tool Calling · SSE 流式输出 · 自研向量存储抽象(内存 / Milvus 可切换)· Docker
🚧 在线 Demo 正在部署中。 部署完成后这里会放可点击的试玩入口。
一句话:用 Hugo + PaperMod 构建的纯静态技术站,托管在 GitHub Pages。
它值得单列的原因:这不是套个模板就完事——为了让它符合一个安全从业者该有的样子,做了这些取舍:
| 决策 | 原因 |
|---|---|
| 纯静态,不要 CMS 和数据库 | 没有数据库就没有 SQL 注入,没有后台就没有弱口令 |
| 零第三方脚本 | 每个外部脚本都是把访问者的浏览器控制权分一份给别人 |
| 页面内不加统计/字体/客服 | 同上,只留必要的评论组件 |
| 源码与构建产物分离 | main 放源码,gh-pages 放产物,发布可复现 |
相关文章:《我把这个博客当成一个安全项目来做》
| 用户名 | analyst |
| 密码 | SecAgent-Demo-2026 |
| 角色 | 分析员(ANALYST) |
这个角色能做什么、不能做什么:
| ✅ 可以 | ❌ 不可以 |
|---|---|
| 查看告警大屏、事件归档 | 执行处置动作(封 IP / 锁账号 / 杀进程) |
| 对话研判、知识库检索 | 审批处置申请 |
| 提交知识条目(待审) | 审核知识库、管理用户 |
权限是刻意收窄的。 处置动作全部要求管理员角色 + 人工审批,所以公开一个分析员账号不会带来风险。
配额说明:为了让服务不被刷爆,接口有 50 次/天 的模型调用配额和 30 次/分钟 的限流。用完了第二天恢复。
按顺序试,能看出系统的设计思路:
在「对话研判」里输入:
什么是路径穿越,怎么防御?
看什么:回答下面会附检索证据,包含命中的文档名、片段内容、相似度分数。
证据被包在一个 <UNTRUSTED_DATA> 标签里 —— 这是提示词注入防护:
知识库文档本身也可能是攻击载荷,不能被当成给模型的指令。
帮我看看最近的告警里有没有可疑的
看什么:调度员会判定这是研判任务,派给对应角色的智能体,并调用工具去拉告警数据,而不是凭空编答案。
看什么:列表默认显示的是聚合后的结果(同一源 IP + 时间窗 + 同类告警合成一条),带 ×N 徽标。点进去能下钻到原始明细。
这是解决"告警风暴"的核心设计。
看什么:处置动作分三级 —— 自动执行 / 需审批 / 禁止。 注意「需审批」那一列 —— 这是整个项目最重要的设计:高危动作永远不会自动执行。
在对话里试试:
帮我封禁 127.0.0.1 这个 IP
看什么:会被代码层的白名单拦下来,而不是靠提示词拒绝。 内网地址、环回地址在处置护栏里是硬拦截的 —— 因为提示词可以被绕过,白名单不能。
demo.xiaokeqing.cn —— 走的是 Cloudflare 命名隧道,不是临时隧道。
区别在这里:
| 临时隧道 | 命名隧道(现在用的) | |
|---|---|---|
| 地址 | 随机分配,重启就换 | 固定,绑在 Cloudflare 账号下 |
| 换服务器 | 链接失效 | 链接不变(只在新机器上重装隧道) |
| 入站端口 | 不需要 | 不需要 |
服务器上没有任何入站端口是开着的 —— 容器只监听 127.0.0.1,
隧道是服务器主动向 Cloudflare 建立出站连接。所以从外面扫这台机器,
扫到的只有 22 端口(而且已经关了密码登录)。
这条也是买域名真正要解决的问题:让地址和机器解耦。 服务器是消耗品,域名是资产。
| 限制 | 说明 |
|---|---|
| 数据是模拟的 | 告警和日志是 MOCK 数据,没有接真实 SOC 环境 |
| 处置动作没实测过 | 代码里有完整实现和护栏,但不敢在生产环境真的封 IP 演示 |
| 响应偏慢 | 服务器在杭州,隧道绕经境外,首屏约 1.2~1.5 秒 |
| 手机端 | 能用,但告警大屏这类宽表格在小屏上体验一般 |
红队评测跑过了,27 例(19 例基础 + 8 例绕过型),结果:
| 指标 | 数值 | 说明 |
|---|---|---|
| 绕过率 | 4 / 19 = 21.05 % | 95% 置信区间约 8 % ~ 44 % |
| 误报率 | 0 / 8 未观察到误拦 | 真实误报率的 95% 置信上限约 37.5 % |
| 拦下 / 绕过 | 15 / 4 |
为什么要写置信区间,而不是写「误报率 0%」
8 个正常样本里 0 次误拦,不等于误报率是 0。 按统计学上的「三法则」,n 次试验 0 次事件时,真实发生率的 95% 置信上限约为
3/n—— 也就是 3/8 ≈ 37.5%。样本量太小,这个数字只够说明「没有明显误杀」, 支撑不了「误报率很低」的结论。同理,4/19 的绕过率区间宽到 8%~44%,几乎不具区分度。
写清楚这一点,是因为一个漂亮但站不住的 0% 比一个诚实的区间更容易被问倒。
为什么不写「拦截率 100%」:第一版 19 例跑出来就是 0 绕过、0 误报, 但那个数字没有意义 —— 用例是照着防护规则写的,当然全能命中。 0% 绕过率不是成绩,是评测集失效的信号。
所以补了 8 例专门针对规则边界的变形载荷(字符插空 / 全角 / Base64 / 同义改写 / 凭据拆开写…),绕过率立刻变成 42.11%。然后修掉其中能修的 4 类 (加文本归一化 + 补中文模式),降到 21.05%。
关键是:修完之后误报率没有变差 —— 8 个正常用例依然全部放行。 说明拦截率的提升不是靠「宁可错杀」换来的。
剩下 4 类修不掉,而且我知道为什么修不掉:
这四类不是「还没修」,是「用规则修不了」。 加正则只会带来误报。 它们的存在,正是这条链路上必须保留人工审批的原因 —— 纵深防御不是口号。
下一步:这套用例是自己写的,可信度天花板就在那。 计划接入 NVIDIA Garak 与 Microsoft PyRIT 这类业界工具, 用第三方用例集解决「自己出题自己阅卷」的问题。
免责与取舍(逐条都是当前事实,2026-10-13 复核):
① 所有数字都来自上面的公开只读端点,取不到就写「未接入 / 上次同步」,不补假数据、不用样本冒充真实;
② /api/public/audit 展示的是真实封禁与处置留痕,并在卡片里写明来源,而不是编一条 live 数据;
③ /api/public/latest 已上线:返回窗口聚合(windowSize=200 / windowAlertCount /
severityCounts / sourceCounts / latestEvent / latestBlock),字段全部来自公开白名单
(来源 IP 显示为前三段 + 末段 x,不含标题、内网目的地址、聚合 id)。此前文档里写的"404 未上线"是旧结论,已更正;
④ 明细下钻端点 /api/public/alerts/{aggId} 仍未上线,所以监测中心只展示聚合记录自带的字段,
不额外拼一份「原始事件列表」;
⑤ 蜜罐命令时间线(commandsAvailable=false)保持「数据源未接入」,不编造命令内容;
⑥ HTTP 状态码分布与 7 天 × 24 小时热力格没有画:公开端点里没有 statusCode / httpStatus 字段,
也没有历史日桶 —— 监测中心底部把这两项如实列成"读不到",而不是拿 24h 数据伪装成 7 天;
⑦ 前端不做匿名常驻 SSE / WebSocket,秒级实时只给登录后的私有后台。

正在读取…
欢迎回来。这里的数字都来自真实只读接口 —— 取不到我就直说读不到。