Новинка Виртуальный VDS сервер в Нидерландах от 390р
Выберите продукт

Auditd в Linux VDS: аудит изменений /etc, Nginx, PHP-FPM и /var/www

Auditd помогает понять, кто изменил конфиг, когда переписали pool PHP-FPM и откуда появился файл в /var/www. Разберём установку, постоянные правила, фильтрацию шума и быстрый разбор событий на VDS.
Auditd в Linux VDS: аудит изменений /etc, Nginx, PHP-FPM и /var/www

Когда на VDS крутится обычный веб-стек Nginx + PHP-FPM, большая часть расследований начинается с простых вопросов: кто поменял конфиг, почему внезапно изменились права на каталог сайта, откуда в /var/www появился незнакомый PHP-файл, какой пользователь правил pool PHP-FPM перед падением сайта. По логам Nginx и PHP-FPM такие вещи часто не видно: веб-сервер пишет запросы и ошибки приложения, но не фиксирует операции с файлами на уровне ядра.

Для этого в Linux есть auditd — демон подсистемы Linux Audit. Он получает события от ядра, пишет их в /var/log/audit/audit.log, а администратор затем разбирает их через auditctl, ausearch и aureport. В этой статье настроим auditd linux-подходом для VDS: без попытки логировать всё подряд, но с полезными правилами для /etc, Nginx, PHP-FPM и веб-корня /var/www.

Auditd не заменяет резервные копии, контроль целостности, CI/CD и нормальные права доступа. Его задача — дать доказуемый след: что изменилось, когда, каким пользователем и через какой процесс.

Что именно стоит аудировать на веб-сервере

Главная ошибка при первом знакомстве с auditd — включить аудит на слишком широкие каталоги и получить гигабайты шума. На VDS это особенно неприятно: диск ограничен, лишняя запись в лог конкурирует с сайтом и базой, а полезные события тонут среди временных файлов, кешей и загрузок.

Для типичного сервера с Nginx и PHP-FPM практично разделить аудит на несколько зон.

  • /etc/nginx — конфигурация Nginx, виртуальные хосты, include-файлы, параметры проксирования и FastCGI.
  • /etc/php на Debian/Ubuntu или /etc/php-fpm.d и /etc/php.ini на RHEL-based системах — настройки PHP-FPM, pool-файлы, лимиты, пользователь процесса.
  • Критичные части /etc — sudo, sshd, systemd unit-файлы, cron. В этой статье фокус на веб-стеке, но общий принцип тот же.
  • /var/www или конкретный каталог сайта — код приложения, публичные файлы, релизы. Здесь правила нужно подбирать особенно аккуратно.

Для конфигурации обычно достаточно отслеживать запись и изменение атрибутов: права w и a. Для веб-корня всё зависит от способа деплоя. Если релизы выкладываются через rsync, Git, CI/CD или symlink-переключение, аудит всего /var/www может быть слишком шумным. В таком случае лучше аудировать только production-каталог, файл входа приложения, подозрительные исполняемые операции или изменения вне окна деплоя.

Установка auditd

Пакеты называются немного по-разному, но сервис почти везде один — auditd. Ниже команды для популярных семейств ОС. Выполняйте их от root или через sudo.

Debian и Ubuntu

sudo apt update
sudo apt install auditd audispd-plugins
sudo systemctl enable --now auditd

AlmaLinux, Rocky Linux, CentOS Stream, Oracle Linux и Fedora

sudo dnf install audit
sudo systemctl enable --now auditd

Проверьте статус демона и состояние подсистемы аудита:

sudo systemctl status auditd
sudo auditctl -s

В выводе auditctl -s важны поля enabled, backlog, lost и backlog_wait_time. Если lost растёт, ядро теряет события: правил слишком много, диск медленный, логирование не успевает или backlog маловат. Для начала на VDS обычно лучше уменьшить шум правил, а не сразу увеличивать буферы.

Схема правил auditd для аудита файлов веб-сервера

Где хранятся правила auditd и как их загружать

Временные правила можно добавить через auditctl, но после перезагрузки они исчезнут. Для постоянной настройки используются файлы в /etc/audit/rules.d/. Затем правила собираются и загружаются командой augenrules.

sudo auditctl -l
sudo augenrules --check
sudo augenrules --load
sudo auditctl -l

Команда auditctl -l показывает активные правила. Команда augenrules --check полезна перед загрузкой: она проверяет, изменился ли итоговый набор. Если вы редактируете правила на удалённой VDS по SSH, не включайте сразу жёсткий immutable-режим -e 2. В этом режиме правила нельзя изменить до перезагрузки, и ошибка может превратить отладку в неприятный квест.

Рабочий порядок такой: сначала загрузить правила, проверить шум и поиск событий, затем добавить их в эксплуатационный набор. Immutable-режим включают только после тестов и при понятном плане отката.

FastFox VDS
Облачный VDS-сервер
Виртуальные серверы с быстрым запуском и гибкой конфигурацией от 390₽ / мес
Доступные локации
Россия Нидерланды

Базовые правила для Nginx, PHP-FPM и /var/www

Создадим отдельный файл правил. Не начинайте его с -D, если не управляете всем набором auditd централизованно: -D очищает предыдущие правила и может случайно отключить аудит, добавленный другими пакетами или вашей системой безопасности.

Debian и Ubuntu

На Debian/Ubuntu конфигурация Nginx обычно лежит в /etc/nginx, а PHP-FPM — в /etc/php, например /etc/php/8.3/fpm/pool.d/. Пользователь веб-процесса часто www-data с uid 33, но лучше проверить.

id -u www-data
sudo install -m 0640 -o root -g root /dev/null /etc/audit/rules.d/50-web-audit.rules

Пример содержимого /etc/audit/rules.d/50-web-audit.rules:

# Nginx configuration
-w /etc/nginx -p wa -k nginx_config

# PHP-FPM configuration on Debian and Ubuntu
-w /etc/php -p wa -k phpfpm_config

# Web root. Narrow this path if deployments are noisy.
-w /var/www -p wa -k webroot_changes

# Execution attempts from web root by PHP-FPM user. Replace 33 if needed.
-a always,exit -F arch=b64 -S execve -F dir=/var/www -F euid=33 -k web_exec_from_webroot

RHEL-based дистрибутивы и Fedora

В AlmaLinux, Rocky Linux, CentOS Stream, Oracle Linux и Fedora Nginx также часто использует /etc/nginx, а PHP-FPM — /etc/php-fpm.d и общий файл /etc/php.ini. Пользователь пула может быть apache, nginx или отдельный пользователь сайта.

id -u nginx
id -u apache
sudo install -m 0640 -o root -g root /dev/null /etc/audit/rules.d/50-web-audit.rules

Пример правил:

# Nginx configuration
-w /etc/nginx -p wa -k nginx_config

# PHP-FPM configuration on RHEL-based systems
-w /etc/php-fpm.d -p wa -k phpfpm_config
-w /etc/php.ini -p wa -k phpfpm_config

# Web root. Narrow this path if deployments are noisy.
-w /var/www -p wa -k webroot_changes

# Execution attempts from web root by PHP-FPM user. Replace 33 with real uid.
-a always,exit -F arch=b64 -S execve -F dir=/var/www -F euid=33 -k web_exec_from_webroot

После записи файла загрузите правила:

sudo augenrules --load
sudo auditctl -l

Если команда ругается на uid, замените число в правиле web_exec_from_webroot на реальный uid пользователя PHP-FPM. Узнать его можно не только через id, но и по процессам:

ps -eo user,pid,comm,args | grep php-fpm
ps -eo user,pid,comm,args | grep nginx

На большинстве современных VDS используется 64-битная система, поэтому в примерах указан arch=b64. Если на сервере действительно запускаются 32-битные бинарники, добавьте отдельное аналогичное правило с arch=b32, но не делайте это «на всякий случай» без проверки — лишние syscall-правила увеличивают шум.

Почему правило на запуск из /var/www полезно

Обычное изменение файла в /var/www ещё не всегда инцидент. CMS, деплой, загрузка медиафайлов и сборка фронтенда могут создавать и менять файлы постоянно. Но попытка выполнить бинарник или скрипт из веб-корня пользователем PHP-FPM — уже сильный сигнал. В нормальной архитектуре PHP-FPM интерпретирует PHP-код, но не должен запускать неизвестные исполняемые файлы из upload-каталогов.

Правило с -S execve ловит системный вызов запуска процесса. Фильтр -F dir=/var/www ограничивает область, а -F euid=33 привязывает событие к эффективному пользователю PHP-FPM. Если у каждого сайта отдельный pool и отдельный пользователь, сделайте несколько правил с разными uid и ключами, например web_exec_site1 и web_exec_site2.

Если на сервере есть легитимные консольные команды приложения, например очереди или artisan/console-команды, запускаемые из каталога релиза, не включайте грубую блокировку на основании одного события. Auditd в этой схеме не блокирует, а показывает факт. Решение принимает администратор или система реагирования.

Проверяем, что события пишутся

Сначала сделайте контролируемое изменение. Например, создайте временный файл в конфигурационном каталоге Nginx и удалите его. Не меняйте боевые конфиги без необходимости.

sudo touch /etc/nginx/auditd-test.conf
sudo rm /etc/nginx/auditd-test.conf

Теперь найдите события по ключу:

sudo ausearch -k nginx_config -i

Ключ -k — одно из самых удобных средств навигации в auditd. Поэтому правила лучше сразу снабжать понятными ключами: nginx_config, phpfpm_config, webroot_changes, web_exec_from_webroot. Через пару месяцев после настройки вы скажете себе спасибо.

Чтобы ограничить поиск недавними событиями, используйте -ts:

sudo ausearch -k nginx_config -ts recent -i
sudo ausearch -k phpfpm_config -ts today -i
sudo ausearch -k webroot_changes -ts yesterday -i

Для конкретного файла полезен фильтр -f:

sudo ausearch -f /etc/nginx/nginx.conf -i
sudo ausearch -f /var/www/example.com/index.php -i

Как читать событие ausearch

Вывод auditd сначала кажется перегруженным. В одном действии может быть несколько записей: SYSCALL, CWD, PATH, иногда PROCTITLE. Это нормально: auditd собирает контекст из разных частей события.

В первую очередь смотрите на поля:

  • type — тип записи, например SYSCALL или PATH.
  • msg=audit(...) — timestamp и идентификатор события. По нему видно, какие строки относятся к одному действию.
  • auid — audit user id, то есть исходный пользователь сессии. Часто это важнее, чем текущий uid после sudo.
  • uid, euid, gid — реальные и эффективные идентификаторы процесса.
  • comm — короткое имя команды.
  • exe — путь к исполняемому файлу процесса.
  • name — файл или каталог, которого коснулось событие.
  • key — ваш ключ правила.

Например, если auid указывает на администратора, exe — на /usr/bin/vim, а name — на /etc/nginx/sites-enabled/example.conf, это похоже на ручное редактирование конфига. Если auid отсутствует или равен системному значению, exe показывает /usr/bin/rsync, а событие попало в окно деплоя, это может быть нормальный релиз. Если же exe — неожиданный процесс, а файл появился в upload-каталоге, нужно разбираться глубже.

Отчёт в терминале с событиями Linux Audit для каталога сайта

Отчёты aureport: быстрый обзор без чтения audit.log вручную

ausearch удобен для расследования конкретного события, а aureport — для сводки. Он помогает быстро понять, какие ключи срабатывали чаще всего и какие файлы менялись.

sudo aureport -k -i
sudo aureport -f -i
sudo aureport -x -i

Ключ -k показывает отчёт по audit keys, -f — по файлам, -x — по исполняемым файлам. Для периода добавляйте --start и --end:

sudo aureport -k -i --start today
sudo aureport -f -i --start yesterday --end today

На практике удобно держать короткий набор команд для утренней проверки после ночных деплоев или подозрительных алертов. Например: сначала отчёт по ключам, затем поиск по самому активному ключу через ausearch, затем проверка конкретного файла через -f.

Настройка ротации и лимитов audit.log

Auditd пишет отдельный лог, обычно /var/log/audit/audit.log. Его ротация управляется не обычным logrotate-файлом Nginx, а параметрами /etc/audit/auditd.conf. На небольшой VDS важно проверить лимиты до включения правил на /var/www.

sudo grep -E 'max_log_file|num_logs|space_left|admin_space_left|disk_full_action' /etc/audit/auditd.conf

Полезные параметры:

  • max_log_file — размер одного audit.log в мегабайтах.
  • num_logs — сколько старых файлов хранить.
  • max_log_file_action — что делать при достижении лимита, часто используется ROTATE.
  • space_left и admin_space_left — пороги свободного места.
  • disk_full_action — действие при заполнении диска.

Не ставьте бесконечную ретенцию на маленьком диске. Лучше хранить разумный локальный период и вывозить логи централизованно, если у вас есть отдельная система логирования. При этом учитывайте, что audit-логи могут содержать имена файлов, аргументы команд и другие чувствительные технические данные. Доступ к ним должен быть ограничен.

После изменения auditd.conf примените настройки. На части систем auditd защищён от обычного restart, поэтому безопаснее использовать штатный reload или service-команду, если она доступна.

sudo systemctl reload auditd
sudo service auditd reload

Если reload не поддерживается, запланируйте перезапуск в окно обслуживания. Не делайте рискованные операции с auditd одновременно с изменением firewall или SSH-доступа.

Как уменьшить шум от /var/www

Каталог /var/www редко бывает однородным. В нём могут лежать код, кеш, пользовательские загрузки, временные файлы, symlink на текущий релиз и несколько старых релизов. Одно правило на весь каталог удобно для старта, но не всегда подходит для постоянной эксплуатации.

Несколько практичных подходов:

  • Аудировать не весь /var/www, а конкретный production-путь: /var/www/example.com/current или /var/www/example.com/public.
  • Не включать аудит на каталоги кеша, если приложение постоянно пишет туда файлы.
  • Отдельно отслеживать конфигурацию и код, а пользовательские загрузки проверять другим инструментом: антивирусным сканированием, WAF-логами, контрольными задачами.
  • Использовать разные ключи для разных сайтов, если на VDS несколько проектов.
  • Согласовать правила с деплоем: события во время релиза нормальны, события ночью вне релиза — повод проверить.

Если у вас atomic deploy через symlink, auditd может вести себя не так, как ожидается, потому что watch ставится на конкретный путь и его разрешение в файловой системе. Для важных правил проверяйте реальный путь:

readlink -f /var/www/example.com/current

Иногда лучше аудировать каталог релизов или публичный каталог внутри текущего релиза, а не сам symlink. После изменения схемы деплоя обязательно повторите тест: создать файл, изменить права, удалить файл и убедиться, что ausearch видит событие.

Расширенные правила для критичных частей /etc

Если базовый аудит Nginx и PHP-FPM работает стабильно, можно добавить точечные правила для системных файлов, которые часто влияют на безопасность веб-сервера. Не обязательно аудировать весь /etc. Часто достаточно нескольких директорий и файлов.

# SSH and sudo
-w /etc/ssh/sshd_config -p wa -k sshd_config
-w /etc/sudoers -p wa -k sudoers_changes
-w /etc/sudoers.d -p wa -k sudoers_changes

# Systemd units and timers
-w /etc/systemd/system -p wa -k systemd_units

# Cron jobs
-w /etc/crontab -p wa -k cron_changes
-w /etc/cron.d -p wa -k cron_changes
-w /etc/cron.daily -p wa -k cron_changes

Почему это важно для веб-стека? Инцидент не всегда начинается с изменения nginx.conf. Иногда добавляют systemd unit для закрепления, меняют cron, правят sudoers или ослабляют sshd-настройки. Auditd помогает увидеть эти изменения рядом с событиями в /var/www. Для отдельного контроля интерактивных входов пригодится инструкция про уведомления о SSH-входах через PAM и journald.

Типовой сценарий расследования

Представим ситуацию: мониторинг сообщил о подозрительном PHP-файле в /var/www/example.com/public/uploads. Сначала ищем события по файлу:

sudo ausearch -f /var/www/example.com/public/uploads/cache.php -i

Если файл уже удалён или имя неизвестно, смотрим ключ по веб-корню за период:

sudo ausearch -k webroot_changes -ts today -i

Затем проверяем, были ли попытки запуска из веб-корня:

sudo ausearch -k web_exec_from_webroot -ts today -i

После этого полезно посмотреть сводку по исполняемым файлам:

sudo aureport -x -i --start today

Если рядом по времени были изменения конфигов, проверяем Nginx и PHP-FPM:

sudo ausearch -k nginx_config -ts today -i
sudo ausearch -k phpfpm_config -ts today -i

Такой порядок экономит время. Вы не читаете весь audit.log, а идёте от конкретного артефакта к процессу, пользователю и соседним изменениям. Дальше уже подключаются бэкапы, Git-история, логи веб-сервера, access/error logs, журналы деплоя и проверка прав. Если расследование связано с переносом сайта, полезно свериться с чек-листом миграции сайта без простоя: он помогает отделить штатные изменения от неожиданных.

Частые проблемы и быстрые проверки

Правила не срабатывают

Проверьте, загружены ли они вообще:

sudo auditctl -l
sudo auditctl -s

Убедитесь, что путь существует и вы тестируете именно его. Для symlink-путей проверьте readlink -f. Также проверьте, что действие подходит под права правила: -p wa ловит запись и атрибуты, но не чтение.

Слишком много событий

Сузьте путь. Вместо /var/www используйте каталог конкретного сайта. Уберите кеши и временные каталоги из области аудита архитектурно: перенесите их за пределы отслеживаемого дерева или аудируйте только более важный подкаталог. Проверьте отчёт:

sudo aureport -k -i --start today
sudo aureport -f -i --start today

audit.log быстро растёт

Проверьте auditd.conf, активные ключи и самые шумные файлы. Если правило на /var/www фиксирует каждую запись кеша, это проблема правила, а не ротации. Ротация нужна, но она не должна маскировать ошибочную настройку.

В событии непонятный пользователь

Смотрите не только uid, но и auid. После sudo текущий uid может быть root, а auid сохранит исходного пользователя сессии. Для системных процессов auid может быть unset, тогда важнее exe, comm, unit в journald и соседние события.

Минимальный чек-лист внедрения на VDS

  • Установить auditd и проверить auditctl -s.
  • Добавить отдельный файл /etc/audit/rules.d/50-web-audit.rules.
  • Начать с Nginx и PHP-FPM, затем осторожно добавить /var/www.
  • Заменить uid в execve-правиле на пользователя вашего PHP-FPM pool.
  • Загрузить правила через augenrules --load.
  • Проверить тестовыми изменениями и поиском через ausearch.
  • Посмотреть шум через aureport -k -i и aureport -f -i.
  • Настроить лимиты auditd.conf и контролировать свободное место.
  • Документировать ключи правил, чтобы дежурный администратор понимал, что искать.

Итоги

Auditd на Linux VDS особенно полезен там, где веб-сервер обслуживает важный проект, а изменения должны быть объяснимы. Для Nginx и PHP-FPM достаточно начать с аудита конфигурационных каталогов и аккуратного контроля /var/www. Команда auditctl помогает проверить активные правила, ausearch — найти конкретные события, а aureport — быстро увидеть общую картину.

Самое важное — не превращать auditd в сборщик всего подряд. Хороший аудит отвечает на конкретные вопросы: кто изменил /etc/nginx, когда поменяли pool PHP-FPM, какой процесс создал файл в /var/www, были ли запуски из веб-корня. Такой набор правил даёт практичную пользу, не перегружает VDS и помогает быстрее разбирать инциденты и неожиданные изменения.

Поделиться статьей

Вам будет интересно

Nginx proxy_cache и backend: как не сломать кэш из-за Cookie и Set-Cookie OpenAI Статья написана AI (GPT 5)

Nginx proxy_cache и backend: как не сломать кэш из-за Cookie и Set-Cookie

Cookie и Set-Cookie часто ломают кэширование или, хуже, создают риск отдать персональную страницу из кэша. Покажем практичную схем ...
PostgreSQL pg_hba.conf на VDS: почему trust 0.0.0.0/0 опасен и как открыть доступ правильно OpenAI Статья написана AI (GPT 5)

PostgreSQL pg_hba.conf на VDS: почему trust 0.0.0.0/0 опасен и как открыть доступ правильно

PostgreSQL не подключается извне, и хочется поставить trust для всех адресов? Разбираем безопасный путь: listen_addresses, точные ...
PostgreSQL на VDS: pg_hba.conf, SCRAM и TLS для безопасного доступа OpenAI Статья написана AI (GPT 5)

PostgreSQL на VDS: pg_hba.conf, SCRAM и TLS для безопасного доступа

PostgreSQL удобно держать на VDS, но открывать порт 5432 «как есть» нельзя. Разберём, как включить сетевые подключения, описать пр ...