# 2026-09-11 工作日志 - 22:40 | FIX | 服务器监控脚本告警去重改造:fail2ban 封禁 IP 改为「仅新增封禁推送一次」。**原因**=IP `157.230.37.93` 被 fail2ban 封禁后(bantime 1h),脚本每 10 分钟重复推送 Bark 告警(日志 21:40~22:30 连续 6 条 ALERT)。**根因**=脚本第 3 段逻辑为「Banned IP list 非空即 alert」,无状态记忆。**改法**=新增状态文件 `/var/lib/server-monitor/banned-ips.state`(记录当前已封禁 IP 集合),仅对不在集合中的 IP 告警;状态同步为当前封禁列表,已解封 IP 自动移出(日后再被封视为新事件、可再提醒)。**验证**=真实环境当前封禁「本轮告警=无→静默」;模拟 5 轮全部符合预期(新封→提醒 / 列表不变→静默 / 解封→剔除 / 再封→再提醒 / 全解封→清空);`bash -n` 语法通过。**留档**=脚本备份 `/usr/local/bin/server-monitor.sh.bak.20260911`;本地副本 `.workbuddy/tmp/server-monitor.sh`。**顺带记录**=cron 位置确认为 xxcool crontab(`*/10 * * * * sudo /usr/local/bin/server-monitor.sh`);bantime=1h/findtime=10m/maxretry=5(`/etc/fail2ban/jail.local`);日志 204K 暂无需轮转。 - 23:00 | CHG | 监控脚本告警去重**终版**(三项全部去重,状态目录 `/var/lib/server-monitor/`):① fail2ban 封禁 IP 改为**永久去重**(`banned-ips.state` 只增不减,同一 IP 此生只提醒一次,解封不重置);② 新增「**新来源 IP 登录**」替代原「新增 SSH 登录」(`ssh-src-ips.state`,只有没见过的 IP 首次登录才提醒,避免自己日常登录刷屏);③ 未登记端口漂移同样只提醒一次(`ports.state`,端口消失后清除)。**验证**=预置 30 天内 16 个已知登录 IP + 当前封禁 IP 后手动执行,输出 `[OK]`、零 Bark 推送;`bash -n` 通过。完整审计仍在 `/var/log/fail2ban.log` + journald,且已上报 admin 后台,去重不影响追溯。 - 23:05 | SEC | **服务器入侵排查(只读体检)结论:未发现被入侵迹象**。查了 15 类:UID0 账号仅 root、无空密码账号、无异常 SUID、`ld.so.preload` 空、`rc.local` 仅腾讯云自身脚本、shell 配置无下载/反弹特征、`/etc/hosts` 无劫持、近 30 天系统目录无改动、无特权容器、无异常内核模块。SSH 成功率来源 IP 全部为本人出口且指纹 = 本地 `xpcool_ed25519`(`SHA256:GKWT/a9o…`),`authorized_keys` 仅 3 把(旧 `skey-q6pq6jb3` 已移除)。外网暴露面=**仅 22025/80/443**,3000/2222/8081/8080/8082/18080/10100/3306 实测全部阻断。**两个"未知物"已查清**:① `/usr/local/bin/server-security-collector.sh`(cron 每 5 分钟)是自建安全日志上报器,把 sshd 认证 + fail2ban Ban/Unban 增量 POST 到 `127.0.0.1:10100/api/service/open/security/log/report`,配置 `/etc/server-security.conf`、状态 `/var/lib/server-security/last.ts`,属正常业务;② `/tmp/cj.txt`(libcurl cookie)、`/tmp/http-server.log`(9-3 临时调试)为历史残留,无害。**重要溯源发现**:`1.204.105.116`(本机出口)曾于 **09-03 23:00 被自己的 fail2ban 封禁**,直到 09-04 23:00 才解封 —— 这正是当时「SSH 22025 超时」的真因(当时误判为安全组问题)。**待办建议**:`X11Forwarding yes` 可关;`lighthouse` 账号(腾讯云自带 uid1000)也是 NOPASSWD ALL,可考虑锁定;nginx conf.d 内有 `.code.xpcool.com.conf.swo`、`tool.xpcool.com.conf.download.0` 等遗留文件可清理。 - 23:56 | SEC | **收尾加固三项全部完成**:① **关闭 X11Forwarding**:实际生效位置是 drop-in `/etc/ssh/sshd_config.d/50-redhat.conf:17`(主配置 `sshd_config:103` 是注释,被 Include 覆盖)→ 备份 `.bak.20260911` → sed 改为 `no` → `sshd -t` PASS → `sshd -T` 确认 `x11forwarding no` → `systemctl reload sshd`(不断连)成功。② **清理 nginx 遗留垃圾**:`/data/nginx/conf.d/` 下 `.code.xpcool.com.conf.swo`(vim 8.2 交换文件)与 `tool.xpcool.com.conf.download.0`(内容与 `tool.xpcool.com.conf` **完全相同**的下载残留);两者本就不匹配 include 规则 `*.conf` 未被加载 → 移入备份区 `/data/nginx/_junk_backup_20260911/`(未直接删,可回滚)→ `nginx -t` OK + reload;conf.d 现仅 8 个正式 `.conf`。全盘扫描 `/data/nginx` `/etc/nginx` 再无其他 `.swo/.swp/~/bak/download/save/orig/rej` 残留。③ **爆破告警改为状态机去重**:第 1 段原逻辑「10 分钟内失败 ≥10 即 alert」在攻击持续时会每 10 分钟刷屏 → 新增状态文件 `/var/lib/server-monitor/ssh-brute.state`(`attacking`/`idle`):进入攻击态时提醒一次并置 `attacking`;失败数回落时**静默复位**为 `idle`(只写 `[INFO]` 日志不推送);**下次再犯视为新一波,重新提醒一次**。告警内容同时增强(附失败次数最多的前 3 个来源 IP)。**验证**=① 模拟 9 轮链路(开始→持续 3 轮→停止→平静→新一波→持续→再停):推送仅 2 次、复位 2 次、持续期间 0 推送 ✅;② 生产脚本手动执行输出 `[OK]`、零推送;③ 站点复验 file/admin/tool/read 四站全 HTTP 200。部署前已按当前失败数(0)预置状态为 `idle`,避免改造瞬间补推。脚本备份 `/usr/local/bin/server-monitor.sh.bak.20260911b`。**遗留待办**:`lighthouse` 账号是否锁定待用户决策。 - 23:58 | DOC | 技能 `linux-server-security-audit` 更新:新增「周期复发型(爆破攻击)状态机去重」策略与代码模板(含"复位分支绝不调 alert()"要点)、新增「SSH/sysctl 配置加固标准做法」(定位 drop-in 生效位置 → 备份 → `sshd -t` 预检失败自动回滚 → `sshd -T` 核对 → reload 不断连)、新增「配置目录遗留垃圾清理」小节(核对内容后移入备份区而非直接删)。