每天早上一份安全日报:过去 24 小时的告警总数与严重度分布、Top 5 来源国家、 蜜罐连接与登录尝试、封禁/解封数、当日最凶来源 IP,外加一条「值得注意」。 两种形态:语音版(日语口语稿,≤120 字,可以直接听)与 HTML 版(中文表格,每个数字后面都写着它出自哪个端点、哪个窗口)。
日报是公开页面,订阅只是邮件提醒。 内容本身就在 /status/ 的「今日日报」卡里, 任何人随时可以看,不需要订阅、不需要留邮箱。这一页不做表单、不在本站收集邮箱 —— 订阅动作只发生在你自己的邮件客户端里(当前订阅地址未配置,下面如实写明,不画一个点开会退信的按钮):
收邮箱意味着:要存(存哪、谁有权限)、要能退订(不然是骚扰)、要防拖库(小站最容易被盯上的就是订阅表)。 而收益只是"提醒",所以这里选择让邮件系统去记,让网页保持无账号。 具体说,这一页没有:
| 没有的东西 | 意味着什么 |
|---|---|
| 表单 / <input> | 页面里没有任何地方能让你输入邮箱 —— 不存在"提交"这个动作。 |
| 后端订阅接口 | 站点是纯静态的(Hugo 产物),没有可写库的接口可打。 |
| 订阅名单 | 本站不存邮箱;名单只在站主的邮件系统里,退订也在那里生效。 |
| 跟踪像素 / 统计脚本 | 邮件正文不放像素、不放唯一链接;日报 HTML 只引内联样式,不引外部资源。 |
能保证什么、不能保证什么:本页能保证"你没在这台静态站上留下邮箱"; 不能保证"邮件在传输途中不经过任何第三方" —— 那取决于你用哪个邮箱发、站主用哪个 SMTP 发。这一点写清楚,比一句"我们重视隐私"有用。
| 内容 | 数据从哪来 / 口径 |
|---|---|
| 告警总数与严重度分布 | alerts 的 stats24h(过去 24 小时窗口,CRITICAL/HIGH/MEDIUM/LOW)。 |
| Top 5 来源国家与独立 IP 数 | geo 的 byCountry(同一 24h 窗口;过内网/保留/本站 IP 已排除,地理库 DB-IP Lite)。 |
| 蜜罐连接与登录尝试 | honeypot 的最近 800 条 Cowrie 告警 —— 不是 24h 时间窗,日报里照实写这一点。 |
| 封禁 / 解封数 | 处置留痕全量(不限 24h);被护栏拦下多少单独一行。 |
| 今日最凶来源 | 蜜罐 topSources 里尝试次数最多的来源 IP 与次数。 |
| 值得注意的一条 | 单一来源 ≥1000 次尝试,或出现新的端口探测器时才写;没触发就写「未触发判定阈值」。 |
取不到就不编:任何一个数字取不到,日报对应位置写 null,并在最后一节「缺数据」里列出缺的是哪一项、哪个端点没给 ——
就像 /status/ 里那些「未取到」一样,宁可难看,不要假数。
日报不是一直在跑。后端定时任务默认关闭(app.report.enabled=false),
打开后每天 08:10 生成一次;没生成的日子,/status/ 的卡片会写
「今日日报未生成(不是读不到其它数据)」—— 这两种"没有"必须分得清,否则一次重启会被读成"今天天下太平"。
语音版由后端直接调用 TTS 合成(data/reports/daily-YYYY-MM-DD.wav);
合成失败只记日志,不影响文字版 —— 所以偶尔会遇到"有文字、没声音"的一天,那是上游 TTS 的事,不是日报没生成。