在Ubuntu服务器上运行auditd审计系统时,最容易被忽视的问题就是日志文件无限增长导致磁盘被占满。一旦/var/log/audit/目录下的audit.log文件把根分区吃光,系统可能直接崩溃、服务中断、SSH无法登录。解决这个问题的核心方法就是给auditd设置磁盘配额——通过配置auditd的max_log_file参数限制单个日志文件大小,再配合logrotate进行日志轮转,同时还可以用磁盘配额工具从文件系统层面兜底。下面我会把每一步操作、每一个参数、每一种场景都讲透。

为什么auditd日志会占满磁盘

auditd是Linux内核审计子系统的用户空间守护进程,它记录系统调用、文件访问、用户登录、权限变更等安全事件。在高负载服务器、频繁SSH登录的机器、或者开启了大量审计规则的环境下,audit.log的增长速度非常快,每天几十MB甚至几百MB都很正常。Ubuntu默认安装auditd后,并没有对日志文件大小做任何限制,max_log_file默认是0(即不限制),这就埋下了隐患。特别是当你配置了auditctl -w /etc/passwd -p wa这类监控敏感文件的规则后,任何对passwd文件的读写操作都会被记录,日志量会急剧膨胀。

第一步:直接修改auditd配置限制单文件大小

打开auditd的主配置文件进行修改,这是最直接的手段。

sudo nano /etc/audit/auditd.conf

找到max_log_file这一行,默认可能是max_log_file = 0或者被注释掉了。把它改成一个合理的值,单位是MB。一般生产环境建议设置为100到500之间,具体取决于你的审计需求和磁盘空间。

max_log_file = 200

这个参数的含义是:当单个audit.log文件达到200MB时,auditd会自动触发日志轮转,生成一个新的audit.log文件。注意,这里不是删除旧日志,而是创建新文件继续写。旧文件需要靠logrotate来处理。

同时建议把下面几个相关参数也一并配置好:

max_log_file_action = ROTATE
num_logs = 5

max_log_file_action设置为ROTATE表示达到大小限制后轮转而不是直接覆盖;num_logs = 5表示最多保留5个旧日志文件。这样你的/var/log/audit/目录下最多会有6个文件(当前1个+历史5个),总占用空间可控。

第二步:配置logrotate实现日志自动清理

光靠auditd自身的轮转还不够,因为旧文件会一直堆积。Ubuntu系统自带logrotate工具,可以定期压缩和删除旧日志。检查是否已有audit的logrotate配置:

ls /etc/logrotate.d/audit

如果文件存在,打开编辑:

sudo nano /etc/logrotate.d/audit

典型的配置内容如下:

/var/log/audit/audit.log {
    rotate 7
    daily
    missingok
    notifempty
    compress
    delaycompress
    postrotate
        /sbin/service auditd restart > /dev/null 2>&1 || true
    endscript
}

这里rotate 7表示保留7个轮转后的旧文件,daily表示每天检查一次是否需要轮转,compress表示用gzip压缩旧日志(能节省大量空间),delaycompress表示延迟一个周期再压缩(方便排查最近的问题)。postrotate里的重启命令是为了让auditd识别新的日志文件。如果你觉得7天太长,可以改成rotate 3,只保留3天的历史日志。

第三步:从文件系统层面设置磁盘配额兜底

上面两步是从应用层控制日志增长,但万一配置出错或者有其他程序也在写/var/log,还是需要文件系统层面的保障。Ubuntu可以用quota工具对/var/log所在的分区设置配额。

首先确认/var/log所在的文件系统和挂载点:

df -h /var/log

假设/var/log在/dev/sda1分区上,且文件系统是ext4。需要在/etc/fstab中添加usrquota和grpquota挂载选项:

sudo nano /etc/fstab

找到对应行,修改为:

/dev/sda1 /var/log ext4 defaults,usrquota,grpquota 0 2

然后重新挂载并初始化配额:

sudo mount -o remount /var/log
sudo quotacheck -cugm /var/log
sudo quotaon /var/log

接下来给审计日志目录设置具体配额限制。假设你想让/var/log/audit目录最多使用2GB空间:

sudo setquota -u root 0 0 2G /var/log
sudo setquota -g root 0 0 2G /var/log

或者更精细地用edquota命令交互式编辑。设置完后用repquota查看当前使用情况:

sudo repquota /var/log

这样即使auditd配置出了问题,文件系统层面也会阻止/var/log继续膨胀,给你留出排查和处理的时间窗口。

第四步:优化审计规则减少不必要的日志量

从源头控制日志量是最高效的策略。很多管理员一上来就开启大量audit规则,结果日志爆炸。建议只监控真正需要的内容。

先查看当前所有审计规则:

sudo auditctl -l

常见的优化策略包括:

1、避免监控高频访问的目录,比如/tmp、/var/tmp,这些地方每秒可能有大量文件创建删除,记录下来全是噪音。

2、对敏感文件使用精确的权限监控而不是全部监控。比如只监控/etc/passwd和/etc/shadow的写操作和属性变更:

sudo auditctl -w /etc/passwd -p wa -k passwd_changes
sudo auditctl -w /etc/shadow -p wa -k shadow_changes

3、排除已知的正常进程产生的审计事件。比如某个备份脚本频繁读取文件,可以用-F排除:

sudo auditctl -w /data -p r -F uid!=1000

4、定期清理不需要的规则,用-d删除:

sudo auditctl -d /data -p r

第五步:监控和告警机制不能少

配置好限额不代表万事大吉,你需要有监控手段知道什么时候快满了。可以写一个简单的shell脚本配合cron定时检查:

#!/bin/bash
LOG_DIR="/var/log/audit"
THRESHOLD=80
USAGE=$(df $LOG_DIR | awk 'NR==2 {print $5}' | sed 's/%//')
if [ $USAGE -gt $THRESHOLD ]; then
    echo "WARNING: $LOG_DIR usage is ${USAGE}%" | mail -s "Disk Space Alert" admin@example.com
fi

保存为/usr/local/bin/check_audit_disk.sh,赋予执行权限:

sudo chmod +x /usr/local/bin/check_audit_disk.sh

加入cron每小时检查一次:

sudo crontab -e
0 * * * * /usr/local/bin/check_audit_disk.sh

第六步:特殊场景的处理建议

如果你的服务器是日志集中收集架构(比如把audit日志转发到远程syslog服务器),本地可以把配额设得更小,比如max_log_file = 50,num_logs = 2,因为本地只是临时缓存。

如果是合规要求必须保留90天以上的审计日志,那就不能只靠本地磁盘。应该把日志实时发送到远程存储或者对象存储,本地只保留最近几天的热数据。可以配置audisp-remote插件:

sudo nano /etc/audisp/plugins.d/syslog.conf

设置active = yes,然后配置rsyslog把audit日志转发出去。

对于容器环境(Docker/Kubernetes),auditd的日志通常挂载在宿主机的/var/log/audit目录下,同样需要在宿主机层面做好配额和轮转配置,否则容器内的审计日志会直接撑爆宿主机磁盘。

总结和最佳实践清单

把所有操作串起来,一套完整的auditd磁盘防护方案应该包括:auditd.conf里设置max_log_file为100-500MB、配置num_logs为3-7个、logrotate设置daily轮转加compress压缩保留3-7天、文件系统层面用quota设置2-5GB的硬上限、审计规则精简只监控关键路径、加上定时监控告警脚本。这六层防护叠加在一起,基本可以杜绝audit日志占满磁盘的问题。记住,安全审计是好事,但不能因为审计本身把系统搞崩了,平衡好安全性和可用性才是真正的运维水平。