1. 1
  2. 2
  3. 3
  4. 4
  5. 5

# теория · шаг 3 из 5

Что дальше и как не отстать

Коротко

Курс кончается, nginx - нет. За рамками остались внешние модули (brotli, WAF, geoip2), возможности коммерческой версии, серьёзная наблюдаемость и генераторы конфигов вроде Ingress. Не отставать помогает одна привычка: раз в квартал читать Feature и Change в CHANGES, а Security - сразу. Главное же, что стоит унести, - не набор директив, а порядок фаз: почти любое «почему оно так себя ведёт» решается тем, что ты мысленно проводишь запрос по фазам и смотришь, какая директива на каком уровне выиграла.

Нужен только план на ближайшую неделю - листай до второго разбора.

Конфиг из статьи, которая до сих пор в первой тройке поиска. Сколько здесь строк из семи сегодня не нужны или вредны?

/etc/nginx/conf.d/shop.local.confhttp server
listen 443 ssl http2;
ssl_stapling on;
ssl_stapling_verify on;

location /api/ {
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    add_header X-Frame-Options SAMEORIGIN;
    proxy_pass http://app:8000;
}

Четыре из семи. И самое неприятное - последняя строка, которая молча выбрасывает все заголовки безопасности уровня выше.

На что это похоже

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

Поэтому вопрос «что читать дальше» правильнее заменить на «как заметить, что то, что я знаю, изменилось».

Механизм: способ думать, который остаётся

выбор server: адрес, порт, имя rewrite на уровне server выбор location rewrite в location лимиты доступ и авторизация try_files и контент фильтры ответа return бьёт всё, что ниже
Восемь строк, которыми объясняется почти любое поведение конфига

Правило

Раз в квартал открывать nginx.org/en/CHANGES и читать строки Feature и Change - их немного и они короткие. Строки Security читать сразу, как выходят. Директиву из чужой статьи проверять по nginx.org/en/docs: там у каждой указано, с какой версии она есть и что означает по умолчанию.

Что успело измениться в разобранном материале, пока курс писался:

изменение версия
proxy_http_version по умолчанию 1.1, keepalive в upstream включён сам 1.29.7
listen ... http2 устарел, появилась директива http2 1.25.1
виртуальные серверы в stream и директива pass 1.25.5
add_header_inherit - управление наследованием заголовков 1.29.3
max_headers, модуль tunnel, least_time для всех 1.29.8 и 1.31.0
njs 1.0 с переходом на QuickJS июнь 2026

Разбор: что не так с конфигом из статьи

Разберём крючок построчно - каждая строка уже встречалась в курсе.

listen 443 ssl http2; - параметр http2 у listen объявлен устаревшим (1.25.1). Работать он будет, но относится к сокету, а не к блоку: замер в десятом разделе показал, что соседний блок с http2 off всё равно отдаёт HTTP/2. Правильно - директива http2 on; внутри своего server.

ssl_stapling on; с сертификатом Let's Encrypt - мёртвая строка. Они убрали OCSP-ссылку из сертификатов в 2025 году, и nginx честно об этом пишет:

↳  вывод/var/log/nginx/error.log
[warn] "ssl_stapling" ignored, no OCSP responder URL in the certificate

proxy_http_version 1.1; и proxy_set_header Connection ""; - с 1.29.7 не нужны: версия 1.1 стала умолчанием, Connection: close бэкенду больше не шлётся. Но помни замер из восьмого раздела: keepalive к бэкенду работает только через группу upstream - шесть запросов на прямой адрес дали шесть соединений, те же шесть через группу - одно.

add_header X-Frame-Options SAMEORIGIN; - самая дорогая строка. Она заменяет унаследованный набор заголовков целиком: HSTS, nosniff и всё остальное с уровня server в ответах этого location исчезнут. Лечится повтором или add_header_inherit merge; (1.29.3).

Четыре строки удаляются целиком: ssl_stapling on;, ssl_stapling_verify on; (бессмысленна без stapling), proxy_http_version 1.1; и proxy_set_header Connection "";. Остаются нужными три, но две из них - с правкой: listen 443 ssl; (без устаревшего http2, его включают директивой http2 on;), add_header X-Frame-Optionsalways и не ломая наследование) и сам proxy_pass.

Разбор: пять минут на своём сервере

Список, который окупается сразу и опирается только на пройденное:

$  команда
nginx -T | less                                  # что реально применено
curl -sI https://твой-сайт/.env | head -1        # 12-й раздел
curl -sI https://твой-сайт/.git/config | head -1
curl -sI https://твой-сайт/assets/любой.js | grep -iE 'cache|content-type|nosniff'
grep -c worker_shutdown_timeout /etc/nginx/nginx.conf
grep -A3 postrotate /etc/logrotate.d/nginx

Что должно получиться: собранный конфиг читается сверху вниз и в нём нет строк, которые некому объяснить; служебные пути отдают 403 или 404, а не содержимое; у ассета есть и кеш, и nosniff - то есть наследование не съело заголовок; worker_shutdown_timeout задан; в ротации есть nginx -s reopen.

Дальше - три метрики из пятнадцатого раздела: доля 5xx, 95-й процентиль $upstream_response_time, число 499. Плюс расхождение accepts и handled в stub_status: оно ловит то, чего в кодах ответа не видно вовсе.

Что ломается без этого

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

Копирование целыми блоками. Конфиг из статьи приносит с собой чужие умолчания и чужие компромиссы: add_header, стирающий твои заголовки; proxy_read_timeout, подобранный под чужой бэкенд; лимит с ключом $http_x_forwarded_for, который подделывается заголовком (двенадцатый раздел). Брать надо строку и понимание, а не блок.

Модуль, которого нет в сборке. Половина «у нас это не работает» объясняется тем, что директива есть в документации и отсутствует в твоём бинарнике. Первым делом - nginx -V, а не поиск опечатки.

Зачем это в работе

Чего в курсе не было и куда идти дальше, когда понадобится. Внешние модули: brotli, ModSecurity и другие WAF, ngx_http_geoip2, VTS-статистика - ставятся пакетом или собираются, и у каждого своя судьба при обновлении nginx. Коммерческая версия: активные проверки здоровья, API управления апстримами, детальная статистика, tunnel_allow_upstream - половина статей в интернете описывает именно её. Наблюдаемость по-взрослому: экспорт в Prometheus, трассировка сквозь nginx и приложение ($request_id - только начало), алерты по процентилям. Мир вокруг: Kubernetes Ingress генерирует конфиги за тебя, и умение прочитать сгенерированное - ровно то, что даёт этот курс.

А если что-то не объясняется - есть nginx -T, error_log и curl. Три инструмента, которыми чинится почти всё.

Теперь сам

Ты открыл CHANGES и видишь три строки:

↳  выводnginx.org/en/CHANGES
    *) Security: a buffer overflow might occur in a worker process.
    *) Feature: the "least_time" directive is now available in all builds.
    *) Change: now nginx uses HTTP/1.1 to connect to upstreams by default.

Какую читать сейчас, какую можно отложить и какая требует правки конфига?

Ответ: Security читается немедленно и означает обновление - это не «новая возможность», а закрытая дыра в работающем сервере. Feature можно отложить: она ничего не ломает, а лишь разрешает то, чего раньше не было. Change - единственная, из-за которой стоит открыть свой конфиг, и правка обычно обратная привычной: не дописать строку, а убрать ставшую лишней (proxy_http_version 1.1;). Опасность Change в том, что она меняет поведение конфига, который ты не трогал, - поэтому её и читают в квартальном обходе, а не когда что-то сломалось.

Главное

За рамками курса остались внешние модули, коммерческая версия, серьёзная наблюдаемость и генераторы конфигов - база для них у тебя теперь есть. Не отставать помогает одна привычка: Security в CHANGES читать сразу, Feature и Change - раз в квартал, причём именно Change меняет поведение конфига, который ты не трогал. Чужой конфиг из статьи разбирай построчно: listen ... http2 устарел, ssl_stapling с Let's Encrypt мёртв, proxy_http_version 1.1 не нужен с 1.29.7, а лишний add_header в location выбрасывает все унаследованные заголовки. И главное - запрос идёт по фазам: выбор server → rewrite → выбор location → rewrite → лимиты → доступ → контент → фильтры, и почти любое «почему так» объясняется тем, какая директива на каком уровне выиграла.

Комментарии

Пока нет комментариев. Будь первым!

Оставить комментарий

Комментарий появится после проверки. Email не публикуется. Войти, чтобы не вводить имя каждый раз.