Чек-лист безопасности, CVE 2026 и аудит конфигурации

Рейтинг: 77.2% · 13 голосов
Самый подробный курс по Nginx - от первого конфига до production API-gateway. Архитектура и event loop, контексты и location, виртуальные хосты, статика, reverse proxy и upstream-балансировка, кэширование, HTTPS и TLS (post-quantum), HTTP/2 и HTTP/3 QUIC, безопасность и rate limiting, realip, JSON-логи и сквозная трассировка, метрики, тюнинг и траблшутинг. Плюс OpenResty (Lua, фазы, JWT, динамика) и Angie (нативные Prometheus, ACME, dynamic upstream). На основе эталонного gateway и лучших практик. Для новичков и SRE/DevOps. Актуально на 2026 (nginx 1.30/1.31, Angie, ingress-nginx EOL -> Gateway API).
Ответить
Аватара пользователя
Igor_NgINX
Сообщения: 44
Зарегистрирован: 11 май 2026, 05:31

Чек-лист безопасности, CVE 2026 и аудит конфигурации

Сообщение Igor_NgINX »

Оглавление курса (44)
  1. Что такое Nginx и почему он захватил веб
  2. Установка Nginx, Angie и OpenResty: пакеты, версии, Docker
  3. Первый конфиг с нуля: минимальный сервер за 5 минут
  4. Архитектура процессов: master, worker и event loop
  5. Анатомия конфигурации: контексты, наследование и модульность
  6. Виртуальные хосты: server и server_name
  7. Директива location: матчинг и приоритеты по шагам
  8. Раздача статики: root, alias, try_files, sendfile
  9. Переменные, map и блок if
  10. rewrite, return и канонизация URL
  11. Работа с заголовками: add_header и proxy_set_header
  12. Модель доверия прокси-заголовков: realip и защита от спуфинга
  13. Сжатие: gzip, brotli и zstd
  14. Reverse proxy: proxy_pass и проброс запроса
  15. upstream и балансировка нагрузки
  16. Таймауты, повторы и устойчивость прокси
  17. FastCGI и PHP: nginx + PHP-FPM (и uwsgi/scgi)
  18. WebSocket, gRPC и стриминг через Nginx
  19. Кэширование ответов: proxy_cache и микрокэш
  20. HTTPS и TLS: сертификаты, протоколы, шифры (2026)
  21. Let's Encrypt и ACME: certbot, acme.sh, нативный ACME Angie
  22. HTTP/2 и HTTP/3 (QUIC) в 2026
  23. Безопасность: заголовки, скрытие версии, ограничения
  24. Rate limiting и защита от перегрузки
  25. Контроль доступа: allow/deny, auth_basic, auth_request и mTLS
  26. Логирование: access_log, форматы и структурированный JSON
  27. Сквозная трассировка запросов и OpenTelemetry
  28. Метрики и мониторинг Nginx
  29. Производительность и тюнинг под нагрузку
  30. Траблшутинг: 502, 504, 403, 404 и debug-лог
  31. OpenResty: Nginx как платформа на LuaJIT
  32. Фазы обработки запроса и Lua-хуки
  33. Lua API: ngx.*, shared dict, cosocket и lua-resty-core
  34. Практика OpenResty: авторизация, JWT, кэш, Redis
  35. Angie: современный форк Nginx 2026
  36. Динамическая конфигурация и service discovery
  37. Nginx как API-gateway и Kubernetes Gateway API
  38. Динамические модули, njs и WAF
  39. Stream-модуль: проксирование TCP и UDP
  40. Деплой, перезагрузка и конфиг как код
  41. Сценарий: статика, SPA и кэширование за CDN
  42. Сценарий: микросервисный gateway по образцу ngx-trace-gateway
  43. Капстоун: собираем production-gateway с нуля
  44. Чек-лист безопасности, CVE 2026 и аудит конфигурации (вы здесь)
Ты прошёл весь путь: от первого listen до балансировки, кэша, TLS и Lua-логики на OpenResty. Теперь самое неприятное и самое важное - финальная ревизия. Потому что один забытый autoindex on, один лишний rewrite, один доверенный не тому диапазону X-Forwarded-For - и весь твой красивый gateway превращается в дыру. В 2026 это не абстракция: NGINX Rift (CVE-2026-42945) активно эксплуатируется с мая, и он сидит в коде с 2008 года. Этот урок - твой боевой чек-лист. Не теория про CIA-триаду, а конкретные директивы, конкретные версии, конкретные команды аудита. Прогоним конфиг через gixy и SSL Labs, разберём свежие CVE и закроем типовые дыры руками.

Nginx безопасность: чек-лист на 2026 без воды

Давай сразу зафиксируем модель. Безопасность шлюза - это не один add_header, а слои. Снаружи внутрь: транспорт (TLS), заголовки ответа (что браузер разрешит делать), фильтрация запроса (методы, размер тела, флуд), сокрытие внутренностей (версии, апстрим-ошибки, dotfiles), скорость (rate limiting против перебора), и наконец гигиена софта (актуальные версии против CVE). Пропустишь слой - получишь компрометацию именно через него.

Пройдёмся по пунктам, каждый с реальной директивой и пояснением почему, а не только как.

1. Транспорт: только TLS 1.2/1.3 и сильные группы. SSLv3, TLS 1.0/1.1 мертвы - POODLE, BEAST. Оставляй два протокола. Помни выверенный факт: ssl_ciphers НЕ управляет шифрами TLS 1.3 - там фиксированный набор AEAD, а тонкая настройка идёт через ssl_conf_command Ciphersuites. И добавь пост-квантовый обмен ключами - в 2026 это уже не экзотика, Chrome и Firefox его шлют по умолчанию.

Код: Выделить всё

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;            # для TLS1.3 порядок не нужен, клиенту виднее
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_ecdh_curve X25519MLKEM768:X25519:prime256v1;   # гибридный post-quantum, OpenSSL 3.5+
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;                  # без ротации ключей тикеты ломают forward secrecy
ssl_conf_command Ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;
Не копируй ssl_dhparam вслепую: он нужен только для классических DHE-шифров. На связке TLS 1.3 + ECDHE он не используется. А ssl_stapling в 2026 фактически легаси - Let's Encrypt убрал OCSP-URL ещё 7 мая 2025, так что стаплить нечего. Если он у тебя включён для LE-сертификата - это мёртвая директива, можешь убирать без сожаления.

2. HSTS - заставь браузер ходить только по HTTPS. Без HSTS первый запрос клиента уйдёт по http и его перехватят (SSL stripping).

Код: Выделить всё

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
Ключевое - флаг always, иначе заголовок не добавится к ответам с кодами 4xx/5xx и редиректам, а именно там он критичен. max-age в секундах (тут два года). preload включай только когда уверен, что весь поддомен-парк живёт на HTTPS - откатить из preload-списка браузеров долго и больно.

3. CSP вместо устаревшего X-XSS-Protection. Вот частая ошибка-копипаст из старых гайдов (она есть и в нашем эталонном global_security.conf как наследие). X-XSS-Protection в 2026 устарел - OWASP прямо говорит: не слать его или слать '0'. Старый XSS-аудитор браузеров сам стал источником уязвимостей и давно удалён. Защита от XSS сегодня - это Content-Security-Policy.

Код: Выделить всё

add_header Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'self'; base-uri 'self'" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
# X-XSS-Protection НЕ шлём (или "0") - он устарел в 2026
X-Content-Type-Options nosniff запрещает браузеру угадывать MIME-тип (защита от подсунутого html под видом картинки). frame-ancestors в CSP - современная замена X-Frame-Options против кликджекинга.

4. server_tokens off и сокрытие версии. По умолчанию nginx пишет точную версию в заголовок Server и на страницах ошибок. Это подарок сканеру: версия -> список CVE -> готовый эксплойт.

Код: Выделить всё

server_tokens off;
Это первое, что увидит атакующий, и первое, что закрывает наш эталонный global_security.conf. Полностью убрать слово nginx из Server в open-source без патча/модуля нельзя, но версию ты прячешь.

5. max_headers - анти-флуд заголовками (nginx 1.29.8). Свежая директива. Раньше ничто не мешало клиенту прислать тысячи мелких заголовков в одном запросе - это header-flooding DoS, который ел память и CPU воркера. Теперь есть жёсткий потолок:

Код: Выделить всё

max_headers 100;     # запрос с большим числом заголовков -> сразу 400 Bad Request
Ставь на http/server-уровне. Запрос сверх лимита отбивается с 400 ещё до разбора. Грабля: при копипасте server-блока в новый vhost эту директиву легко потерять - именно поэтому полезен периодический аудит (об этом ниже).

Изображение

Nginx hardening: фильтрация запроса и сокрытие внутренностей

Теперь слой запроса. Тут живут самые дешёвые в эксплуатации дыры.

6. Запрет dotfiles, .git, .env и бэкапов. Классика утечек: выложили проект rsync-ом вместе с .git, и любой выкачивает исходники и секреты через /.git/config. Или .env с паролем БД лежит в корне сайта.

Код: Выделить всё

location ~ /\.(?!well-known) {        # любые dotfiles, кроме .well-known (ACME, security.txt)
    deny all;
    access_log off;
    log_not_found off;
}
location ~* \.(env|bak|sql|zip|tar|gz|old|swp|orig)$ {
    deny all;
}
Первый регэксп - то, что делает app_redirects_security.conf в эталоне: режет точечные файлы, но оставляет /.well-known/ для ACME-челленджей. Второй - бэкапы и дампы. Без этого dev2.khovanskiy выложит database.sql.bak - и привет.

7. client_max_body_size - потолок тела запроса. По умолчанию 1m. Если у тебя загрузка файлов - подними точечно на нужном location, но НЕ ставь глобально гигабайты: бесконечный POST это и DoS, и переполнение диска во временных файлах.

Код: Выделить всё

client_max_body_size 1m;                  # глобально жёстко
location /api/upload/ {
    client_max_body_size 20m;             # послабление только там, где реально нужно
}
8. limit_except и отключение TRACE - ограничь методы. Эндпоинт, который только читает, не должен принимать POST/PUT/DELETE. А метод TRACE открывает Cross-Site Tracing - его надо глушить.

Код: Выделить всё

location /api/read/ {
    limit_except GET HEAD { deny all; }   # всё кроме GET/HEAD -> 403
}
# глобальный белый список методов (как в эталонном http_server.conf):
if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 405; }
TRACE сюда не попадает и получает 405. limit_except - декларативнее и безопаснее, чем простыни if. Помни общее правило: if внутри location - зло, используй его только для return/rewrite на верхнем уровне.

9. Сокрытие апстрим-ошибок. Когда бэкенд падает с 500 и стектрейсом, нельзя отдавать это клиенту - там пути, версии фреймворка, иногда SQL. Перехватывай и подменяй своей страницей.

Код: Выделить всё

proxy_intercept_errors on;
error_page 500 502 503 504 /errors/50x.html;
location = /errors/50x.html { internal; root /usr/share/nginx/html; }
proxy_intercept_errors on заставляет nginx ловить коды ошибок от апстрима и отдавать твой error_page вместо сырого ответа бэкенда. Связка с recursive_error_pages on и именованными @-локациями - ровно как в эталонном проекте.

10. Никакого autoindex на проде. autoindex on показывает листинг каталога - то есть отдаёт карту всех файлов любому. По умолчанию off, но его иногда включают для отладки и забывают. Проверь, что нигде нет лишнего autoindex on. В эталоне он явно autoindex off.

11. Правильный realip - иначе спуфинг X-Forwarded-For. Это пункт, который ломают чаще всего. Если перед nginx стоит CDN/балансировщик, то $remote_addr - это адрес прокси, НЕ клиента. Ты подключаешь realip, чтобы вытащить настоящий IP из X-Forwarded-For. Но если доверять этому заголовку от КОГО УГОДНО, клиент сам пришлёт X-Forwarded-For: 127.0.0.1 и обойдёт твой allow/rate-limit/гео.

Код: Выделить всё

set_real_ip_from 10.0.0.0/8;          # ТОЛЬКО реальные сети твоих прокси/CDN
set_real_ip_from 173.245.48.0/20;     # пример: диапазон Cloudflare
real_ip_header X-Forwarded-For;
real_ip_recursive on;                 # пройти цепочку справа налево, отбросить доверенные
Золотое правило: set_real_ip_from перечисляет ТОЛЬКО известные сети прокси. Никаких 0.0.0.0/0. real_ip_recursive on важен в цепочке нескольких прокси - он идёт по списку XFF и берёт первый недоверенный адрес как клиентский. Для L4-проксирования без HTTP-заголовков используй PROXY protocol. Ошибёшься тут - и твой rate limit по IP, гео-блокировки и логи становятся фикцией.

12. Анти-Slowloris таймауты. Slowloris - атака, где клиент открывает соединения и шлёт заголовки/тело по байту в час, держа воркеры занятыми. Лечится таймаутами на медленных стадиях.

Код: Выделить всё

client_header_timeout 10s;    # сколько ждём полный набор заголовков
client_body_timeout 10s;      # сколько ждём тело
send_timeout 10s;             # таймаут на отправку ответа клиенту
keepalive_timeout 30s;
Если клиент не уложился в client_header_timeout - соединение рвётся с 408. Это дешёвая и эффективная защита: реальному клиенту хватает секунд, ботнету - нет.

13. Rate limiting на чувствительных эндпоинтах. Логин, восстановление пароля, OTP - всё, что перебирают. В эталоне для этого отдельные зоны: app_login 5r/s, security_sensitive 1r/s.

Код: Выделить всё

limit_req_zone $binary_remote_addr zone=app_login:10m rate=5r/s;

location /api/login {
    limit_req zone=app_login burst=5 nodelay;
    proxy_pass http://backend_upstream;
}
Заметь $binary_remote_addr - после правильного realip это уже настоящий клиентский IP. burst=5 nodelay даёт небольшой запас на легитимные всплески, но режет перебор. На пункте 11 и 13 видно, как слои связаны: без верного realip rate limit бессмысленен.

14. Минимизация rewrite-правил. Это не только про читаемость. Связано напрямую со свежим CVE (следующая секция): уязвимость живёт именно в ngx_http_rewrite_module. Чем меньше у тебя сложных rewrite с PCRE-захватами и знаками вопроса в замене, тем меньше поверхность атаки. Где можно - заменяй rewrite на try_files, return, map. Это и быстрее, и безопаснее.

Nginx CVE 2026: гигиена версий, которую нельзя игнорировать

Конфиг можно вылизать идеально, но если бинарь дырявый - всё зря. 2026 выдался жарким. Запоминай эти четыре CVE и минимально безопасные версии.

CVE-2026-42945 - NGINX Rift. Главная боль года. Heap buffer overflow в ngx_http_rewrite_module. Затронуты ВСЕ версии от 0.6.27 (2008 год!) до 1.30.0 включительно. CVSS 4.0 - 9.2, критический. Механика: при rewrite-правиле, где безымянный PCRE-захват комбинируется со знаком вопроса в замене, флаг состояния is_args, выставленный на фазе подсчёта длины, протекает в фазу копирования - и ngx_escape_uri пишет за пределы буфера. Триггерится ОДНИМ запросом без аутентификации. Минимум - перезапуск воркера (DoS), при отключённом ASLR возможен и RCE. Эксплуатируется в дикой природе с мая 2026.
Лечение: обнови на nginx 1.30.1 (stable) или 1.31.0+ (mainline). freenginx и Angie выпустили свои патчи. И минимизируй rewrite-правила (пункт 14) как defense-in-depth.

CVE-2026-1642 - инъекция ответа от апстрима. При MITM между nginx и бэкендом атакующий может подмешать в ответ апстрима лишние заголовки/тело (response splitting). Защита - TLS до апстрима там, где канал не доверен, и обновление.

CVE-2026-40460 - HTTP/3 connection migration spoofing. Если у тебя включён QUIC/HTTP/3, баг в миграции соединения позволяет подделать адрес. Держи nginx с HTTP/3 строго обновлённым.

CVE-2026-8711 - heap overflow в njs js_fetch. Касается тех, кто использует njs с Fetch API. Обнови njs-модуль.

Вывод простой и жёсткий: держи nginx и ВСЕ динамические модули (njs, otel, brotli) обновлёнными. Сторонние модули обновляются отдельно от ядра - про них забывают. Проверяй текущую версию и сравнивай с минимально безопасной:

Код: Выделить всё

nginx -v
# nginx version: nginx/1.30.1   <- ниже 1.30.1 в stable-ветке = уязвим к Rift
nginx -V 2>&1 | tr ' ' '\n' | grep -i module    # какие модули вкомпилены
Nginx аудит: gixy, SSL Labs и автоматизация проверок

Глазами всё это не уследить. Поэтому финальный шаг - автоматический аудит. Три инструмента, которые должны стать рутиной.

gixy - статический анализатор nginx.conf. Изначально написан в Yandex, сейчас активно поддерживается форк gixy-ng (на PyPI). Делает 30+ проверок: SSRF через proxy_pass с переменной, HTTP response splitting, небезопасный add_header (который, кстати, ОБНУЛЯЕТ унаследованные заголовки на своём уровне - частая дыра!), проблемы с regex в location. Запуск:

Код: Выделить всё

pip install gixy-ng
gixy /etc/nginx/nginx.conf
Типичный вывод:

Код: Выделить всё

==================== Results ===================
>> Problem: [add_header_redefinition] Nested "add_header" drops parent headers.
Description: "add_header" replaces ALL inherited headers from the parent level.
Severity: HIGH
Pseudo config:
    server {
        add_header Strict-Transport-Security ...;
        location / {
            add_header X-Frame-Options SAMEORIGIN;   # тут HSTS ПОТЕРЯЛСЯ
        }
    }
==================== Summary ===================
Total issues: Unspecified: 0  Low: 1  Medium: 0  High: 1
Вот эта add_header_redefinition - реальная ловушка: добавил один add_header в location, и все security-заголовки с server-уровня там исчезли. gixy ловит это мгновенно. Встрой gixy в CI/CD: пусть пайплайн падает на High-находках до выката.

testssl.sh и SSL Labs - аудит TLS. testssl.sh гоняешь локально по любому порту, он проверит протоколы, шифры, известные крипто-баги (ROBOT, Heartbleed), цепочку, HSTS.

Код: Выделить всё

./testssl.sh --quiet --color 0 https://cyberlake.ru
А ssllabs.com/ssltest (тот самый nginx ssl labs тест) даёт публичную оценку A-F снаружи, как видит реальный клиент. Цель - A+. Если ниже A - смотри, что не так: чаще всего слабые шифры, отсутствие HSTS или старый протокол. Сверяй свой ssl-блок с Mozilla SSL Configuration Generator (профиль Intermediate для широкой совместимости, Modern если клиенты только свежие).

securityheaders.com - аудит заголовков ответа. Вбиваешь домен, получаешь оценку по CSP, HSTS, X-Content-Type-Options и компании. Быстрый способ убедиться, что секция из пунктов 2-3 реально доехала до браузера (и не съелась add_header-redefinition).

WAF-слой как усиление. Поверх всего этого ставится WAF - ModSecurity с набором правил OWASP CRS (Core Rule Set). Он ловит SQLi/XSS/path traversal на уровне сигнатур ещё до бэкенда. В эталонном app_redirects_security.conf есть упрощённые ручные фильтры (union select, ../, GLOBALS) - это бедняцкий WAF на регэкспах. Для серьёзного прода - полноценный ModSecurity+CRS, но помни про ложные срабатывания: гоняй сначала в DetectionOnly-режиме.

Мини-лаба: прогони свой конфиг через аудит

Повтори руками по шагам на тестовом стенде.
  • Шаг 1. Проверь версию: nginx -v. Если ниже 1.30.1 (stable) - ты уязвим к NGINX Rift. Запланируй обновление.
  • Шаг 2. Поставь анализатор: pip install gixy-ng, затем gixy /etc/nginx/nginx.conf. Выпиши все High и Medium находки.
  • Шаг 3. Найди в конфиге хоть один location с собственным add_header. Убедись через gixy или curl -I, что security-заголовки с server-уровня там не потерялись. Если потерялись - вынеси заголовки в include и подключи на каждом уровне, либо собери все add_header в одном месте.
  • Шаг 4. Добавь в server max_headers 100; client_header_timeout 10s; client_body_timeout 10s;. Проверь nginx -t и reload.
  • Шаг 5. Заблокируй dotfiles регэкспом из пункта 6. Проверь: curl -I http://localhost/.git/config должен вернуть 403.
  • Шаг 6. Прогони внешний аудит: testssl.sh по своему домену и ssllabs.com/ssltest. Добейся оценки A или A+. Затем securityheaders.com - закрой пробелы по заголовкам.
  • Шаг 7. Проверь realip: если перед тобой прокси, убедись, что set_real_ip_from содержит ТОЛЬКО сети прокси, а в логах $remote_addr показывает реальный клиентский IP, а не адрес балансировщика.
Контрольные вопросы
  • Почему set_real_ip_from 0.0.0.0/0 - это дыра, и что именно сможет подделать клиент?
  • В чём суть CVE-2026-42945, какие версии затронуты и до какой версии надо обновиться в stable-ветке?
  • Почему X-XSS-Protection в 2026 не нужен, и что его заменяет?
  • Что делает add_header внутри location с заголовками, заданными на server-уровне, и как gixy помогает это поймать?
Итог

Безопасность nginx - это слои, и каждый закрывается конкретной директивой: TLS 1.2/1.3 с пост-квантовыми группами, HSTS и CSP (без устаревшего X-XSS-Protection), server_tokens off, свежий max_headers против флуда, запрет dotfiles, потолки тела и таймауты против Slowloris, верный realip против спуфинга XFF, rate limit на чувствительных эндпоинтах и минимум rewrite. Поверх - гигиена версий: NGINX Rift и компания CVE 2026 лечатся обновлением на 1.30.1+. И не доверяй глазам - прогоняй конфиг через gixy, TLS через testssl.sh и SSL Labs, заголовки через securityheaders.com. Сделай этот чек-лист частью CI - и твой gateway перестанет быть одной забытой директивой от компрометации.
👍4 ❤️2 🔥1 😄 🤔2
Аватара пользователя
subd
Сообщения: 1
Зарегистрирован: 30 май 2026, 19:02

Re: Чек-лист безопасности, CVE 2026 и аудит конфигурации

Сообщение subd »

Дошло про realip только тут. У меня set_real_ip_from стоял на 0.0.0.0/0 потому что лень было выписывать сети cloudflare. То есть мой rate limit по сути ничего не ловил, любой слал X-Forwarded-For и обходил. Спасибо, побежал чинить.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
ken242
Сообщения: 1
Зарегистрирован: 14 май 2026, 10:38

Re: Чек-лист безопасности, CVE 2026 и аудит конфигурации

Сообщение ken242 »

Прогнал gixy-ng по своему конфигу и он сразу нашёл add_header redefinition в двух location. Реально все security-заголовки с server там пропадали, securityheaders показывал F на этих путях а я думал баг сайта. Поставил в CI на блок High.
👍2 ❤️2 🔥 😄 🤔
Ответить
← Предыдущая глава
Капстоун: собираем production-gateway с нуля

Все главы курса «Nginx профессионально: от первого конфига до API-gateway на OpenResty и Angie»

Поделиться темой: ✈ Telegram VK
Похожие запросы: Установка и первый конфиг nginxnginx в Docker

Вернуться в «Nginx профессионально: от первого конфига до API-gateway на OpenResty и Angie»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость