服务器监控告警全量去重(封禁IP/登录来源/端口);完成入侵排查体检(结论:未被入侵)
This commit is contained in:
parent
4a6477d5b6
commit
09ccc59ebf
@ -1,3 +1,5 @@
|
||||
# 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` 等遗留文件可清理。
|
||||
|
||||
@ -57,7 +57,7 @@
|
||||
- 权限映射:admin_menu type=2 行的 path 必须匹配实际路由(现为 `POST /api/service/admin/...`,见 manifest/sql/007_menu_permissions_v3.sql)。
|
||||
- 文件下载站(2026-09-03 上线,当晚迁移):`file.xpcool.com` = **FileBrowser Quantum** 容器 `fbq`(`gtstef/filebrowser:stable` v1.5.5,`127.0.0.1:10881→80`,restart unless-stopped,`/data/share:/srv:ro` **只读挂载**,数据卷 `/data/filebrowser-q`:config.yaml+database.db+tmp,属主=镜像 uid1000)+ nginx 反代。**要点**:初始凭据 **admin/admin**(首登后立即改密);配置走 `config.yaml`(sources/cacheDir),管理走网页 UI;API 与原版不兼容(需用户建 long-live token,/swagger 亦需);镜像默认非 root(uid1000);原版 filebrowser(容器 `filebrowser`/10880/db `/data/filebrowser/database`)已于 2026-09-01 归档、现已停用**保留回滚**;Quantum v2.0 beta 权限模型改 per-source(view/download/modify/create/delete)。改密/建只读账号/临时分享(过期+密码+匿名)均在网页 UI。
|
||||
- SSH 凭据/密码不入库,需要时询问用户或查对话记忆;远程批量命令用 paramiko 脚本(`%TEMP%\wb_deploy\ssh_exec.py`,支持第 2 参数超时秒数),docker build 用服务器端 nohup+日志轮询防超时。**(2026-09-11 密钥轮换后更新)**:当前登录 = 本地 `~/.ssh/xpcool_ed25519`(ed25519,注释 xpcool-server-20260904)→ `xxcool@193.112.118.168:22025`(root 被拒;密码登录已禁);旧 `CentOS.pem`(RSA,对应服务器公钥 `skey-q6pq6jb3`)**已作废并从 authorized_keys 移除**(因私钥误提交 Gitea 事件而轮换),服务器 authorized_keys 另存 2 把钥(`mcp-server-manager@local`、`xxcoolwork@gmail.com`)为其他用途、保留不动;安全组按出口 IP 限放 22025(本机出口 1.204.105.116 曾因未放行连不上,80/443 可达);本机旧记录 `~/.ssh/id_ed25519` 与 wb_deploy 脚本**在当前设备不存在**。
|
||||
- **服务器安全加固(2026-08-27 完成)**:firewalld 已启用(放行 22025/80/443/3000/2222;cockpit/rpcbind 已停);fail2ban 保护 sshd(port=22025, maxretry5/bantime1h);监控脚本 `/usr/local/bin/server-monitor.sh` + cron 每 10 分钟(调度在 **xxcool 的 crontab**:`*/10 * * * * sudo /usr/local/bin/server-monitor.sh`;日志 `/var/log/server-monitor.log`,Bark 推送配 `/etc/server-monitor.conf` 的 `BARK_URL`);**fail2ban 封禁告警已去重(2026-09-11)**:状态文件 `/var/lib/server-monitor/banned-ips.state` 存当前封禁 IP 集合,仅对**新增**封禁推送一次;已解封 IP 自动移出状态,日后再被封视为新事件可再提醒(脚本备份 `server-monitor.sh.bak.20260911`);dnf-automatic 每天 06:00 自动安全补丁;SSH 密钥登录已部署(本地 `~/.ssh/id_ed25519`)但用户要求保留密码登录。**坑**:① 腾讯云安全组未放行 3000/2222/8081,Gitea 走 nginx 反代 80/443;② 改 sshd 前必须先 `sshd -t` 预检+备份(曾因脏行导致 SSH 断开);③ EPEL 源需腾讯云镜像(`mirrors.cloud.tencent.com/epel`)且 baseurl 必须手动写全;④ CentOS9 的 fail2ban 在 EPEL。**⑤(2026-09-04 新坑)腾讯云改带宽若切计费模式会触发实例冷重启,重启后 firewalld 自定义端口规则曾丢失致 SSH 22025 失联(80/443 正常)——firewall-cmd 放行务必带 `--permanent`,且实例冷重启后要复查 22025 放行**。另:带宽 3M→5M 已升级(2026-09-04,实测 619KB/s 满速)。
|
||||
- **服务器安全加固(2026-08-27 完成)**:firewalld 已启用(放行 22025/80/443/3000/2222;cockpit/rpcbind 已停);fail2ban 保护 sshd(port=22025, maxretry5/bantime1h);监控脚本 `/usr/local/bin/server-monitor.sh` + cron 每 10 分钟(调度在 **xxcool 的 crontab**:`*/10 * * * * sudo /usr/local/bin/server-monitor.sh`;日志 `/var/log/server-monitor.log`,Bark 推送配 `/etc/server-monitor.conf` 的 `BARK_URL`);**告警去重终版(2026-09-11)**:状态目录 `/var/lib/server-monitor/` —— `banned-ips.state`(已提醒过的封禁 IP,**只增不减 → 同一 IP 永不重复提醒**)、`ssh-src-ips.state`(已提醒过的登录来源 IP,**仅新 IP 首次登录**才提醒)、`ports.state`(当前已告警的未登记端口,消失后清除);完整审计仍在 fail2ban.log + journald 且已上报 admin 后台(脚本备份 `server-monitor.sh.bak.20260911`);另有安全日志上报器 `/usr/local/bin/server-security-collector.sh`(cron **每 5 分钟**,xxcool crontab)→ POST 到 `127.0.0.1:10100/api/service/open/security/log/report`,配置 `/etc/server-security.conf`(INTERNAL_TOKEN)、状态 `/var/lib/server-security/last.ts`;dnf-automatic 每天 06:00 自动安全补丁;SSH 密钥登录已部署(本地 `~/.ssh/id_ed25519`)但用户要求保留密码登录。**坑**:① 腾讯云安全组未放行 3000/2222/8081,Gitea 走 nginx 反代 80/443;② 改 sshd 前必须先 `sshd -t` 预检+备份(曾因脏行导致 SSH 断开);③ EPEL 源需腾讯云镜像(`mirrors.cloud.tencent.com/epel`)且 baseurl 必须手动写全;④ CentOS9 的 fail2ban 在 EPEL。**⑤(2026-09-04 新坑)腾讯云改带宽若切计费模式会触发实例冷重启,重启后 firewalld 自定义端口规则曾丢失致 SSH 22025 失联(80/443 正常)——firewall-cmd 放行务必带 `--permanent`,且实例冷重启后要复查 22025 放行**。另:带宽 3M→5M 已升级(2026-09-04,实测 619KB/s 满速)。**⑥(2026-09-11 溯源新坑)本机出口 IP `1.204.105.116` 曾于 09-03 23:00 被自己的 fail2ban 封禁、09-04 23:00 才解封——这正是当时「SSH 22025 超时」的真因(当时误判为安全组未放行,绕了远路)。SSH 突然不通时,排查顺序应为:先 `fail2ban-client status sshd` + `grep Ban /var/log/fail2ban.log`,再怀疑安全组**。**⑦(2026-09-11 体检结论)服务器未发现被入侵迹象**:UID0 仅 root、无空密码账号、无异常 SUID/后门/劫持、无特权容器、系统目录近 30 天无改动;外网暴露面实测仅 **22025/80/443**(3000/2222/8081 等均被安全组挡住,firewalld 虽放行 3000/2222 但安全组是第二道闸)。
|
||||
- 本地 pnpm 修复(2026-08-27 升级为 wrapper 方案):根因=本环境 MSYS 路径转换故障,把 `/c/...` 参数转成 `E:\c\...`(多 `E:\c\` 前缀)致 corepack shim 与 node 都找不到 pnpm.js。**已建持久 wrapper**:`~/.workbuddy/binaries/node/bin/pnpm`(内容:`export NODE_OPTIONS=--experimental-sqlite; exec "<托管node.exe>" "C:/Users/ybtdevxxl/.workbuddy/binaries/node/workspace/node_modules/pnpm/bin/pnpm.cjs" "$@"`,关键=给 node 传 Windows 风格路径 `C:/...` 规避 MSYS 转换)。**提交/构建前需 `PATH="~/.workbuddy/binaries/node/bin:$PATH"` 前置**,pre-commit 钩子(lefthook oxlint/oxfmt/eslint/stylelint/checkType)即可正常运行;否则钩子崩 → 只能 --no-verify。已验证 pnpm 11.16.0 + `pnpm exec oxlint` 1.79.0。
|
||||
|
||||
## 日常同步习惯(建议)
|
||||
|
||||
103
.workbuddy/tmp/check-security.sh
Normal file
103
.workbuddy/tmp/check-security.sh
Normal file
@ -0,0 +1,103 @@
|
||||
#!/bin/bash
|
||||
# 服务器安全体检(只读,不做任何修改)
|
||||
echo "################ 1. 账号与提权 ################"
|
||||
echo "--- UID 0 账号(应只有 root)---"
|
||||
awk -F: '$3==0{print " " $1}' /etc/passwd
|
||||
echo "--- 可登录 shell 的账号 ---"
|
||||
grep -E "/(bash|sh|zsh)$" /etc/passwd | awk -F: '{print " " $1 " (uid=" $3 ")"}'
|
||||
echo "--- 空密码账号(应为空)---"
|
||||
awk -F: '($2==""){print " !! " $1}' /etc/shadow 2>/dev/null || echo " (无法读取)"
|
||||
echo "--- /home 目录(按修改时间)---"
|
||||
ls -lt /home/ 2>/dev/null | head -6
|
||||
echo "--- sudoers 非默认条目 ---"
|
||||
grep -rhE "^[[:space:]]*[^#[:space:]]" /etc/sudoers /etc/sudoers.d/ 2>/dev/null | grep -vE "^Defaults|^root[[:space:]]|^%wheel|^#|^$" | sed 's/^/ /' || echo " (仅默认)"
|
||||
|
||||
echo
|
||||
echo "################ 2. 全部 SSH 授权公钥 ################"
|
||||
find / -xdev -name authorized_keys -path "*ssh*" 2>/dev/null | while read f; do
|
||||
echo "--- $f ---"
|
||||
awk 'NF>=3{print " " $3 " [" substr($1,1,20) "...]"}' "$f"
|
||||
done
|
||||
|
||||
echo
|
||||
echo "################ 3. sshd 生效配置 ################"
|
||||
sshd -T 2>/dev/null | grep -iE "^port |^permitrootlogin|^passwordauthentication|^pubkeyauthentication|^authorizedkeysfile|^permitemptypasswords|^allowusers|^x11forwarding" | sed 's/^/ /'
|
||||
|
||||
echo
|
||||
echo "################ 4. 最近登录记录 ################"
|
||||
echo "--- 成功登录(最近)---"
|
||||
last -n 12 2>/dev/null | head -14 | sed 's/^/ /'
|
||||
echo "--- 失败登录尝试(最近,需 root)---"
|
||||
lastb -n 8 2>/dev/null | head -10 | sed 's/^/ /' || echo " (无 btmp 记录)"
|
||||
|
||||
echo
|
||||
echo "################ 5. 定时任务持久化 ################"
|
||||
for u in root xxcool; do
|
||||
echo "--- crontab[$u] ---"
|
||||
crontab -u $u -l 2>/dev/null | grep -vE "^#|^$" | sed 's/^/ /' || echo " (空)"
|
||||
done
|
||||
echo "--- /var/spool/cron 下的用户 ---"; ls /var/spool/cron/ 2>/dev/null | sed 's/^/ /'
|
||||
echo "--- /etc/cron.d 文件 ---"; ls /etc/cron.d/ 2>/dev/null | sed 's/^/ /'
|
||||
echo "--- 周期目录内容 ---"; ls /etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly 2>/dev/null | grep -v ":" | sed 's/^/ /'
|
||||
echo "--- systemd timers ---"; systemctl list-timers --all --no-pager 2>/dev/null | head -6 | sed 's/^/ /'
|
||||
|
||||
echo
|
||||
echo "################ 6. 劫持/预加载类后门 ################"
|
||||
echo "--- /etc/ld.so.preload ---"
|
||||
[ -s /etc/ld.so.preload ] && cat /etc/ld.so.preload | sed 's/^/ !! /' || echo " (空/不存在 = 正常)"
|
||||
echo "--- /etc/rc.local ---"
|
||||
[ -s /etc/rc.local ] && grep -vE "^#|^$" /etc/rc.local | sed 's/^/ /' || echo " (空 = 正常)"
|
||||
echo "--- shell 配置中的下载/反弹特征(curl|wget|/dev/tcp|base64|bash -i)---"
|
||||
HITS=$(grep -rnE "curl[^|]*(sh|base64)|wget[^|]*\.sh|/dev/tcp/|bash -i" /root/.bashrc /root/.bash_profile /root/.profile /home/*/.bashrc /home/*/.bash_profile /etc/profile.d/ /etc/profile /etc/bashrc 2>/dev/null | grep -vE "server-monitor")
|
||||
[ -n "$HITS" ] && echo "$HITS" | sed 's/^/ !! /' || echo " (无明显特征)"
|
||||
echo "--- /etc/hosts(DNS 劫持检查)---"
|
||||
grep -vE "^#|^$" /etc/hosts | sed 's/^/ /'
|
||||
|
||||
echo
|
||||
echo "################ 7. 进程 TOP(CPU) ################"
|
||||
ps aux --sort=-%cpu | head -10 | awk '{printf " %-8s %5s%% %5s%% %s\n", $1, $3, $4, $11" "$12}' | head -10
|
||||
|
||||
echo
|
||||
echo "################ 8. 监听端口(对外) ################"
|
||||
ss -tulnp 2>/dev/null | awk 'NR==1{print " "$0} $1=="tcp"||$1=="udp"{print " "$0}' | head -22
|
||||
|
||||
echo
|
||||
echo "################ 9. 对外连接(ESTABLISHED) ################"
|
||||
ss -tnp state established 2>/dev/null | head -15 | sed 's/^/ /'
|
||||
|
||||
echo
|
||||
echo "################ 10. 临时目录可疑文件 ################"
|
||||
find /tmp /var/tmp /dev/shm -maxdepth 2 -type f 2>/dev/null | head -12 | sed 's/^/ /'
|
||||
echo " (以上应仅为正常的临时文件)"
|
||||
|
||||
echo
|
||||
echo "################ 11. 系统关键目录近期改动的文件(近 30 天) ################"
|
||||
find /usr/bin /usr/sbin /bin /sbin /etc/init.d /etc/systemd/system -newermt "-30 days" -type f 2>/dev/null | head -18 | sed 's/^/ /'
|
||||
|
||||
echo
|
||||
echo "################ 12. SUID 文件(非标准位置需警惕) ################"
|
||||
find /tmp /var/tmp /dev/shm /home -perm -4000 -type f 2>/dev/null | head -8 | sed 's/^/ !! /'
|
||||
echo " (以上为空 = 正常)"
|
||||
|
||||
echo
|
||||
echo "################ 13. Docker 容器 ################"
|
||||
docker ps -a --format " {{.Names}} | {{.Image}} | {{.Status}}" 2>/dev/null
|
||||
echo "--- 特权/危险配置容器 ---"
|
||||
for c in $(docker ps -q 2>/dev/null); do
|
||||
docker inspect -f ' {{.Name}} privileged={{.HostConfig.Privileged}} netmode={{.HostConfig.NetworkMode}} pid={{.HostConfig.PidMode}}' "$c" 2>/dev/null
|
||||
done
|
||||
echo "--- 本地镜像列表 ---"
|
||||
docker images --format " {{.Repository}}:{{.Tag}}" 2>/dev/null | head -14
|
||||
|
||||
echo
|
||||
echo "################ 14. 内核模块 ################"
|
||||
lsmod 2>/dev/null | awk 'NR>1{print " "$1}' | head -20
|
||||
|
||||
echo
|
||||
echo "################ 15. 云安全 agent 状态 ################"
|
||||
for s in yunjing barad_agent sgagent tat_agent; do
|
||||
st=$(systemctl is-active $s 2>/dev/null)
|
||||
echo " $s: ${st:-未安装/未知}"
|
||||
done
|
||||
echo
|
||||
echo "################ 体检结束 ################"
|
||||
@ -3,14 +3,19 @@
|
||||
# 服务器安全与资源监控脚本(轻量版)
|
||||
# 功能:
|
||||
# 1. SSH 爆破检测(10分钟内失败认证超阈值)
|
||||
# 2. 新增 SSH 登录记录
|
||||
# 3. fail2ban 新增封禁 IP(同一 IP 仅提醒一次;解封后再被封会重新提醒)
|
||||
# 2. 新来源 IP SSH 登录(仅"没见过的新 IP"首次登录时提醒,避免自己日常登录刷屏)
|
||||
# 3. fail2ban 新封禁 IP(同一 IP 只提醒一次,永久去重)
|
||||
# 4. 根分区磁盘、内存、系统负载告警
|
||||
# 5. 未登记的公网监听端口变化告警(暴露面漂移)
|
||||
# 5. 未登记的公网监听端口变化告警(同一端口只提醒一次)
|
||||
# 告警方式:写日志 /var/log/server-monitor.log + 可选 Bark 推送
|
||||
# Bark 配置:/etc/server-monitor.conf 中设置 BARK_URL 后生效
|
||||
# 部署:/usr/local/bin/server-monitor.sh,配合 cron 每 10 分钟执行
|
||||
# 去重状态:/var/lib/server-monitor/banned-ips.state(存放当前已封禁 IP 集合)
|
||||
# 去重状态目录:/var/lib/server-monitor/
|
||||
# - banned-ips.state :已提醒过的封禁 IP(只增不减 → 同一 IP 永不再重复提醒)
|
||||
# - ssh-src-ips.state:已提醒过的登录来源 IP(仅新 IP 首次登录提醒)
|
||||
# - ports.state :当前已提醒的未登记端口(端口消失后清除,再出现会再提醒)
|
||||
# 说明:完整审计数据仍在 /var/log/fail2ban.log 与 journald,且已由
|
||||
# server-security-collector.sh 上报到 admin 后台,去重不影响追溯。
|
||||
# ============================================================
|
||||
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
|
||||
@ -26,38 +31,44 @@ BARK_URL=${BARK_URL:-}
|
||||
alert() { ALERT="${ALERT}$1
|
||||
"; }
|
||||
|
||||
# 去重状态目录(第 2、3、7 段共用)
|
||||
STATE_DIR=/var/lib/server-monitor
|
||||
mkdir -p "$STATE_DIR" 2>/dev/null
|
||||
BAN_STATE=$STATE_DIR/banned-ips.state
|
||||
SSH_STATE=$STATE_DIR/ssh-src-ips.state
|
||||
PORT_STATE=$STATE_DIR/ports.state
|
||||
touch "$BAN_STATE" "$SSH_STATE" "$PORT_STATE" 2>/dev/null
|
||||
|
||||
# ---------- 1) SSH 爆破检测(近10分钟失败认证) ----------
|
||||
FAILED=$(sudo journalctl _SYSTEMD_UNIT=sshd.service --since "10 minutes ago" 2>/dev/null | grep -ci "Failed password")
|
||||
if [ "${FAILED:-0}" -ge 10 ]; then
|
||||
alert "SSH爆破风险: 10分钟内 ${FAILED} 次密码失败"
|
||||
fi
|
||||
|
||||
# ---------- 2) 新增成功登录 ----------
|
||||
NEWLOGIN=$(sudo journalctl _SYSTEMD_UNIT=sshd.service --since "10 minutes ago" 2>/dev/null | grep -iE "Accepted (password|publickey)" | tail -3)
|
||||
[ -n "$NEWLOGIN" ] && alert "新增SSH登录:
|
||||
$NEWLOGIN"
|
||||
|
||||
# ---------- 3) fail2ban 新增封禁 IP(同一 IP 只提醒一次) ----------
|
||||
# 状态文件记录"当前已封禁的 IP 集合":
|
||||
# - 当前封禁列表里出现状态文件中没有的 IP → 新封禁,告警一次
|
||||
# - 已解封的 IP 会从状态文件移除,若日后再次被封,视为新事件可再提醒
|
||||
STATE_DIR=/var/lib/server-monitor
|
||||
STATE_FILE=$STATE_DIR/banned-ips.state
|
||||
mkdir -p "$STATE_DIR" 2>/dev/null
|
||||
touch "$STATE_FILE" 2>/dev/null
|
||||
# ---------- 2) 新来源 IP 登录(仅首次出现的 IP 才提醒) ----------
|
||||
ACCEPTED=$(sudo journalctl _SYSTEMD_UNIT=sshd.service --since "10 minutes ago" 2>/dev/null | grep -iE "Accepted (password|publickey)")
|
||||
if [ -n "$ACCEPTED" ]; then
|
||||
NEWIPS=""
|
||||
for ip in $(printf '%s\n' "$ACCEPTED" | awk '{for(i=1;i<=NF;i++) if($i=="from") print $(i+1)}' | sort -u); do
|
||||
grep -qxF "$ip" "$SSH_STATE" 2>/dev/null || NEWIPS="${NEWIPS} ${ip}"
|
||||
done
|
||||
if [ -n "$NEWIPS" ]; then
|
||||
alert "新来源IP登录:${NEWIPS}
|
||||
$(printf '%s\n' "$ACCEPTED" | tail -3)"
|
||||
for ip in $NEWIPS; do echo "$ip" >> "$SSH_STATE"; done
|
||||
fi
|
||||
fi
|
||||
|
||||
# ---------- 3) fail2ban 新封禁 IP(同一 IP 只提醒一次) ----------
|
||||
CUR_BANNED=$(sudo fail2ban-client status sshd 2>/dev/null | sed -n 's/.*Banned IP list:[[:space:]]*//p')
|
||||
NEW_BANNED=""
|
||||
for ip in $CUR_BANNED; do
|
||||
grep -qxF "$ip" "$STATE_FILE" 2>/dev/null || NEW_BANNED="${NEW_BANNED} ${ip}"
|
||||
grep -qxF "$ip" "$BAN_STATE" 2>/dev/null || NEW_BANNED="${NEW_BANNED} ${ip}"
|
||||
done
|
||||
# 状态文件同步为当前封禁集合(自动剔除已解封 IP)
|
||||
if [ -n "$CUR_BANNED" ]; then
|
||||
printf '%s\n' $CUR_BANNED > "$STATE_FILE"
|
||||
else
|
||||
: > "$STATE_FILE"
|
||||
if [ -n "$NEW_BANNED" ]; then
|
||||
alert "fail2ban 新封禁IP:${NEW_BANNED}(已自动封禁,无需处理)"
|
||||
for ip in $NEW_BANNED; do echo "$ip" >> "$BAN_STATE"; done
|
||||
fi
|
||||
[ -n "$NEW_BANNED" ] && alert "fail2ban 新封禁IP:${NEW_BANNED}(已自动封禁,无需处理)"
|
||||
|
||||
# ---------- 4) 根分区磁盘 ----------
|
||||
DF=$(df -P / 2>/dev/null | tail -1 | awk '{print $5}' | tr -d '%')
|
||||
@ -83,7 +94,17 @@ for p in $NOW_PORTS; do
|
||||
*) EXTRA="${EXTRA} ${p}" ;;
|
||||
esac
|
||||
done
|
||||
[ -n "$EXTRA" ] && alert "发现未登记的公网监听端口:${EXTRA}(请核查是否为新增服务)"
|
||||
# 同一端口只提醒一次(端口消失后再出现视为新事件)
|
||||
NEW_EXTRA=""
|
||||
for p in $EXTRA; do
|
||||
grep -qxF "$p" "$PORT_STATE" 2>/dev/null || NEW_EXTRA="${NEW_EXTRA} ${p}"
|
||||
done
|
||||
if [ -n "$EXTRA" ]; then
|
||||
printf '%s\n' $EXTRA > "$PORT_STATE"
|
||||
else
|
||||
: > "$PORT_STATE"
|
||||
fi
|
||||
[ -n "$NEW_EXTRA" ] && alert "发现未登记的公网监听端口:${NEW_EXTRA}(请核查是否为新增服务)"
|
||||
|
||||
# ---------- 输出:日志 + Bark 推送 ----------
|
||||
if [ -n "$ALERT" ]; then
|
||||
|
||||
Loading…
Reference in New Issue
Block a user