监控系统事件的脚本如何编写

wen 实用脚本 1

本文目录导读:

监控系统事件的脚本如何编写

  1. 使用 Linux 内核审计系统(Auditd)
  2. 使用 inotify(文件系统事件)
  3. 监控系统日志(Syslog / Journald)
  4. 使用 eBPF(现代高性能监控)
  5. 跨平台方案(使用 Python 的 watchdog)
  6. Windows 事件日志监控(PowerShell)
  7. 通用脚本设计最佳实践
  8. 完整监控框架结构(Bash 版)

编写监控系统事件的脚本通常涉及操作系统级的事件追踪(如文件变更、进程创建、登录日志)或应用程序级的事件(如日志异常、性能指标超标),具体实现方式取决于操作系统和目标事件类型。

以下分场景介绍核心方法和示例脚本:

使用 Linux 内核审计系统(Auditd)

适合监控文件访问、系统调用、进程执行等底层事件。

步骤:

  • 安装 auditd:sudo apt install auditd -y
  • 添加规则:sudo auditctl -w /etc/passwd -p rwxa -k passwd_changes
  • 编写脚本轮询日志:
    #!/bin/bash
    # 监控 /etc/passwd 的写操作
    tail -Fn0 /var/log/audit/audit.log | while read line; do
      if echo "$line" | grep -q "passwd_changes"; then
          echo "[ALERT] 文件被修改: $(date)"
          # 可发送告警(如 mail/curl)
          # echo "$line" | mail -s "Security Alert" admin@example.com
      fi
    done

使用 inotify(文件系统事件)

适合监控特定目录的文件创建、修改、删除。

Python 示例(依赖 inotify):

#!/usr/bin/env python3
import pyinotify
import logging
class EventHandler(pyinotify.ProcessEvent):
    def process_IN_CREATE(self, event):
        logging.warning(f"文件创建: {event.pathname}")
    def process_IN_DELETE(self, event):
        logging.warning(f"文件删除: {event.pathname}")
    def process_IN_MODIFY(self, event):
        logging.warning(f"文件修改: {event.pathname}")
wm = pyinotify.WatchManager()
handler = EventHandler()
notifier = pyinotify.Notifier(wm, handler)
wm.add_watch('/var/log', pyinotify.IN_CREATE | pyinotify.IN_DELETE | pyinotify.IN_MODIFY, rec=True)
notifier.loop()

监控系统日志(Syslog / Journald)

适合监控 SSH 登录失败、sudo 使用等安全事件。

Bash 示例(监控 SSH 暴力破解):

#!/bin/bash
journalctl -f -u sshd -n 0 | while read line; do
    if echo "$line" | grep -qi "Failed password"; then
        ip=$(echo "$line" | grep -oP 'from \K[0-9.]+')
        count=$(grep -c "Failed password for.*$ip" /var/log/auth.log 2>/dev/null)
        if [ "$count" -gt 5 ]; then
            echo "检测到 SSH 爆破攻击,IP: $ip 失败次数: $count" 
            # 可追加到防火墙黑名单
            # iptables -A INPUT -s $ip -j DROP
        fi
    fi
done

使用 eBPF(现代高性能监控)

适合自定义内核级跟踪,如监控特定系统调用。

Python 示例(使用 bcc 库监控 openat 系统调用):

#!/usr/bin/env python3
from bcc import BPF
bpf_text = """
int trace_openat(struct pt_regs *ctx, int dfd, const char __user *filename) {
    bpf_trace_printk("Open file: %s\\n", filename);
    return 0;
}
"""
b = BPF(text=bpf_text)
b.attach_kprobe(event="do_sys_openat2", fn_name="trace_openat")
b.trace_print()

跨平台方案(使用 Python 的 watchdog)

安装依赖: pip install watchdog

#!/usr/bin/env python3
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class MyHandler(FileSystemEventHandler):
    def on_any_event(self, event):
        print(f"[{time.ctime()}] 事件类型: {event.event_type} 路径: {event.src_path}")
        # 可在此发 HTTP 回调、写数据库等
observer = Observer()
observer.schedule(MyHandler(), path='/data/monitor', recursive=True)
observer.start()
try:
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    observer.stop()
observer.join()

Windows 事件日志监控(PowerShell)

# 监控安全日志中的登录失败(EventID 4625)
$logName = 'Security'
$eventId = 4625
$watcher = New-Object System.IO.FileSystemWatcher
Register-ObjectEvent -InputObject (Get-WmiObject -Class Win32_NTLogEvent -Filter "LogFile='$logName' AND EventCode=$eventId") -EventName "InstanceCreationEvent" -Action {
    $event = $EventArgs.NewEvent
    Write-Host "登录失败 - 用户: $($event.UserName) 时间: $($event.TimeGenerated)"
    # 可触发动作:发送邮件、写入文件
}
# 保持会话运行
while ($true) { Start-Sleep -Seconds 5 }

通用脚本设计最佳实践

  1. 持久化运行:使用 systemd 服务或后台进程(nohup / &)
  2. 告警机制:集成邮件(sendmail)、即时通讯(Slack Webhook)、钉钉机器人
  3. 日志去重与限流:避免高频事件刷屏,使用状态缓存(如 redis)
  4. 错误恢复:遇到异常后尝试重启(try-except / trap)
  5. 性能优化:对高频事件使用批量处理,避免长时间阻塞

完整监控框架结构(Bash 版)

#!/bin/bash
MONITOR_DIR="/data/critical"
LAST_STATE_FILE="/tmp/monitor_state.txt"
# 获取当前快照
find "$MONITOR_DIR" -type f -printf '%s %p\n' | sort > /tmp/current_state.txt
if [ -f "$LAST_STATE_FILE" ]; then
    diff "$LAST_STATE_FILE" /tmp/current_state.txt | while read line; do
        if echo "$line" | grep -q "^>"; then
            echo "新增文件: ${line:1}"
        elif echo "$line" | grep -q "^<"; then
            echo "文件被删除: ${line:1}"
        fi
    done
fi
cp /tmp/current_state.txt "$LAST_STATE_FILE"

根据具体场景选择合适的技术栈:

  • 内核级/安全审计 → Auditd / eBPF
  • 文件变化监控 → inotify / Watchdog
  • 日志文本监控 → journalctl / tail + grep
  • Windows 系统 → Event Log + PowerShell

建议优先使用成熟的监控系统(Prometheus + Node Exporter、Zabbix),仅在需要高度定制或轻量级场景时编写脚本。

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