За 5–10 минут вы проведёте базовый аудит безопасности Nginx: проверите версии TLS и шифры, защитные HTTP-заголовки, HSTS, доступ к /admin и /status, rate limiting и текущую конфигурацию. На выходе будут сохранённые результаты проверок, готовые конфигурационные фрагменты и понятный список изменений, которые нужно внести и проверить без риска для рабочей среды.
Nginx принимает на себя первый удар: все запросы к вашим сервисам проходят через него до того, как попасть в приложение. Ошибка в конфигурации означает прямой доступ к внутренним данным, перехват трафика или отказ в обслуживании. В 2026 году базовой настройки HTTPS недостаточно, нужен системный аудит: проверка TLS, защитных заголовков и правил доступа. Ниже приведён пошаговый план с готовыми конфигурациями и командами для самостоятельной проверки.
Вы выполните аудит по четырём направлениям: соберёте текущую конфигурацию, проверите параметры TLS, добавите защитные HTTP-заголовки и ограничите доступ к чувствительным разделам. Каждый шаг проверяется командами, которые можно запустить прямо сейчас. Если вы настраиваете Nginx впервые, начните с разбора модулей Nginx, чтобы понимать, какие возможности доступны в вашей сборке.
Быстрый чек-лист аудита безопасности Nginx
- Соберите конфигурацию, версию и список модулей через
nginx -Tиnginx -V. - Проверьте, что сервер принимает только TLS 1.2 и TLS 1.3.
- Проверьте HSTS, CSP, X-Frame-Options и другие защитные заголовки.
- Проверьте ограничение доступа к
/admin,/statusи внутренним API. - Проверьте rate limiting для входа и API.
- Скройте версию Nginx через
server_tokens offи повторите внешнее сканирование. - Сохраните результаты и добавьте проверку конфигурации в CI/CD.
Подготовка к аудиту: инструменты и исходные данные
Перед изменениями зафиксируйте текущее состояние. Это позволит откатиться, если новая конфигурация нарушит работу сервиса. Сохраните полный вывод конфигурации, список модулей и версию сервера.
Сбор информации о текущей конфигурации
Команда nginx -T выводит полную конфигурацию со всеми подключёнными файлами. Это главный источник для анализа. Выполните на сервере:
nginx -T > /root/nginx_audit_$(date +%F).conf
nginx -V 2>&1 | tee /root/nginx_modules_$(date +%F).txt
nginx -v 2>&1 | tee /root/nginx_version_$(date +%F).txt
Первая команда сохраняет конфигурацию, вторая показывает версию и параметры сборки, включая подключённые модули, третья фиксирует номер версии. Проверьте, что в выводе nginx -V есть модули http_ssl_module, http_v2_module, http_v3_module (для QUIC) и http_realip_module. Если какого-то модуля нет, часть рекомендаций из этой статьи потребует пересборки Nginx.
Сделайте резервную копию каталога конфигурации:
cp -a /etc/nginx /etc/nginx.backup.$(date +%F)
Выбор инструментов для автоматизированной проверки
Ручная проверка каждой директивы занимает часы. Автоматические сканеры ускоряют процесс и выявляют неочевидные проблемы. Основной набор для аудита Nginx в 2026 году:
- testssl.sh - проверяет TLS-конфигурацию: протоколы, шифры, сертификаты и уязвимости. Запускается одной командой:
./testssl.sh https://example.com. - nmap - сканирует открытые порты и определяет службы:
nmap -sV -p 80,443 example.com. Показывает, какие порты реально открыты снаружи. - Mozilla Observatory - онлайн-проверка защитных заголовков и общей безопасности HTTP.
- SSL Labs - глубокий анализ TLS-стека, совместимости с клиентами и цепочек сертификатов.
Запустите инструменты до внесения изменений и сохраните результаты. После настройки повторите проверку и сравните показатели. Это даст объективную картину прогресса.
Аудит и настройка TLS Nginx
TLS защищает данные между клиентом и сервером. Слабые протоколы и шифры позволяют понизить безопасность соединения или использовать устаревшие алгоритмы. В 2026 году для публичного сервиса обычно оставляют TLS 1.2 и TLS 1.3. SSLv3, TLS 1.0 и TLS 1.1 должны быть запрещены, если нет документированной необходимости поддерживать устаревших клиентов.
Проверка поддерживаемых протоколов и шифров
Проверьте каждый протокол отдельно с помощью openssl s_client:
openssl s_client -connect example.com:443 -tls1_2 -brief </dev/null
openssl s_client -connect example.com:443 -tls1_3 -brief </dev/null
openssl s_client -connect example.com:443 -tls1_1 -brief </dev/null
Если первые две команды возвращают сертификат и строку «Protocol version», протоколы работают. Третья команда должна завершиться ошибкой «unsupported protocol» или «handshake failure». Если TLS 1.1 всё ещё принимается, отключите его после проверки совместимости клиентов.
Для полного списка шифров используйте testssl.sh:
./testssl.sh --protocols --cipher-per-proto https://example.com
В выводе ищите шифры с пометкой «offered». Убедитесь, что отсутствуют экспортные шифры (EXPORT), статические RSA (RSA-PSK, RSA-AES), CBC-шифры в TLS 1.2, а также шифры с ключами меньше 128 бит. Допустимые наборы: ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-RSA-AES128-GCM-SHA256, ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-RSA-AES256-GCM-SHA384, ECDHE-ECDSA-CHACHA20-POLY1305, ECDHE-RSA-CHACHA20-POLY1305.
Настройка TLS Nginx
Проверенный базовый блок для Nginx 1.24+:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305';
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
Разбор параметров:
- ssl_protocols - разрешает только TLS 1.2 и 1.3.
- ssl_ciphers - список шифров с прямой секретностью (ECDHE) и аутентифицированным шифрованием (GCM, CHACHA20). В TLS 1.3 выбор набора шифров делает клиент.
- ssl_prefer_server_ciphers off - в TLS 1.3 эта директива не работает, а для TLS 1.2 сохраняет совместимость с современными клиентами.
- ssl_session_cache - кэш сессий на 10 мегабайт. Ускоряет повторные подключения и снижает нагрузку на CPU.
- ssl_session_tickets off - отключает session tickets, если вы не настроили безопасную ротацию их ключей.
- ssl_stapling - включает OCSP stapling. Перед включением проверьте корректность цепочки сертификата и наличие
resolver. - ssl_dhparam - файл с параметрами Диффи-Хеллмана для DHE-совместимости. Сгенерируйте его командой
openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048, если он требуется вашей конфигурации.
После изменения конфигурации проверьте синтаксис и перезагрузите Nginx:
nginx -t && systemctl reload nginx
Настройка HSTS (HTTP Strict Transport Security)
HSTS заставляет браузер всегда использовать HTTPS для вашего домена, даже если пользователь вводит http:// или переходит по http-ссылке. Заголовок добавляется в блок server, слушающий порт 443:
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
Параметры:
- max-age=63072000 - срок действия политики в секундах (2 года).
- includeSubDomains - распространяет политику на все поддомены.
- preload - разрешает включение в список предзагрузки HSTS браузеров. Добавляйте этот параметр только если уверены, что весь домен и все поддомены будут работать по HTTPS постоянно. Удаление из списка preload занимает месяцы.
Для дополнительных сценариев настройки HTTPS, HSTS и CSP используйте руководство по SSL termination в Nginx.
Настройка защитных HTTP-заголовков Nginx
Заголовки безопасности управляют поведением браузера: что можно загружать, как обрабатывать ответы и какие API доступны странице. Без них повышается риск XSS, clickjacking и утечек данных.
Content-Security-Policy (CSP)
CSP ограничивает источники, из которых браузер может загружать скрипты, стили, изображения и другие ресурсы. Это важная защита от XSS, но политика должна соответствовать фактическим ресурсам приложения.
Базовая политика для статического сайта:
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self'" always;
Для приложения с внешними сервисами добавьте нужные домены в соответствующие директивы. Например, для Google Fonts:
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
font-src 'self' https://fonts.gstatic.com;
Тестируйте политику в режиме Content-Security-Policy-Report-Only перед включением. Браузер будет сообщать о нарушениях, но не блокировать ресурсы. Настройте приём отчётов через директиву report-uri или report-to. После устранения нарушений замените заголовок на принудительный.
Другие важные заголовки: X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy
Каждый заголовок закрывает конкретный вектор атаки:
- X-Frame-Options - запрещает встраивание страницы во фреймы на чужих сайтах. Значение
SAMEORIGINразрешает фреймы только с вашего домена,DENYзапрещает полностью. - X-Content-Type-Options - значение
nosniffзапрещает браузеру угадывать MIME-тип. - Referrer-Policy - управляет передачей заголовка Referer при переходах. Значение
strict-origin-when-cross-originпередаёт только домен при переходе на другой сайт и полный URL при переходе внутри вашего домена. - Permissions-Policy - отключает доступ к API браузера: геолокация, микрофон, камера, USB. Значение
geolocation=(), microphone=(), camera=(), usb=()запрещает доступ для всех источников.
Готовый блок для добавления в server:
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=(), usb=()" always;
Директива always добавляет заголовки также к ответам с кодами 4xx и 5xx. После включения проверьте не только главную страницу, но и ответы ошибок.
Проверка защитных заголовков
Проверьте результат напрямую:
curl -I https://example.com | grep -E 'strict-transport|content-security|x-frame|x-content|referrer|permissions'
Mozilla Observatory покажет оценку и список недостающих заголовков. SSL Labs поможет проверить HTTPS и TLS, а локальная команда curl подтвердит, что заголовки возвращаются именно вашим Nginx.
Контроль доступа Nginx: IP, аутентификация и rate limiting
Административные панели, статусные страницы и внутренние API не должны быть доступны всем. Nginx умеет ограничивать доступ на уровне location: по IP-адресам, по логину и паролю, по частоте запросов.
Ограничение доступа по IP-адресам
Для раздела /admin, доступного только из офисной сети:
location /admin {
allow 192.168.1.0/24;
allow 10.0.0.5;
deny all;
}
Директивы allow и deny обрабатываются по порядку. Первое совпадение определяет результат, поэтому deny all должен быть последним. Для IPv6 используйте подсети вида 2001:db8::/32.
Ограничение по IP не работает как единственный критерий, если пользователи заходят через прокси или VPN с динамическими адресами. В этом случае комбинируйте его с аутентификацией. Если Nginx стоит за балансировщиком, настройте модуль http_realip_module, чтобы Nginx видел реальные IP клиентов, а не адрес балансировщика.
Базовая HTTP-аутентификация
Дополнительный уровень защиты для чувствительных разделов. Создайте файл паролей:
htpasswd -c /etc/nginx/.htpasswd admin
Команда запросит пароль и создаст файл. Для добавления новых пользователей используйте htpasswd /etc/nginx/.htpasswd username без флага -c.
Подключите аутентификацию к location:
location /status {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
stub_status on;
}
Базовая аутентификация передаёт пароль в base64, что не является шифрованием. Используйте её только поверх HTTPS. Для более надёжной защиты рассмотрите JWT-аутентификацию через модуль auth_jwt, доступный в Nginx 1.22+.
Защита от подбора паролей и брутфорса
Ограничение частоты запросов к формам входа снижает эффективность перебора. Определите зону лимита в блоке http:
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
Примените зону к location с формой входа:
location /login {
limit_req zone=login burst=3 nodelay;
proxy_pass http://backend;
}
Параметры: rate=5r/m - 5 запросов в минуту с одного IP, burst=3 - допускает кратковременный всплеск до 3 запросов сверх лимита, nodelay - обрабатывает всплеск без задержки. При превышении лимита Nginx по умолчанию возвращает 503.
Дополнительные меры защиты от распространенных атак
Базовые настройки TLS, заголовков и доступа закрывают основные векторы, но Nginx также нужно защитить от перегрузки и разведки. Следующие меры снижают поверхность атаки.
Ограничение частоты запросов (Rate Limiting)
Глобальный лимит защищает от чрезмерного числа запросов и сканирования. Определите зону для всего сервера:
limit_req_zone $binary_remote_addr zone=general:10m rate=30r/s;
Примените в server или location:
limit_req zone=general burst=20 nodelay;
Для API с высоким трафиком создайте отдельную зону с большим лимитом. Для статики лимит можно не применять, если она отдаётся из кэша и не нагружает бэкенд.
Скрытие информации о сервере
Заголовок Server: nginx/1.24.0 сообщает злоумышленнику точную версию. Отключите версию:
server_tokens off;
После этого заголовок будет выглядеть как Server: nginx. Для полного удаления или замены заголовка используйте модуль headers_more:
more_set_headers "Server: web";
Модуль headers_more не входит в стандартную сборку и требует пересборки Nginx. Если вы не готовы к этому, ограничьтесь server_tokens off.
Фильтрация подозрительных запросов
Простые правила блокируют известные паттерны SQL-инъекций и XSS до того, как запрос попадёт в приложение:
if ($request_uri ~* "(union.*select|select.*from|insert.*into|drop.*table|--)") {
return 403;
}
if ($request_uri ~* "(<script|%3Cscript|javascript:)") {
return 403;
}
Эти правила дают ложные срабатывания на легитимных запросах, содержащих подстроки в параметрах. Тестируйте их на реальном трафике и ведите журнал блокировок. Для серьёзной фильтрации используйте ModSecurity или WAF-конфигурации для Nginx, которые разбирают запросы по стандартным правилам OWASP.
Что проверить после изменений
- nginx -t - проверяет синтаксис и наличие подключённых файлов до reload.
- curl -I - подтверждает, что HSTS и защитные заголовки возвращаются в HTTP-ответе.
- openssl s_client - проверяет доступность конкретных версий TLS.
- testssl.sh - повторно сканирует протоколы, шифры, сертификаты и заголовки.
- nmap - показывает фактически открытые снаружи порты и обнаруженные службы.
- Mozilla Observatory и SSL Labs - дают внешнюю оценку HTTP-заголовков и TLS.
Автоматизация аудита и постоянный мониторинг
Разовый аудит фиксирует состояние на момент проверки. Безопасность требует регулярного повторения: конфигурации меняются, появляются новые уязвимости, старые настройки устаревают. Автоматизация снижает трудозатраты и гарантирует, что проверка не будет забыта.
Создание скрипта для регулярной проверки
Скрипт запускает testssl.sh и сохраняет результаты с датой:
#!/bin/bash
DOMAIN="example.com"
OUTPUT_DIR="/var/log/nginx-audit"
DATE=$(date +%F)
mkdir -p $OUTPUT_DIR
/opt/testssl.sh/testssl.sh --quiet --json-pretty https://$DOMAIN > $OUTPUT_DIR/tls_$DATE.json
/opt/testssl.sh/testssl.sh --quiet --headers https://$DOMAIN > $OUTPUT_DIR/headers_$DATE.txt
find $OUTPUT_DIR -name "*.json" -mtime +30 -delete
echo "Audit completed: $DATE" | systemd-cat -t nginx-audit
Добавьте задачу в cron:
0 3 * * 1 /usr/local/bin/nginx-audit.sh
Скрипт выполняется каждый понедельник в 3 часа ночи. Результаты хранятся 30 дней. Для отправки на почту добавьте вызов mailx или интеграцию с вашей системой оповещений.
Интеграция с CI/CD
Проверка конфигурации перед деплоем предотвращает попадание ошибок в production. Минимальный шаг в пайплайне:
nginx -t -c /etc/nginx/nginx.conf
Для проверки безопасности используйте контейнер с testssl.sh, который запускается против тестового окружения. Если оценка ниже заданного порога, деплой блокируется. Это помогает не ухудшить безопасность при изменениях конфигурации.
Заключение: чек-лист безопасности Nginx
Пройдите по пунктам и отметьте выполненные. Каждый пункт проверяется командами из соответствующих разделов.
- TLS 1.2 и TLS 1.3 включены, старые протоколы отключены.
- Шифры только ECDHE с GCM или CHACHA20, без CBC и статических RSA.
- HSTS добавлен с max-age не менее 1 года.
- CSP настроен и протестирован в report-only режиме.
- X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy добавлены.
- Доступ к
/admin,/statusи другим чувствительным разделам ограничен по IP или паролю. - Rate limiting включён для форм входа и API.
- server_tokens off скрывает версию Nginx.
- Автоматический аудит запускается по расписанию.
- Проверка конфигурации встроена в CI/CD.
Повторяйте аудит не реже одного раза в квартал или после каждого значительного изменения конфигурации. Безопасность Nginx - это процесс, а не разовое действие. Для комплексного hardening Linux-сервера используйте практическое руководство по безопасности Linux.