0

0

/var/log/audit/audit.log 被外部进程删除的 inotify 监控与恢复

舞姬之光

舞姬之光

发布时间:2026-01-30 20:09:44

|

622人浏览过

|

来源于php中文网

原创

inotify无法触发事件是因为文件被彻底删除后watch自动移除,且auditd不会自动重建日志文件;需通过SIGHUP重载配置恢复监控,或用audit规则记录删除行为。

/var/log/audit/audit.log 被外部进程删除的 inotify 监控与恢复

audit.log 被删后 inotify 无法触发事件的原因

inotify 对已删除的文件句柄会立即失效,IN_DELETE_SELF 事件只在文件被 unlink 但仍有进程打开时触发;一旦 /var/log/audit/audit.log 被外部进程(如 logrotate、恶意脚本)彻底删除且 auditd 未重开日志文件,inotify watch 就自动移除,后续写入也不会恢复监控。

常见错误现象:inotifywait -m -e delete_self /var/log/audit/audit.log 在文件被删后静默退出,或直接报 No such file or directory

  • auditd 默认使用 log_file 配置项指定日志路径,但不保证文件存在时才打开 —— 它会在启动时创建,但不会在运行中自动重建被删文件
  • 即使你用 IN_MOVED_TO 监控目录,也捕获不到 audit.log 被删后的新文件名(比如 audit.log.1),因为 rename 不等于 recreate
  • Linux 内核 5.10+ 对 inotify 的 watch 限制更严格,重复 add_watch 可能因 ENOSPC 失败,需检查 /proc/sys/fs/inotify/max_user_watches

用 inotifywait + auditd 重启实现有限恢复

真正可行的“恢复”不是自动重建文件,而是检测删除后强制 auditd 重新打开日志文件。这依赖 auditd 支持 SIGHUP 重载配置(默认开启),且日志路径在 /etc/audit/auditd.conf 中是静态路径(非带时间戳的轮转路径)。

一个最小可用监控脚本逻辑:

#!/bin/bash
LOG="/var/log/audit/audit.log"
CONF="/etc/audit/auditd.conf"

while true; do if [[ ! -f "$LOG" ]]; then

文件消失:先确保目录存在,再发信号让 auditd 重建

mkdir -p "$(dirname "$LOG")"
killall -HUP auditd 2>/dev/null
# 等 auditd 重开(通常 < 1s),再继续监控
sleep 0.5

fi

Cutout.Pro
Cutout.Pro

AI驱动的视觉设计平台

下载

仅当文件存在时才加 watch,避免 inotifywait 报错退出

inotifywait -q -e delete_self "$LOG" 2>/dev/null && { echo "$(date): $LOG was deleted, triggering auditd reload" >> /var/log/audit/watcher.log } done

  • 不能依赖 inotifywait -m 长期运行,必须在外层用 while 循环兜底判断文件是否存在
  • killall -HUP auditdsystemctl reload auditd 更快,且不依赖 systemd;但需确保 auditd 进程名确实是 auditd(RHEL 8+ 可能为 auditd.service
  • 该方案对 logrotate 的正常轮转无效 —— 因为 logrotate 默认用 copytruncatecreate,不会真删原文件;只有暴力 rm 才触发

比 inotify 更可靠的替代方案:auditd 自身规则 + ausearch

与其监控文件系统事件,不如用 auditd 的内核级审计能力记录谁删了它。在 /etc/audit/rules.d/immutable.rules 中添加:

-a always,exit -F path=/var/log/audit/audit.log -F perm=w -k audit_log_delete

然后执行 augenrules --load。之后任何进程对该文件的 unlink、rename、truncate 操作都会被记录。

  • ausearch -i -k audit_log_delete 可查到完整调用,包括 UID、PID、命令行参数
  • 该规则不受文件是否存在的影响 —— audit 规则基于路径字符串匹配,只要路径字段一致就生效
  • 注意:如果攻击者先删规则再删日志(auditctl -D),这条规则就失效;所以应设为 immutable:echo "auditctl -e 2" >> /etc/rc.local

audit.log 删除后能否完全恢复内容?

不能。auditd 不缓存未写入磁盘的日志,一旦文件被删且 auditd 未及时重开,正在 buffer 中的日志条目就永久丢失。唯一可能保留部分数据的场景是:

  • auditd 开启了 flush = incrementalfreq = 20(默认),意味着最多丢最近 20 条
  • 文件被删前刚完成一次 sync,而内核 page cache 还没刷盘 —— 此时从 /proc/kcore 或内存镜像中可能恢复,但实操门槛极高,不具通用性
  • 系统启用了 auditd 的 remote logging(如 tcp_client),那日志副本在远端服务器上

所以重点永远在「防止删」和「快速告警」,而不是幻想恢复。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

237

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

458

2024.03.01

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

97

2023.09.25

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

320

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1502

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

624

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

653

2024.03.22

C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

12

2026.01.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 8.1万人学习

Git 教程
Git 教程

共21课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号