Shell脚本如何监控关键目录变更

wen 实用脚本 2

Shell脚本如何监控关键目录变更:实战指南与原理剖析

目录导读

  1. 为什么需要监控关键目录变更?
  2. 监控核心机制:inotify与轮询的对比
  3. 实战:编写一个高性能的目录监控Shell脚本
  4. 高级技巧:过滤噪音与告警集成
  5. 常见问题与解答
  6. 总结与最佳实践

为什么需要监控关键目录变更?

在服务器运维中,/etc、/var/www、/data/db等关键目录的意外变更可能引发严重问题:配置文件被篡改、网站文件被植入恶意代码、数据库文件异常删除,通过Shell脚本监控目录变更,可以:

Shell脚本如何监控关键目录变更

  • 实时发现入侵行为:当攻击者植入后门或修改系统配置时,立即触发告警
  • 捕捉运维误操作:比如误删文件、错误修改权限等
  • 审计文件完整性:配合备份策略,记录每次变更的详细信息

:为什么不用现成的监控工具(如Tripwire)?
:Shell脚本更轻量,易于集成到现有运维体系,且能灵活定制告警逻辑,适合对性能要求较高的场景。

监控核心机制:inotify与轮询的对比

机制 原理 适用场景 资源消耗
inotify 内核级文件事件监听 实时监控、高频率变更 极低(事件驱动)
轮询(cron+find) 定期扫描目录状态 低频监控、兼容老旧系统 高(周期扫盘)

推荐方案:优先使用inotify(Linux 2.6.13+内核支持),如果系统不支持(如某些容器环境),则使用轮询作为降级方案。

:inotify能监控子目录递归吗?
:可以,通过inotifywait-r参数实现递归监听,但注意要设置--monitor保持进程常驻。

实战:编写一个高性能的目录监控Shell脚本

以下脚本使用inotify监控/etc目录,记录变更日志并发送邮件告警:

#!/bin/bash
# 配置区
MONITOR_DIR="/etc"
LOG_FILE="/var/log/dir_monitor.log"
EMAIL_TO="admin@example.com"
EXCLUDE_PATTERN="\.(swp|~)$"  # 忽略临时文件
# 依赖检查
if ! command -v inotifywait &> /dev/null; then
    echo "Error: inotify-tools not installed. Run: apt install inotify-tools"
    exit 1
fi
# 监控主逻辑
inotifywait -m -r --timefmt '%Y-%m-%d %H:%M:%S' --format '%T %w%f %e' \
    "$MONITOR_DIR" | while read datetime file event
do
    # 过滤排除模式
    if [[ "$file" =~ $EXCLUDE_PATTERN ]]; then
        continue
    fi
    # 记录日志
    echo "[$datetime] $event: $file" >> "$LOG_FILE"
    # 对关键变更(如MODIFY, DELETE)发送告警
    case "$event" in
        MODIFY|DELETE|CREATE|MOVED_TO|MOVED_FROM)
            mail -s "ALERT: $event on $file" "$EMAIL_TO" <<< \
                "$(hostname) - $event detected on $file at $datetime"
            ;;
    esac
done

脚本关键点解析:

  • -m:保持监听模式
  • -r:递归子目录
  • --timefmt:自定义时间格式
  • --format:输出格式(时间、路径、事件类型)
  • 性能优化:通过正则排除.*.swp等临时文件,避免日志风暴

:如果监控目录有大量文件(如10万+),inotify能扛住吗?
:默认inotify watch数量有限(/proc/sys/fs/inotify/max_user_watches),需调大:echo 65536 > /proc/sys/fs/inotify/max_user_watches,另外建议拆分监控多个子目录。

高级技巧:过滤噪音与告警集成

1 屏蔽高频无效事件

  • 忽略ACCESSCLOSE_NOWRITE事件(读操作无意义)
  • MODIFY事件增加300ms去重窗口(防止编辑器保存时多次触发)
# 使用flock实现简单去重
flock -w 0.3 /tmp/dir_monitor.lock -c "你的处理逻辑"

2 与第三方告警集成

  • 企业微信机器人:curl -X POST -H "Content-Type: application/json" -d '{"msgtype":"text","text":{"content":"变更告警"}}' https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx
  • 飞书/钉钉:类似webhook方式
  • Prometheus告警:输出metrics到node_exporter

常见问题与解答

Q1:监控进程意外退出怎么办?
A:使用supervisor或systemd守护进程,并添加重启策略:

[Unit]
Description=Directory Monitor
[Service]
ExecStart=/path/to/monitor_script.sh
Restart=always
RestartSec=10

Q2:如何监控网络挂载目录(NFS/SMB)?
A:inotify不支持网络文件系统,改为轮询方案:find /mnt/nfs_dir -newer /tmp/snapshot -type f

Q3:监控日志占满磁盘怎么办?
A:配置logrotate轮转:

/var/log/dir_monitor.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
}

总结与最佳实践

  1. 优先inotify:性能好、实时性强,但注意调整内核参数
  2. 精确过滤:排除临时文件、系统扫描操作,告警才有价值
  3. 分级告警:DELETE/TRUNCATE为高优先级,CREATE/MODIFY为中优先级
  4. 定期测试:每月模拟一次变更,验证告警链路是否正常
  5. 日志审计:配合ELK或Loki进行集中分析,追溯历史变更

通过合理的Shell脚本设计,不仅能监控关键目录,还能成为入侵检测和合规审计的有力工具,监控的目的是发现问题,而不是制造噪音——每一次告警都应该是值得被关注的异常。

抱歉,评论功能暂时关闭!