auditd на Linux в 2026: правила аудита, ausearch и интеграция с SIEM

Практическое руководство по настройке auditd на RHEL 9 и Ubuntu 24.04 в 2026: правила sudo, execve и /etc/passwd, поиск через ausearch и пересылка событий в Wazuh или Splunk через audisp-плагины.

auditd на Linux 2026: правила и SIEM

Обновлено: 3 августа 2026

auditd это демон подсистемы аудита ядра Linux, который перехватывает системные вызовы и события файловой системы через netlink и пишет структурированные записи в /var/log/audit/audit.log для форензики, соответствия требованиям (PCI DSS, HIPAA, DISA STIG) и обнаружения атак. В отличие от rsyslog и journald, auditd работает на уровне ядра, поэтому события не теряются, даже если процесс успел удалить свой след в пользовательском пространстве. В этом руководстве я разберу, как настроить auditd на RHEL 9 и Ubuntu 24.04 в 2026 году, какие правила стоит добавить сверх STIG и как переслать поток событий в Wazuh или Splunk без потери в 20 000 EPS.

  • Актуальные версии в 2026: audit 3.1.5 в RHEL 9.x и 3.1.2 в Ubuntu 24.04. Upstream перескочил с 3.1.5 сразу на 4.0 (никакой 3.2 не было) и добавил TLS в удалённом логировании в 4.2.
  • Начиная с audit 3.0 отдельного демона audispd больше нет: его функциональность встроена в auditd, а плагины лежат в /etc/audit/plugins.d/, а не в /etc/audisp/.
  • Правила делятся на watches (-w) для файлов и syscall rules (-a) для системных вызовов. Каждое правило обязательно должно иметь тег -k, иначе поиск в ausearch превращается в grep по трём миллионам строк.
  • STIG SCAP Benchmark для RHEL 9 (V1R1) содержит 416 правил, десятки касаются именно аудита. Большинство из них создают лавину событий в контейнеризованных средах и требуют фильтрации.
  • Пересылку в SIEM делают через плагины audisp-remote, audisp-syslog или audisp-af_unix для Wazuh. Прямой tail через rsyslog imfile ломается на ротации.
  • Флаг -e 2 замораживает конфигурацию до перезагрузки: правила нельзя ни добавить, ни удалить даже из-под root. Это требование STIG, но им легко себе выстрелить в ногу.

Что делает auditd и чем он отличается от syslog

Подсистема аудита Linux состоит из трёх частей: kauditd-потока в ядре, netlink-сокета AUDIT_NETLINK_GRP_READLOG и пользовательского демона auditd, который вытаскивает записи из сокета и пишет их на диск. Правила загружаются один раз через auditctl и живут в ядре. Процесс auditd можно вообще убить, а kauditd продолжит собирать события в кольцевой буфер до тех пор, пока не переполнится backlog_limit.

Это принципиально отличает его от rsyslog и systemd-journald. Rsyslog читает поток от приложений, доверяя им форматирование. Злоумышленник с root может подменить бинарник и «забыть» логировать. Journald завязан на структурированные поля от systemd-юнитов и тоже работает в userspace. А вот auditd перехватывает syscall до того, как ядро отдаёт управление обратно процессу. То есть даже rm -f /var/log/audit/audit.log оставит после себя событие PATH с полным контекстом (uid, auid, tty, exe, comm).

Честно говоря, на банковских проектах, где я это внедрял, auditd был единственным источником, который принимают форензик-аудиторы без вопросов. Причина в том, что записи содержат auid (audit UID), устанавливаемый PAM при логине и неизменяемый до конца сессии. Если пользователь сделал sudo -i и работает как root, обычный who покажет root, а auditd отдаст исходный логин.

Установка auditd на RHEL 9 и Ubuntu 24.04

На RHEL 9 пакет уже установлен по умолчанию, а вот плагины нет. На Ubuntu 24.04 всё ставится вручную. Проверьте версию перед началом: с audit 3.1 многое поменялось, и статьи 2019 года про audispd уже не применимы.

# RHEL 9 / Rocky 9 / AlmaLinux 9
sudo dnf install -y audit audit-libs audispd-plugins
sudo systemctl enable --now auditd
auditctl -v      # должно вывести: auditctl version 3.1.5

# Ubuntu 24.04 LTS
sudo apt update
sudo apt install -y auditd audispd-plugins
sudo systemctl enable --now auditd
auditctl -v      # auditctl version 3.1.2

Проверьте, что kauditd действительно поднят:

sudo auditctl -s
# enabled 1
# failure 1
# pid 1234
# rate_limit 0
# backlog_limit 8192
# lost 0
# backlog 0
# backlog_wait_time 60000

Если enabled равен 0, добавьте audit=1 в параметры загрузки ядра через grubby --update-kernel=ALL --args="audit=1 audit_backlog_limit=8192" и перезагрузитесь. Некоторые облачные образы (особенно AWS AL2023 и Azure RHEL) поставляются с audit=0 по умолчанию. Это единственный legit случай, когда демон запущен, а событий нет.

Синтаксис правил: watches, syscall и ключи

Есть два вида правил, и путать их — самая частая ошибка новичков:

  1. Watches (-w /path -p [rwxa] -k key) следят за путём файла или каталога. Реализованы поверх inotify, работают быстро, но не срабатывают, если файл открывается через жёсткую ссылку в другом месте.
  2. Syscall rules (-a action,list -S syscall -F field=value -k key) фильтруют вызовы ядра по 64 полям (uid, auid, arch, exe, cwd и т. д.). Дают полный контекст, но каждое дополнительное правило стоит CPU-циклов.

Ключевой параметр: всегда указывайте -k. Тег становится полем key= в записи и позволяет фильтровать через ausearch -k имя_ключа. Без него события смешиваются в общей ленте, и найти нужное можно только через ausearch --raw | grep, что на нагруженном сервере убьёт I/O.

Пример разницы:

# Watch: срабатывает при любом изменении /etc/shadow
-w /etc/shadow -p wa -k identity

# Syscall rule: то же самое, но только когда исполняется от non-root пользователя
-a always,exit -F arch=b64 -S openat -F path=/etc/shadow -F success=1 \
   -F auid>=1000 -F auid!=-1 -k shadow-access-by-user

Правила пишутся в файлы /etc/audit/rules.d/*.rules по одному правилу на строку. Утилита augenrules --load собирает их в единый /etc/audit/audit.rules в алфавитном порядке имён файлов. Поэтому назовите свои файлы с префиксом (например, 10-base.rules, 50-stig.rules, 99-immutable.rules). Порядок критичен, потому что первое совпавшее правило выигрывает.

Практический ruleset: sudo, /etc/passwd, execve и STIG

Ниже приведён базовый набор, который я использую на всех hardened-серверах. Он покрывает 80% того, что реально нужно для аудита: изменения пользователей, sudo, монтирование, загрузку модулей ядра и выполнение команд под root. Полный STIG-ruleset для RHEL 9 можно взять из DISA STIG SCAP Benchmark, но перед деплоем в контейнерную среду его нужно фильтровать. Иначе получите десятки тысяч событий в минуту от cAdvisor и containerd.

# /etc/audit/rules.d/50-base.rules

# ---- Изменения identity ----
-w /etc/passwd -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/sudoers -p wa -k identity
-w /etc/sudoers.d/ -p wa -k identity

# ---- Использование sudo и su ----
-a always,exit -F path=/usr/bin/sudo -F perm=x -F auid>=1000 -F auid!=-1 -k priv-esc
-a always,exit -F path=/usr/bin/su   -F perm=x -F auid>=1000 -F auid!=-1 -k priv-esc

# ---- Изменения системного времени ----
-a always,exit -F arch=b64 -S adjtimex,settimeofday,clock_settime -k time-change
-w /etc/localtime -p wa -k time-change

# ---- Загрузка модулей ядра ----
-a always,exit -F arch=b64 -S init_module,finit_module,delete_module -k modules
-w /usr/sbin/insmod  -p x -k modules
-w /usr/sbin/rmmod   -p x -k modules
-w /usr/sbin/modprobe -p x -k modules

# ---- Монтирование ----
-a always,exit -F arch=b64 -S mount,umount2 -F auid>=1000 -F auid!=-1 -k mounts

# ---- Выполнение команд от имени root после sudo ----
-a always,exit -F arch=b64 -S execve -F euid=0 -F auid>=1000 -F auid!=-1 -k rootcmd

# ---- Провал доступа (EACCES/EPERM) ----
-a always,exit -F arch=b64 -S openat -F exit=-EACCES -F auid>=1000 -F auid!=-1 -k access-denied
-a always,exit -F arch=b64 -S openat -F exit=-EPERM  -F auid>=1000 -F auid!=-1 -k access-denied

Загрузите набор:

sudo augenrules --load
sudo auditctl -l   # проверка, что все правила приняты

Поиск событий: ausearch, aureport и autrace

Три утилиты, без которых логи бесполезны:

  • ausearch: фильтр по ключам, времени, UID, PID. Основной инструмент для расследований.
  • aureport: агрегатор с топом файлов, топом пользователей и сводкой авторизаций.
  • autrace: эквивалент strace, но пишущий в audit.log. Полезен для расследования, но нельзя запускать на процессах, которые уже отслеживаются syscall-правилами (получите бесконечный цикл).

Несколько сценариев из моей практики:

# Все события изменения identity за последние 24 часа
sudo ausearch -k identity --start today --end now -i

# Кто пытался читать /etc/shadow, но получил EACCES?
sudo ausearch -k access-denied --file /etc/shadow -i

# Все sudo-команды пользователя ivan за август
sudo ausearch -k priv-esc --start 2026-08-01 --end 2026-08-31 -ua ivan -i

# Все загрузки модулей ядра, красиво отформатированные
sudo aureport --mods --summary -i

# Топ-10 файлов с провалами доступа
sudo aureport -f --failed --summary -i | head -20

Флаг -i раскрывает UID в имена (из /etc/passwd) и syscall-номера в имена, без него вы читаете сырые числа. Флаг -ua ищет по audit UID, а не по effective UID, поэтому находит действия пользователя даже после sudo -i.

Для длительных расследований я обычно выгружаю нужный срез в отдельный файл и уже там ковыряюсь через jq:

sudo ausearch -k rootcmd --start yesterday --format json > /tmp/rootcmd.json
jq '.[] | {time, auid: .auid, exe: .PATH[0].name, cmdline: .PROCTITLE.proctitle}' /tmp/rootcmd.json

Как переслать логи auditd в Wazuh или Splunk

Прямой tail /var/log/audit/audit.log через rsyslog imfile? Самый популярный совет из статей десятилетней давности, и он всё ещё регулярно ломается: после ротации через logrotate rsyslog иногда теряет inode и молчит до следующего рестарта. Правильный способ: использовать audisp-плагины, которые работают внутри процесса auditd и получают события напрямую из очереди, до записи на диск.

Начиная с audit 3.0 плагины лежат в /etc/audit/plugins.d/ (а не в /etc/audisp/plugins.d/, как в старых мануалах). Актуальный набор в 2026 году:

  • audisp-af_unix: сокет для Wazuh-агента (заменил встроенный af_unix в 3.1).
  • audisp-syslog: форвардит в локальный syslog (для дальнейшей пересылки rsyslog'ом).
  • audisp-remote: TCP/TLS-пересылка на удалённый auditd (TLS появился в 4.2 upstream).
  • audisp-filter: предфильтр событий до отправки в плагины (новинка 3.1).
  • audisp-statsd: метрики в StatsD/Prometheus.

Пример конфигурации для интеграции с Wazuh SIEM через агента:

# /etc/audit/plugins.d/af_unix.conf
active = yes
direction = out
path = /sbin/audisp-af_unix
type = always
args = 0640 /var/ossec/queue/ossec/audit
format = string

Wazuh-агент читает этот сокет и переправляет события в manager, где они обогащаются MITRE ATT&CK-тегами. Для Splunk путь другой: включаете audisp-syslog, направляете facility local6 в отдельный файл через rsyslog, и Splunk Universal Forwarder монитирит уже этот файл. Так вы не теряете структурированность и не перегружаете journald.

# /etc/audit/plugins.d/syslog.conf
active = yes
direction = out
path = /sbin/audisp-syslog
type = always
args = LOG_LOCAL6 LOG_INFO
format = string

# /etc/rsyslog.d/30-audit.conf
local6.* /var/log/audit-forward.log
& stop

После правки любого плагина перезапускайте auditd правильным способом: sudo service auditd restart (не systemctl).

Тюнинг производительности и ротация логов

На нагруженном сервере (500+ EPS) стандартные параметры создают три проблемы: переполнение буфера ядра, замедление процессов (auditd блокирует syscall до приёма события) и заполнение /var/log/audit за несколько часов. Основной конфиг живёт в /etc/audit/auditd.conf:

# /etc/audit/auditd.conf — ключевые параметры

max_log_file = 100                  # МБ на один файл
num_logs = 20                        # хранить 20 ротаций (~2 ГБ суммарно)
max_log_file_action = ROTATE         # что делать при достижении лимита
space_left = 500                     # МБ свободного места (trigger warning)
space_left_action = SYSLOG           # варианты: EMAIL, EXEC, SUSPEND, SINGLE, HALT
admin_space_left = 100
admin_space_left_action = SUSPEND    # STIG требует SINGLE или HALT
disk_full_action = SUSPEND
disk_error_action = SUSPEND
flush = INCREMENTAL_ASYNC            # NONE / DATA / SYNC / INCREMENTAL_ASYNC
freq = 50                            # flush каждые 50 записей

# --- параметры ядра (auditctl) ---
# в /etc/audit/rules.d/00-init.rules
-D                                   # очистить существующие правила
-b 16384                             # backlog_limit (размер очереди в ядре)
--backlog_wait_time 30000            # ms ожидания перед drop при переполнении
-f 1                                 # failure mode: 0=silent, 1=printk, 2=panic
--loginuid-immutable                 # запрет смены auid после установки

Мониторьте состояние демона: auditctl -s показывает lost (события, потерянные из-за переполнения) и backlog (текущая длина очереди). Если lost растёт, увеличивайте -b или сокращайте набор правил. Также посмотрите параметры sysctl для hardened-ядра: некоторые из них (например, kernel.dmesg_restrict) взаимодействуют с audit-подсистемой.

Как сделать конфигурацию auditd неизменяемой

Флаг -e 2 замораживает конфигурацию до перезагрузки: ни одно правило нельзя ни добавить, ни удалить, даже из-под root. Это требование STIG (SV-258126r958732_rule) и просто хорошая практика: если атакующий получил root, он не сможет спрятать свои следы через auditctl -D. Добавляется всегда последней строкой в правилах:

# /etc/audit/rules.d/99-finalize.rules
-e 2

Значения флага -e:

  • -e 0: аудит выключен, но правила и очередь работают.
  • -e 1: аудит включён (по умолчанию).
  • -e 2: locked, правила заморожены до перезагрузки.

После установки -e 2 изменения правил применяются только через перезагрузку. Это неудобно, но правильно: если вам часто нужно править ruleset «на живую», значит, у вас нет CI/CD-процесса управления конфигурацией. Заведите официальный audit-userspace в pipeline и деплойте через Ansible-роль с notify: reboot, а не через auditctl вручную. Я сам однажды забыл про -e 2 на препрод-сервере и час дебажил, почему augenrules --load не подхватывает новые правила. Все ответы были в dmesg, но кто туда смотрит первым, честно.

Полный список подсистем аудита, включая новые фичи 4.x, задокументирован в Red Hat Security Hardening guide для RHEL 9. Если ваша инфраструктура ещё не мигрировала на audit 4.x, планируйте: TLS-remote-logging из 4.2 закрывает целый класс уязвимостей MITM при пересылке событий через WAN.

Часто задаваемые вопросы

В чём разница между auditd и rsyslog?

Rsyslog собирает сообщения от приложений в пользовательском пространстве и доверяет им форматирование. auditd перехватывает системные вызовы на уровне ядра через netlink, поэтому события фиксируются независимо от того, что делает приложение или атакующий с root-правами. rsyslog удобен для application logs, а auditd остаётся единственно приемлемым источником для форензики и compliance.

Как аудировать выполнение команд конкретным пользователем?

Используйте syscall-правило на execve с фильтром по auid: -a always,exit -F arch=b64 -S execve -F auid=1001 -k user-1001-cmd. Затем ищите через ausearch -k user-1001-cmd -i. auid ставится PAM при логине и неизменяем, поэтому sudo не сбросит его.

Почему auditd заполняет /var/log/audit и как его ротировать?

Стандартные лимиты в /etc/audit/auditd.conf (max_log_file=8, num_logs=5) рассчитаны на десктоп. На сервере поднимите max_log_file до 100 МБ и num_logs до 20, установите max_log_file_action=ROTATE. Не подключайте logrotate, auditd ротирует сам через встроенный механизм.

Можно ли отключить auditd без перезагрузки?

Если не установлен флаг -e 2, то да: sudo auditctl -e 0 остановит запись событий, но kauditd в ядре продолжит работать. Полное отключение с выгрузкой правил делается через auditctl -D && auditctl -e 0. Если конфигурация заморожена (-e 2), только перезагрузка снимет блокировку.

Обязательно ли использовать STIG-ruleset целиком?

Нет, и в контейнеризованных средах категорически не рекомендуется. STIG SCAP Benchmark для RHEL 9 (V1R1, 416 правил) писался под bare-metal и создаёт лавину событий от containerd, kubelet и CNI-плагинов. Используйте STIG как базу, но фильтруйте правила по exe!= для системных бинарников, которые генерируют шум.

Об авторе Mateusz Wojciechowski

Mateusz spent eight years on the Red Hat consulting bench before going independent in 2024, embedded with banks and telcos rolling out RHEL 8 and 9 across regulated estates. Most of that work was SELinux policy debugging, FIPS-mode enablement, and cleaning up the kind of sudoers files that grow organically over a decade. He holds OSCP and RHCE, and maintains a small set of Ansible roles for STIG-hardened RHEL builds that a few European credit unions now run in production. Before Red Hat he was a junior sysadmin at Allegro in Poznan, mostly babysitting Postfix and learning why you don't run updatedb on an NFS root. Mateusz writes about the boring half of Linux security: package signing, audit daemon tuning, and the unglamorous work of actually reading journalctl output before paging anyone.