Аудит безопасности Nginx начинается с двух вопросов: какую роль сервер играет в инфраструктуре и какие риски должна закрыть проверка. Ответы превращают цель аудита в измеримый результат, например: «к 1 декабря 2026 года все публичные TLS-сертификаты обновляются автоматически не позднее чем за 30 дней до истечения» или «server_tokens выключен на всех виртуальных хостах».
Дальше цели выстраиваются в четыре блока по убыванию приоритета: конфигурация TLS и управление сертификатами, директивы безопасности, версия и подключённые модули, анализ логов на подозрительную активность. Для reverse proxy порядок сдвигается: первыми проверяют корректность проксирования заголовков, потому что ошибка в них открывает обход аутентификации на backend.
Сплошной перебор директив без приоритетов занимает дни и даёт список из сотни пунктов, где критичное теряется среди косметического. Сначала цели, потом команды. Комплексный аудит безопасности ИТ-инфраструктуры: практический план для DevOps и администраторов помогает связать цели одного сервера с картиной по всему парку машин, Docker и Kubernetes.
Почему аудит Nginx нужно начинать с целей, а не с команд
Цель аудита описывает проверяемый результат и срок, к которому он достигается: «исключить утечку версии Nginx в заголовке Server», «снизить долю необработанных ошибок 5xx на 50% за месяц», «сократить число сертификатов с остатком менее 30 дней до нуля». Формулировка сразу отсекает проверки, которые не влияют на результат, и оставляет 5-7 пунктов вместо сотни.
Приоритеты зависят от роли сервера и модели угроз. Узел, который только отдаёт статические файлы, проверяют иначе, чем балансировщик под высоким трафиком. Если Nginx раздаёт статику через try_files, цель «проверить валидацию X-Forwarded-For» бессмысленна: цепочки проксирования нет. Обратная ситуация с балансировщиком: без настройки max_fails и fail_timeout вы получите случайные 502 при отказе одного upstream, и никакая проверка шифров этот риск не снимет.
Аудит встраивается в цикл управления уязвимостями: инвентаризация, приоритизация, исправление, повторная проверка. Разовая проверка перед релизом закрывает только первую итерацию, поэтому метрики фиксируют и в отчёте, и в трекере задач. Чек-лист экспресс-аудита Linux-сервера даёт базовый набор команд на 30-60 минут, который удобно брать как регулярный прогон.
Как роль сервера определяет приоритеты аудита
Роль сервера задаёт цели первого уровня. Ниже сведены три типовые роли и проверки, критичные именно для них.
| Роль сервера Nginx | Цели первого уровня | Что можно отложить |
|---|---|---|
| Reverse proxy перед приложением | Валидация Host и X-Forwarded-For, защита от HTTP request smuggling, ограничение методов через limit_except, таймауты proxy_connect_timeout и proxy_read_timeout, запрет proxy_pass на внешние адреса без проверки | Раздачу статики, MIME-типы, кэширование больших файлов |
| Раздача статики | autoindex off, права Linux на файлы и каталоги, корректные MIME-типы, запрет доступа к каталогам с точкой в имени, лимиты на размер запроса | Модуль stream, балансировочные директивы, sticky sessions, health-check |
| Балансировщик нагрузки | Активный health-check (max_fails, fail_timeout), sticky sessions, rate limiting, защита от перегрузки, логирование upstream и времени ответа | Логику раздачи статики, MIME-типы, autoindex |
Таблица экономит время: проверять нужно свою колонку, а не весь список директив Nginx целиком. Для раздачи статики первым делом закрывают листинг каталогов и права на файлы, а вопросы шифрования сессий уходят на второй план.
Формулировка целей и метрик: примеры для аудита
Рабочий шаблон цели содержит четыре элемента: что проверяем, на каком множестве объектов, к какому сроку и по какому признаку считаем результат достигнутым. Пример: «К 1 июня 2026 года все публичные TLS-сертификаты Nginx имеют срок действия не более 200 дней и обновляются автоматически». Метрики к такой цели:
- число сертификатов, до истечения которых осталось меньше 30 дней, целевое значение 0;
- доля сертификатов, перевыпускаемых автоматикой, целевое значение 100%;
- время от появления алерта о сроке до фактического перевыпуска, целевое значение не более 24 часов;
- доля запросов с кодом 5xx от общего числа, целевое значение не более 0,1%.
Масштаб перевыпуска быстро становится узким местом: инфраструктура из 1000 внешних сертификатов при 47-дневном цикле требует около 12 000 перевыпусков в год, то есть порядка 33 операций в день. Расчёт и графики по сокращению сроков сертификатов показывают, почему ручное управление перестаёт работать уже на среднем парке.
Для логов метрика формулируется так: «снизить количество необработанных ошибок 5xx на 50% за месяц» с базовой линией на момент старта. Без базовой линии улучшение нечем доказать, а ухудшение легко не заметить.
Аудит TLS-конфигурации Nginx: что проверять в первую очередь
С 15 марта 2026 года максимальный срок жизни публичного TLS-сертификата сокращён с 398 до 200 дней, дальше сокращение идёт по расписанию: 100 дней в 2027-м и 47 дней в 2029-м. Решение принял CA/Browser Forum, инициатором выступила Apple, ключевым спонсором - Sectigo. Голосование прошло с 4 по 11 апреля 2025 года: 25 голосов «за» от удостоверяющих центров и четыре единогласных «за» от браузеров (Apple, Google, Microsoft, Mozilla). Источник: TLS-сертификатам урезали жизнь до 47 дней.
Базовый набор параметров, которые проверяют первыми:
- ssl_protocols: только TLSv1.2 и TLSv1.3, протоколы SSLv3, TLSv1.0 и TLSv1.1 отключены;
- ssl_ciphers: набор без RC4, 3DES, NULL и экспортных шифров, отдельно проверяется набор для TLS 1.3;
- ssl_prefer_server_ciphers: значение on для TLS 1.2, при этом порядок шифров задаёт сервер;
- ssl_session_cache shared:SSL:10m и ssl_session_timeout с разумным значением, обычно 10 минут;
- HSTS: add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always. Заголовок включают после проверки, что весь трафик действительно идёт по HTTPS, иначе часть пользователей потеряет доступ;
- OCSP stapling: ssl_stapling on, ssl_stapling_verify on, ssl_trusted_certificate с полной цепочкой.
Цепочку и даты проверяют без остановки сервера. Команда openssl s_client -connect example.com:443 -servername example.com -showcerts выводит всю цепочку, включая промежуточные сертификаты. Даты истечения показывает связка: echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates. Если промежуточный сертификат отсутствует в конфигурации, часть мобильных клиентов получит ошибку проверки цепочки при рабочем десктопном браузере.
Самоподписанные сертификаты в продакшене ломают проверку цепочки у клиентов и не дают отзыва через OCSP. Их место - внутренние стенды, тестовые контуры и служебные интерфейсы, закрытые сетевыми правилами. Для публичных хостов цель формулируйте прямо: «ноль публичных виртуальных хостов с самоподписанным сертификатом».
Проверка сроков действия и автоматизации перевыпуска сертификатов
Сокращение сроков переносит фокус аудита с набора шифров на процесс обновления. При ручном управлении нагрузка растёт нелинейно: для 2500 систем в 2027 году это около 37 500 рабочих часов, а в 2029-м - порядка 108 900 часов. Разбор нагрузки на команду при разных циклах перевыпуска объясняет, почему автоматизация становится не удобством, а условием работы.
Что проверять в этом блоке:
- ACME-клиент установлен и обслуживает все публичные сертификаты. На практике это certbot или acme.sh; ручные CSR остаются только как исключение с обоснованием;
- таймер systemd или задание cron запускает certbot renew не реже двух раз в сутки со случайной задержкой, чтобы не бить по лимитам центра сертификации;
- хук развёртывания перезагружает Nginx: certbot renew --deploy-hook "systemctl reload nginx". Без хука сертификат на диске обновится, а в памяти останется старый;
- мониторинг дат истечения с алертами за 30 и за 14 дней, отдельно по каждому домену, включая те, что живут только в конфигурации без трафика;
- проверка, что staging-контур ACME не используется в продакшене и наоборот, иначе браузеры отклонят выданный сертификат.
Ограничение: приведённые сроки касаются публичных сертификатов. Внутренний PKI может жить по своим правилам, и цели для него формулируют отдельно, с опорой на политику компании.
Директивы безопасности Nginx: чек-лист для проверки
Директивы, которые проверяют в первую очередь:
- server_tokens off. Скрывает версию в заголовке Server и на страницах ошибок. Полноценной защитой директива не считается, но убирает готовый ориентир для подбора эксплойта под конкретный релиз;
- client_max_body_size с конкретным лимитом, обычно 1m для обычного сайта и отдельное значение для локаций загрузки файлов;
- client_body_timeout и client_header_timeout в диапазоне 10-15 секунд, чтобы медленные клиенты не держали соединения;
- keepalive_timeout с осмысленным значением, типично 30-65 секунд;
- add_header X-Content-Type-Options nosniff always;
- add_header X-Frame-Options SAMEORIGIN always;
- add_header Content-Security-Policy с политикой, проверенной на фронтенде, иначе часть скриптов перестанет загружаться;
- add_header Referrer-Policy strict-origin-when-cross-origin always;
- limit_req_zone и limit_req для форм логина, API и поиска;
- ssl_session_tickets off, если нет ротации ключей тикетов.
Опасные конфигурации, которые встречаются чаще всего: autoindex on без аутентификации (полный листинг каталогов), location с alias, выводящий за пределы корня, proxy_pass без проверки заголовка Host и отсутствие ограничения методов через limit_except GET POST. Разбор защиты каталогов, Basic-аутентификации и диагностика кодов 401, 403, 404 и 502 есть в материале Права доступа к данным в Nginx: аутентификация и контроль. Готовые команды для проверки TLS, заголовков, HSTS и ограничения доступа по адресам собраны в статье Аудит безопасности Nginx: TLS, заголовки и контроль доступа в 2026.
Контроль версий Nginx и подключённых модулей
Версия Nginx попадает в заголовок Server, пока не выключен server_tokens, и в страницы ошибок по умолчанию. Устаревший релиз получает уязвимости, которые уже закрыты в свежих сборках, поэтому проверка версии входит в базовый аудит. Ориентир: релиз не старше шести месяцев, критичные исправления безопасности ставятся вне очереди.
Сторонние модули расширяют функциональность и одновременно поверхность атаки: Lua, GeoIP, headers-more, модули WAF. Смежный риск показывает история драйверов Gigabyte Control Center. Уязвимости в ядерных драйверах GVCIDrv64.sys и gdrv3.sys позволяют локальному атакующему через специально сформированный IOCTL-запрос обойти защиты памяти и повысить привилегии до Ring 0, вплоть до NT AUTHORITY\SYSTEM. Причина - недостаточный контроль доступа и неправильная валидация входных параметров в IOCTL-интерфейсах. Разбор инцидента с драйверами Gigabyte полезен как иллюстрация: доверенный компонент с ошибкой в проверках открывает путь к полной компрометации системы.
Для Nginx логика та же: устаревший или непроверенный модуль может обойти ограничения, которые вы задали директивами. Держите сборку из официальных репозиториев, проверяйте подписи пакетов и фиксируйте образы по digest, а не по тегу latest. Обновление Nginx с бэкапом конфигурации и сценарием отката описано в чек-листе Обновление Nginx: бэкап и быстрое восстановление.
Как проверить версию и модули без остановки сервера
Команда nginx -V выводит версию, аргументы сборки и список подключённых модулей. Перезагрузка не нужна, конфигурация при этом не читается. Команда nginx -T показывает полную собранную конфигурацию с учётом всех include и тоже безопасна на работающем сервере.
Вывод обеих команд сохраняйте для истории аудита: nginx -V 2> nginx-build.txt, а затем nginx -T 2> nginx-full-config.txt. На следующей итерации diff покажет, что изменилось в сборке и конфигурации, и вы не будете искать изменения вручную.
В контейнерах версия внутри образа отличается от хостовой, поэтому проверку запускают в самом контейнере, а не на хосте. Если образ собран на distroless или минимальном alpine, убедитесь, что утилита доступна, либо логируйте версию Nginx при старте процесса и забирайте её из логов.
Анализ логов Nginx на подозрительную активность
Что искать в access.log и error.log: серии ответов 4xx, рост 5xx, необычные User-Agent, запросы к чувствительным путям (.env, .git/config, wp-login.php, /admin, /phpmyadmin), параметры с кавычками, обратными слэшами и последовательностями ../. Всплеск 404 обычно означает сканирование уязвимостей, серия 401 на /admin указывает на перебор паролей, а стабильные 5xx говорят об ошибке конфигурации или атаке на backend.
Инструменты под задачу: goaccess для разбора в реальном времени, awk и sort для быстрых выборок, ELK или OpenSearch для корреляции событий по нескольким сервисам. В cloud-native архитектуре логи рассматривают как поток событий и отправляют напрямую во внешнюю систему, а не накапливают на узле. Подборка практик DevOps по логированию и инфраструктуре объясняет, почему такой подход упрощает реакцию на инциденты.
Пример команды для поиска топ-адресов по ошибкам: awk '$9 ~ /^4/ {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20. Для подсчёта доли 5xx меняется условие на /^5/ и добавляется сравнение с общим числом строк.
Ротация закрывает риск переполнения диска: без logrotate и лимитов access.log на активном сайте занимает гигабайты и приводит к отказу записи в журнал. Проверяйте срок хранения, сжатие и наличие свободного места отдельной метрикой, потому что диск, забитый логами, останавливает и сам Nginx.
Настройка оповещений на аномалии в логах
fail2ban блокирует адреса по количеству ошибок. Рабочие шаблоны: jail nginx-http-auth для 401 на Basic-аутентификации, nginx-limit-req для срабатываний limit_req и собственный фильтр для серий 404, характерных для сканеров. Начните с режима только оповещения, чтобы не заблокировать собственные мониторинговые проверки.
Prometheus с Grafana или Zabbix даёт пороги на потоке событий. Парсинг логов выполняют mtail, grok_exporter или filebeat, дальше настраивают правила: более 100 ответов 401 за 5 минут с одного адреса - уведомление; доля 5xx выше 1% за 10 минут - уведомление; новый User-Agent, дающий свыше 50% запросов - уведомление. Пороги подбирайте по базовой линии трафика, иначе легитимная активность будет постоянно вызывать ложные срабатывания.
Как адаптировать аудит под конкретную инфраструктуру
Дистрибутив меняет список проверок. РЕД ОС - российский RPM-дистрибутив, наследующий архитектуру RHEL: пакетный менеджер семейства RPM, systemd, штатный фаервол firewalld вместо ufw и голого iptables, а поверх обычных прав файлов работает SELinux. Типовой Ubuntu-мануал по настройке Nginx и PHP промахивается в трёх местах: другие имена пакетов, другой синтаксис управления портами и дополнительный слой проверки доступа SELinux. Практика сборки веб-стека Nginx и PHP на РЕД ОС показывает эти различия на конкретных шагах. В аудит добавляется проверка контекстов SELinux для каталогов и портов, иначе при верной конфигурации Nginx получит отказ 403 или не запустится после смены порта.
Практика immutable infrastructure меняет цели аудита: серверы и контейнеры никогда не патчатся и не изменяются на месте, обновления требуют сборки нового образа, тестирования, развёртывания и вывода старых инстансов. Описание подхода и его эффектов подчёркивает главную выгоду: дрейф конфигураций исчезает, откаты становятся детерминированными, а восстановление после сбоя упрощается. Следовательно, проверять нужно сборку образа и пайплайн, а не наличие обновлений на живом сервере.
Метрики восстановления задают верхнюю границу для целей аудита. RTO - максимально допустимая длительность простоя системы после сбоя до восстановления сервиса, RPO - максимально допустимая потеря данных, измеряемая назад во времени от момента сбоя. При бэкапах в полночь и сбое в 2:00 ночи RPO равен 2 часам данных, а восстановление за 30 минут даёт RTO 30 минут. Определения RTO и RPO с примерами помогают перевести эти требования в проверяемые цели по Nginx: время подъёма конфигурации из бэкапа, время переключения на резервный upstream.
Особенности аудита Nginx в контейнерах и immutable infrastructure
Проверки для контейнерного Nginx строятся вокруг образа и рантайма:
- базовый образ: distroless или alpine вместо полного Debian. Наличие curl, bash и компилятора в финальном слое увеличивает поверхность атаки и размер образа;
- отсутствие секретов внутри образа: ключи и пароли приходят через переменные окружения, secrets или монтируемые тома, а не через COPY в Dockerfile;
- непривилегированный пользователь в директиве USER и отказ от запуска от root;
- read-only корневая файловая система там, где это возможно, с записью только в каталоги кэша и временных файлов;
- лимиты CPU и памяти, которые защищают узел от перегрузки при всплеске трафика;
- логи в stdout и stderr со сбором агентом, а не в файлы внутри контейнера;
- фиксация базового образа по digest, чтобы сборка была воспроизводимой.
Аудит пайплайна дополняет проверку сервера: убедитесь, что уязвимости базового образа сканируются, что образ пересобирается после выхода патчей и что описание ролей раздачи статики и проксирования совпадает с фактической конфигурацией. Расхождения между документацией и реальным образом находят быстрее всего сравнением nginx -T из работающего контейнера с версией в репозитории.
Примеры формулировок целей и метрик для аудита Nginx
Готовые формулировки, которые можно адаптировать под свою инфраструктуру. Каждая цель измерима и проверяется конкретной командой или запросом.
| Цель аудита | Метрика | Способ проверки |
|---|---|---|
| Все публичные TLS-сертификаты обновляются автоматически не позднее чем за 30 дней до истечения | Доля сертификатов с остатком более 30 дней: 100% | Инвентарь сертификатов, вывод openssl x509 -noout -dates, список certbot certificates |
| server_tokens отключён на всех виртуальных хостах | Ноль хостов, отдающих версию в заголовке Server | nginx -T с поиском server_tokens, проверка curl -I по каждому домену |
| В логах нет успешных обращений к .git, .env и резервным копиям | Ноль записей со статусом 200 к этим путям | Выборка по access.log за 30 дней с фильтром по путям и коду ответа |
| Версия Nginx не старше шести месяцев | Дата релиза в пределах 180 дней от текущей | nginx -V и сверка версии с перечнем исправлений безопасности |
| Количество 5xx не превышает 0,1% от общего числа запросов | Доля 5xx по итогам месяца | Разбор access.log или метрики Prometheus по кодам ответов |
| Самоподписанные сертификаты остались только на внутренних стендах | Ноль публичных хостов с самоподписанным сертификатом | openssl s_client с проверкой цепочки по инвентарю доменов |
| Реакция на инцидент с Nginx укладывается в 30 минут | Медиана времени от алерта до первого действия | Журнал дежурств и история инцидентов |
Метрики согласуйте с бизнес-требованиями к доступности и восстановлению: RTO и RPO задают границы, внутри которых выбирают допустимые значения для остальных целей. Отчёт об аудите удобно строить той же таблицей с добавленными колонками фактического значения, расхождения, ответственного и срока исправления. Такой отчёт одинаково понятен и технической команде, и руководителю.
Начните с инвентаризации: выпишите все серверы Nginx, их роли и сроки истечения сертификатов. Этого достаточно, чтобы сформулировать первые три цели и выбрать проверки для ближайшего прогона, а остальные пункты добавить по мере закрытия приоритетных.