Что такое auditd и зачем он нужен на Linux-сервере
auditd это демон подсистемы Linux Audit Framework. Ядро формирует событие при системном вызове, обращении к файлу, запуске процесса или смене учётных данных, а демон забирает поток через netlink-сокет и пишет его в /var/log/audit/audit.log. Отключить такую запись правкой конфига приложения не выйдет: событие рождается до того, как системный вызов вернёт результат.
Практическая ценность сводится к трём вопросам, на которые auditd отвечает за секунды: кто менял конфигурацию SSH, какие команды запускали через sudo и кто обращался к /etc/shadow. Минимальный набор правил для этого занимает три строки.
-w /etc/ssh/sshd_config -p wa -k ssh_config -a always,exit -F arch=b64 -S execve -F exe=/usr/bin/sudo -F auid>=1000 -F auid!=unset -k sudo_cmd -w /etc/passwd -p wa -k passwd_changes
Ключ ssh_config в конце строки это метка события. По ней журнал фильтруется командой ausearch -k ssh_config, и вы получаете список записей с uid, euid, auid, pid, именем команды и временем. Поле auid хранит логин пользователя, который открыл сессию, даже если действие выполнено от root. Именно оно показывает, что за sudo находился конкретный инженер, а не безликий суперпользователь.
Дальше разберём установку демона, синтаксис правил, готовый набор для SSH, sudo и критичных файлов, поиск событий, ротацию журналов, фильтрацию шума и диагностику типичных ошибок.
Чем auditd отличается от syslog и journald
rsyslog и systemd-journald собирают то, что им отдают приложения: свой текст, свой формат, свою полноту. auditd работает уровнем ниже и берёт события у ядра. Разница проявляется в момент инцидента: приложение может не записать неудачную попытку чтения файла, а ядро зафиксирует её всегда, пока правило активно.
| Параметр | auditd | rsyslog | systemd-journald |
|---|---|---|---|
| Источник событий | ядро: системные вызовы, доступ к файлам, execve | приложения и службы | приложения, службы, systemd |
| Кто формирует запись | ядро, демон только читает поток | само приложение | само приложение и systemd |
| Можно обойти правкой конфига приложения | нет | да | да |
| Формат записи | строки type=SYSCALL, type=EXECVE с полем key= | текстовые сообщения RFC 3164 или 5424 | бинарный журнал, чтение через journalctl |
| Где настраивается хранение | /etc/audit/auditd.conf | logrotate | /etc/systemd/journald.conf |
| Типовая задача | аудит доступа к файлам и привилегированных команд | сбор логов сервисов | локальная диагностика |
Вывод простой: auditd не заменяет syslog и journald, а закрывает то, чего у них нет, а именно аудит доступа к объектам и привилегированных действий на уровне ядра. Все три источника спокойно работают на одном сервере.
Когда auditd обязателен: требования CIS, PCI DSS и внутренних политик
CIS Linux Benchmark требует включённый auditd, правила на изменения /etc/passwd, /etc/shadow, /etc/group, /etc/sudoers и аудит привилегированных команд. PCI DSS, требование 10.2, предписывает фиксировать доступ к системным компонентам и действия привилегированных пользователей, а пункт 10.2.5 отдельно говорит об изменениях и удалениях.
Перевод требований в правила выглядит так:
- изменение файлов аутентификации: -w /etc/shadow -p wa -k shadow_changes;
- привилегированные команды: -a always,exit -F arch=b64 -S execve -F exe=/usr/bin/sudo -k sudo_cmd;
- доступ к конфигурации SSH: -w /etc/ssh/sshd_config -p wa -k ssh_config.
Перед настройкой аудита закройте базовые вещи вроде паролей, ключей и лишних портов: чек-лист по аудиту безопасности Linux-сервера проводит по пользователям, sudo, SSH и службам до того, как вы начнёте читать audit.log.
Установка и запуск auditd: пошаговая инструкция
Пакет и служба называются по-разному в разных семействах дистрибутивов.
# RHEL, CentOS, AlmaLinux, Rocky, Fedora dnf install -y audit # Debian, Ubuntu apt update && apt install -y auditd audispd-plugins
systemctl enable --now auditd systemctl status auditd
Служба должна быть в состоянии active (running) и иметь статус enabled. Пакет audispd-plugins в Debian нужен, если планируете пересылать события наружу, например в syslog или на удалённый коллектор.
Новый набор правил удобно обкатывать на отдельной машине, чтобы неудачная строка не забила журнал боевого сервера. Подойдёт недорогой VDS из Timeweb Cloud: развернули копию конфигурации, применили правила, оценили объём событий и только потом перенесли набор на прод.
Проверка, что auditd действительно работает
auditctl -s auditctl -l
Первая команда возвращает состояние подсистемы: enabled (1 означает аудит включён, 2 означает правила заморожены до перезагрузки), pid демона, lost (число потерянных событий), backlog и backlog_limit (текущая и максимальная длина очереди), rate_limit. Значение lost больше нуля говорит о том, что события теряются, и очередь пора увеличивать.
Вторая команда печатает список загруженных правил. Пустой вывод при наличии файлов в /etc/audit/rules.d/ означает, что правила не применены.
Настройка audit=1 в GRUB для гарантированного старта
Без параметра ядра аудит включается только после того, как userspace запустит демон. События первых секунд загрузки, включая старт служб, при этом теряются.
grep GRUB_CMDLINE_LINUX /etc/default/grub # было: GRUB_CMDLINE_LINUX="rhgb quiet" # стало: GRUB_CMDLINE_LINUX="rhgb quiet audit=1 audit_backlog_limit=8192" # Debian, Ubuntu update-grub # RHEL, CentOS grub2-mkconfig -o /boot/grub2/grub.cfg reboot dmesg | grep -i audit
Значение audit=1 включает аудит на старте ядра, audit=2 добавляет панику при невозможности его запустить. Второй вариант выбирают там, где остановка сервера предпочтительнее работы без журнала. Параметр audit_backlog_limit задаёт размер очереди на этапе загрузки, пока демон ещё не поднялся.
Постоянные правила аудита: структура и синтаксис
Правило, добавленное через auditctl, живёт до перезагрузки. Постоянные правила лежат в каталоге /etc/audit/rules.d/ отдельными файлами с числовым префиксом, а утилита augenrules собирает их в /etc/audit/audit.rules по возрастанию номера.
ls -1 /etc/audit/rules.d/ 10-base-config.rules 30-ssh.rules 40-sudo.rules 50-critical-files.rules 99-finalize.rules augenrules --load systemctl restart auditd
Синтаксис у двух форм записи правил такой:
-w /etc/sudoers -p wa -k sudoers_changes -a always,exit -F arch=b64 -S execve -F exe=/usr/bin/sudo -k sudo_cmd
Флаг -w следит за путём, -p перечисляет права (r это чтение, w это запись, x это выполнение, a это смена атрибутов), -k задаёт ключ. Полная форма -a action,list с фильтрами -F даёт больше контроля: path, dir, perm, exe, auid, uid, arch, exit. Ядро разворачивает -w в правило always,exit с фильтром по пути, так что по возможностям обе формы совпадают.
Замыкающее правило -e 2 в файле 99-finalize.rules замораживает конфигурацию, и изменить её можно только перезагрузкой. Это мешает снять аудит на скомпрометированном сервере, но и мешает отладке, поэтому включайте заморозку после того, как набор правил устоялся.
Ключи поиска (-k): как правильно именовать
Ключ это ниточка, которая ведёт от инцидента к событию. Договоритесь о схеме заранее: ssh_config, ssh_keys, sudo_cmd, sudoers_changes, passwd_changes, shadow_changes, cron_changes. Один ключ покрывает одну логическую группу, иначе поиск превращается в перебор. Технические ограничения: без пробелов, до 31 символа, регистр учитывается. Проверка, что ключ читается, занимает секунду:
ausearch -k ssh_config -ts recent -i
Порядок применения правил и приоритеты
Ядро просматривает правила сверху вниз, и первое совпадение решает судьбу события. Правила-исключения (-a never) ставят выше правил-включателей, иначе исключение не сработает. Числовые префиксы файлов дают ровно этот порядок: 10- для базовых настроек и исключений, 30-50 для рабочих правил, 99- для финала.
Список загруженных правил печатает auditctl -l, и порядок строк в выводе совпадает с порядком применения. Проверяйте его после каждой правки: правило с опечаткой в пути не выдаст ошибку, просто не сработает.
Готовые правила аудита для SSH, sudo и критичных файлов
Ниже рабочий набор. Разложите его по файлам в /etc/audit/rules.d/, примените через augenrules --load и проверьте живым событием.
Правила для SSH: конфиги и ключи
-w /etc/ssh/sshd_config -p wa -k ssh_config -w /etc/ssh/sshd_config.d/ -p wa -k ssh_config -w /etc/ssh/ssh_config -p wa -k ssh_client_config -w /root/.ssh/ -p rwa -k ssh_keys -a always,exit -F arch=b64 -F path=/etc/ssh/sshd_config -F perm=r -F auid>=1000 -F auid!=unset -k ssh_config_read
Права wa на sshd_config ловят правку конфигурации, смену владельца и режима доступа. Право r показывает, кто читал файл из пользовательской сессии. Отдельного внимания требуют приватные ключи: правило с -p rwa на /root/.ssh/ фиксирует чтение ключа, и это событие часто оказывается первым признаком компрометации. Если ключи разложены по домашним каталогам, добавьте такое же правило для конкретных путей, следить целиком за /home дорого по объёму событий.
Правила для sudo: команды и изменения sudoers
-a always,exit -F arch=b32 -S execve -F exe=/usr/bin/sudo -F auid>=1000 -F auid!=unset -k sudo_cmd -a always,exit -F arch=b64 -S execve -F exe=/usr/bin/sudo -F auid>=1000 -F auid!=unset -k sudo_cmd -a always,exit -F arch=b32 -S execve -F exe=/usr/bin/su -F auid>=1000 -F auid!=unset -k su_cmd -a always,exit -F arch=b64 -S execve -F exe=/usr/bin/su -F auid>=1000 -F auid!=unset -k su_cmd -w /etc/sudoers -p wa -k sudoers_changes -w /etc/sudoers.d/ -p wa -k sudoers_changes
Фильтр auid>=1000 отсекает системные процессы, auid!=unset убирает события без привязанной сессии, где auid равен 4294967295. Архитектуру указывайте обе, b32 и b64, иначе на x86_64 часть вызовов останется вне аудита. Добавьте правила на /usr/bin/pkexec и /usr/bin/newgrp, если эти файлы есть в системе.
Разбор выглядит так:
ausearch -k sudo_cmd -ts today -i | grep -A2 'type=EXECVE' aureport -k --summary | grep -E 'sudo|su'
Правила для критичных файлов: passwd, shadow, group, crontab
-w /etc/passwd -p wa -k passwd_changes -w /etc/shadow -p wa -k shadow_changes -w /etc/group -p wa -k group_changes -w /etc/gshadow -p wa -k gshadow_changes -w /etc/crontab -p wa -k cron_changes -w /etc/cron.d/ -p wa -k cron_changes -w /etc/pam.d/ -p wa -k pam_changes -a always,exit -F arch=b64 -F path=/etc/shadow -F perm=r -F auid>=1000 -F auid!=unset -k shadow_read
Для файлов аутентификации хватает прав wa: запись и смена атрибутов. Чтение отслеживают точечно, только для /etc/shadow, где лежат хеши паролей, и попытка чтения из непривилегированной сессии редко бывает случайной. Демоны sshd и cron читают этот файл постоянно, поэтому фильтр auid>=1000 обязателен, иначе журнал утонет в служебных записях.
| Что отслеживаем | Правило | Ключ | Что попадёт в лог |
|---|---|---|---|
| Правка конфигурации SSH | -w /etc/ssh/sshd_config -p wa -k ssh_config | ssh_config | запись с uid, euid и auid того, кто менял файл |
| Чтение приватного ключа | -w /root/.ssh/ -p rwa -k ssh_keys | ssh_keys | событие с perm=r и путём к файлу ключа |
| Запуск команды через sudo | -a always,exit -F arch=b64 -S execve -F exe=/usr/bin/sudo -F auid>=1000 -F auid!=unset -k sudo_cmd | sudo_cmd | type=EXECVE с полным argv и рабочим каталогом |
| Изменение sudoers | -w /etc/sudoers -p wa -k sudoers_changes | sudoers_changes | запись с новым режимом доступа к файлу |
| Правка базы пользователей | -w /etc/passwd -p wa -k passwd_changes | passwd_changes | кто, когда и в какой сессии менял файл |
| Чтение хешей паролей | -a always,exit -F arch=b64 -F path=/etc/shadow -F perm=r -F auid>=1000 -F auid!=unset -k shadow_read | shadow_read | auid пользователя, обратившегося к /etc/shadow |
| Изменение заданий cron | -w /etc/cron.d/ -p wa -k cron_changes | cron_changes | правки файлов расписания |
| Смена настроек PAM | -w /etc/pam.d/ -p wa -k pam_changes | pam_changes | изменения в стеке аутентификации |
Поиск событий: ausearch и aureport на практике
ausearch: поиск по ключу, времени и пользователю
ausearch -k ssh_config -ts today -i ausearch -k sudo_cmd -ts recent -i ausearch -k passwd_changes -ts 09/01/2026 -te 09/11/2026 -i ausearch -ua ivanov -ts yesterday ausearch -m EXECVE -k sudo_cmd -i
Флаг -i расшифровывает числовые UID и GID в имена, без него вы увидите только цифры. Значение -ts recent покрывает последние 10 минут, что удобно сразу после проверки правила. Итоговая дата задаётся через -te. Фильтр -m ограничивает тип записи, например EXECVE для запущенных команд.
aureport: сводные отчёты для быстрой диагностики
aureport --summary aureport -au --summary aureport -x --summary aureport -k aureport --failed
Отчёт по ключам показывает, какие правила дают больше всего записей, и это первая команда при разборе шума. Отчёт по аутентификации отделяет успешные входы от неуспешных, отчёт по исполняемым файлам выводит топ запущенных программ.
| Задача | Команда | Что показывает |
|---|---|---|
| Общая картина по серверу | aureport --summary | счётчики событий по типам записей |
| Попытки входа в систему | aureport -au --summary | успешные и неуспешные аутентификации |
| Топ выполняемых программ | aureport -x --summary | самые частые исполняемые файлы |
| Нагрузка по ключам | aureport -k | число событий на каждый ключ поиска |
| Только отказы | aureport --failed | события с признаком неудачи |
| Обращения к файлам | aureport -f | файлы, к которым обращались правила аудита |
Когда серверов становится больше десятка, локальный журнал перестаёт помогать: события нужно свозить в одну точку и раскладывать по дашбордам. Как это устроить, разобрано в отдельном материале про настройку auditd и сбор логов в SIEM.
Ротация журналов auditd: настройка и защита от переполнения диска
Конфигурация хранится в /etc/audit/auditd.conf. Один журнал на сервере с активными правилами легко доходит до сотен мегабайт в сутки, и без ограничений он занимает весь раздел /var.
| Параметр | Значение для продакшена | Смысл |
|---|---|---|
| log_file | /var/log/audit/audit.log | основной файл журнала |
| max_log_file | 50 | размер файла в мегабайтах до ротации |
| num_logs | 10 | сколько файлов хранить, суммарно около 500 МБ |
| max_log_file_action | rotate | старые файлы удаляются после достижения предела num_logs |
| space_left | 200 | порог свободного места в мегабайтах для предупреждения |
| space_left_action | syslog | предупреждение уходит в системный журнал |
| admin_space_left | 100 | критический порог, места почти не осталось |
| admin_space_left_action | single | переход в однопользовательский режим вместо остановки |
| disk_full_action | halt | поведение при полностью заполненном диске |
| disk_error_action | syslog | реакция на ошибку записи в файл |
| flush | incremental | сброс буфера на диск порциями, sync надёжнее, но медленнее |
Отдельно про max_log_file_action. Значение rotate удаляет самые старые файлы и удерживает занятое место в предсказуемых рамках. Значение keep_logs ничего не удаляет: набор файлов растёт, пока есть место, и такой режим берут, когда нужна длительная локальная история. Значение suspend останавливает запись журнала, halt останавливает сервер. Ставьте halt только там, где остановка узла дешевле потери аудита.
Что делать, если диск всё равно переполняется
du -sh /var/log/audit/ ls -lh /var/log/audit/ aureport -k | sort -k2 -nr | head -20
Смотрите, какой ключ даёт максимум событий. Чаще всего в лидерах оказывается правило на неудачные openat с кодом EACCES или широкое правило на каталог с приложениями. Уменьшать max_log_file вслепую не стоит: сначала разберитесь с источником записей, а уже потом правьте ротацию.
Снижение шума: исключения и фильтрация правил auditd
Шум лечится тремя инструментами: фильтрами -F внутри правил, правилами -a never и пересмотром списка отслеживаемых путей. Начните с третьего пункта, он самый дешёвый.
Исключение системных вызовов и процессов
-a never,exit -F arch=b64 -F exe=/usr/local/bin/backup.sh -k noise_backup -a never,exit -F arch=b64 -F dir=/srv/app/cache/ -k noise_cache -a never,exit -F arch=b64 -F exe=/usr/lib/systemd/systemd-journald -a never,exit -F key=shadow_read
Правило с -a never гасит событие целиком, поэтому его ставят в файл с меньшим номером, чем включающие правила. Строка с -F key=shadow_read полностью отключает группу по ключу, это удобно, когда правило устарело, а файл с ним удалять не хочется. Исключение по коду возврата, например всех openat с exit=-EACCES, снимает целый класс записей, и применять его стоит, только если такие события не нужны ни одному вашему правилу.
Как измерить шум до и после исключений
# срез до правок aureport -k | sort -k2 -nr | head # срез после правок и загрузки набора augenrules --load systemctl restart auditd aureport -k | sort -k2 -nr | head ausearch -k noise_backup -ts recent
Сравнивайте объём событий по ключам до и после. Рабочий ориентир: снижение общего числа записей на 30-70% без потери событий из списка критичных ключей. Команда ausearch по исключённому ключу должна вернуть строку no matches, это подтверждает, что правило-исключение действительно работает.
Проверка результата и диагностика типичных ошибок
Чек-лист: 5 команд для проверки auditd
| Шаг | Команда | Ожидаемый результат |
|---|---|---|
| Состояние службы | systemctl is-active auditd | active |
| Состояние подсистемы | auditctl -s | enabled=1, lost=0, backlog меньше backlog_limit |
| Загруженные правила | auditctl -l | список строк из rules.d в том же порядке |
| Живое событие | sudo ls /root, затем ausearch -k sudo_cmd -ts recent -i | запись с вашим auid и полным argv команды |
| Сводка по журналу | aureport --summary | счётчики событий по типам без нулевых значений |
Типичные ошибки и их решения
| Симптом | Причина | Решение |
|---|---|---|
| Правила исчезли после перезагрузки | строки добавляли через auditctl, а не в каталог rules.d | перенести их в файл .rules и выполнить augenrules --load |
| Служба не стартует, в журнале ошибка сокета | systemd-journald тоже подключён к аудит-сокету | выставить Audit=no в /etc/systemd/journald.conf и перезапустить journald |
| audit.log не растёт | неверные владелец или права на каталоге /var/log/audit | chown root:root /var/log/audit, chmod 700, перезапуск auditd |
| В поле lost значения больше нуля | события не успевают уходить в userspace | увеличить backlog_limit через auditctl -b 8192 и параметр ядра audit_backlog_limit |
| augenrules --load не меняет набор правил | включено правило -e 2, конфигурация заморожена | перезагрузить сервер или снять -e 2 на время отладки |
| Правило не срабатывает, событий нет | опечатка в пути или указана только архитектура b64 | проверить путь командой ls и добавить строку для arch=b32 |
Автоматические проверки конфигурации экономят время на поиске расхождений между серверами. Связка Lynis и OpenSCAP вместе с ручными правилами описана в руководстве по харденингу и аудиту Linux-сервера.
Итог: минимальный набор правил для старта
Скопируйте набор в /etc/audit/rules.d/50-audit-baseline.rules, примените и проверьте живым событием.
-w /etc/ssh/sshd_config -p wa -k ssh_config -w /etc/ssh/sshd_config.d/ -p wa -k ssh_config -w /root/.ssh/ -p rwa -k ssh_keys -a always,exit -F arch=b64 -S execve -F exe=/usr/bin/sudo -F auid>=1000 -F auid!=unset -k sudo_cmd -a always,exit -F arch=b64 -S execve -F exe=/usr/bin/su -F auid>=1000 -F auid!=unset -k su_cmd -w /etc/sudoers -p wa -k sudoers_changes -w /etc/sudoers.d/ -p wa -k sudoers_changes -w /etc/passwd -p wa -k passwd_changes -w /etc/shadow -p wa -k shadow_changes -w /etc/group -p wa -k group_changes -w /etc/crontab -p wa -k cron_changes -w /etc/cron.d/ -p wa -k cron_changes -a always,exit -F arch=b64 -F path=/etc/shadow -F perm=r -F auid>=1000 -F auid!=unset -k shadow_read
augenrules --load systemctl restart auditd auditctl -l | wc -l ausearch -k ssh_config -ts today -i
Дальше держите под контролем три вещи: параметры ротации в auditd.conf, срез aureport -k раз в неделю и реакции на события с высоким auid там, где его быть не должно. Когда серверов больше одного, переходите к централизованному сбору событий, а порядок регулярных проверок зафиксируйте в регламенте аудита безопасности Linux-серверов, чтобы проверки оставались воспроизводимыми.