活力39282
在线时间13640 小时
阅读权限200
管理员
自由的灵魂
- 积分
- 107434
- 主题
- 5630
- 回帖
- 26661
- 注册时间
- 2003-4-10
- 最后登录
- 2026-10-2
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
🔴 问题现象
- 仪表盘显示持久化黑名单 302,751(后增至 320,427)
- 但日志 persistent.log / realtime.log 数小时无更新
- fail2ban-persistent.json 时间戳正常(说明数据生成未停)
- 关键错误日志:ERROR: 当前用户无权访问 ipset(请以 root 身份运行)出现在 20:30、21:00、21:30(每 30 分钟一次)
🧭 排查路径与关键认知迭代
| 阶段 | 假设 | 验证方式 | 结论 | | 1️⃣ 初判 | 日志未写入 = 脚本未运行 | 查看 JSON 时间戳 | ❌ 脚本在运行,只是日志静默 | | 2️⃣ 权限怀疑 | cron 任务非 root 执行 | sudo crontab -l | ✅ 任务确实在 root cron 中 | | 3️⃣ 调度器怀疑 | 宝塔 or systemd 重复调度 | 检查宝塔 + systemctl list-timers | ❌ 仅 root cron 在工作 | | 4️⃣ 脚本逻辑怀疑 | generate-persistent.sh 自己读 ipset | 检查脚本内容 | ❌ 实际是 export-ips.sh 报错 | | 5️⃣ 环境怀疑 | cron 的 PATH 缺失导致 ipset 命令找不到 | which ipset + 模拟 cron 环境 | ✅ 根本原因确认 |
🎯 根本原因(Root Cause)
💡 Cron 的默认 PATH 不包含 /sbin,而 ipset 位于 /sbin/ipset
→ 脚本中 ipset list 命令找不到可执行文件 → 返回非零退出码
→ 触发脚本中的“权限错误”提示(误报,实际是命令未找到)
- # cron 默认 PATH(典型值)
- PATH=/usr/bin:/bin
- # ipset 实际位置
- /sbin/ipset ← 不在 PATH 中!
复制代码
✅ 解决方案在脚本开头显式设置完整 PATH:
- #!/bin/bash
- PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- # ... rest of script
复制代码
修复后,ipset 命令可被找到,权限检查通过,流程正常。
🛠️ 经验总结(避坑指南)
| 教训 | 正确做法 | | 不要用“权限错误”笼统提示命令失败 | 区分:command not found vs permission denied | | Cron 环境 ≠ 交互式 Shell | 所有脚本必须显式设置 PATH、HOME 等环境变量 | | 日志来源要清晰 | 避免 cron 重定向 + 脚本日志双写,统一日志出口 | | 先确认调度源,再改逻辑 | 用 crontab -l、systemctl list-timers、pstree 精准定位 | | 模拟 cron 环境测试 | 用 env -i PATH=... script.sh 验证 |
🔧 推荐加固措施(可选)
- 脚本开头加 PATH(已做)
- 用 command -v ipset 预检命令存在性
- 日志中加入 [USER] 和 [ENV
ATH=...] 调试信息 - 使用 flock 防止 cron 任务堆积
🌟 最终状态
- ✅ 实时防护:60,183 IP
- ✅ 持久化黑名单:320,427 IP
- ✅ 更新时间:00:32(与当前时间一致)
- ✅ 无权限错误日志
系统稳定运行,问题闭环。
📌 一句话心得:
“在自动化脚本中,永远不要假设环境变量和你终端里一样。”
保存此笔记,下次遇到类似“权限错误”,先查 PATH!💪
|
|