Обновить
32K+

Nginx *

Веб-сервер и почтовый прокси-сервер

30,87
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Роутинг NGINX на предикатах для обработки API‑трафика без скриптов

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели6.1K

Типовую задачу проксирования трафика на базе заголовков и тела HTTP-запроса теперь можно решать напрямую с помощью предикатных локейшенов в NGINX.

До версии 1.31.5 для этого применяли тяжелые скрипты (медленно) и лабиринты из редиректов (неудобно). Теперь можно создать блоки location на базе любой переменной. В этом блоге разбираем методики чтения запроса и показываем примеры паттернов конфигурирования NGINX, которые вы можете применять для любого API или AI-трафика.

Читать далее

Новости

Zero Downtime Deploy: как обновлять production, не роняя пользователей

Уровень сложностиПростой
Время на прочтение4 мин
Охват и читатели6.7K

Представим ситуацию: у вас есть примитивное веб-приложение онлайн-редактора, которое уже набрало среднюю нагрузку под 100 RPS. И вы, как тимлид, дождались того самого дня, когда вся кропотливая работа над обновлением и бессонные ночи наконец завершились.

Настал момент релиза.

Вы радуетесь, что пользователи вашего приложения станут ещё счастливее. Они доверяют вашему сервису свои важные задачи, а вы расширите их возможности и сделаете их жизнь ещё немного лучше.

И вот момент.

3, 2, 1…

Релиз состоялся.

Вы рады. Ваши коллеги тоже рады. Всё прошло успешно.

Но спустя некоторое время к вам заходит начальство с максимально неприятным выражением лица...

Чем недовольно начальство?

Как я сделал и запустил ГрузоБот: Python, MAX API, SQLite и первые пользователи

Время на прочтение5 мин
Охват и читатели8.8K

Несколько месяцев назад я начал делать небольшой сервис для контейнерной логистики.

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

Так появился ГрузоБот это сервис для грузоотправителей, экспедиторов и перевозчиков, работающий через мессенджер MAX.

Сейчас проект уже находится в бета, но продакшене, поэтому хочу рассказать не столько о самом сервисе, сколько о том, что оказалось под капотом и с какими задачами пришлось столкнуться при разработке.

Читать далее

В логе адрес, с которого запрос не приходил. Его вписал сам клиент

Уровень сложностиСредний
Время на прочтение5 мин
Охват и читатели10K

Недавно разбирал блокировку у заказчика. Сработало правило «десять неудачных входов с одного адреса - бан». Забанило адрес, с которого никто ничего не делал. Через два часа забанило ещё один, потом ещё - и все из документационного диапазона, который в интернете не маршрутизируется.

Логика правила была в порядке. Просто в качестве адреса клиента оно брало то, что клиент про себя написал сам.

Читать далее

Публичное демо без регистрации: как показать живой мониторинг и не подставиться

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели10K

В Grafana есть режим публикации дашборда наружу: генерируется токен, по нему дашборд открывается без учётной записи, только на чтение. В интерфейсе это две галочки.

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

Читать далее

Дело о пропавшем IPv6

Уровень сложностиСложный
Время на прочтение7 мин
Охват и читатели6.5K

«Это ТСПУ РКН, поделать ничего нельзя» — а проблема три месяца ждала в консоли сервера

Время расследования · 2 дня Причин найдено · 3 Команд для победы · 1

Клиент — онлайн-СМИ застройщика федерального уровня, несколько десятков публикаций в день, своя редакция. С июня сайт периодически становился недоступен. Подрядчик, который ведёт техподдержку, прислал такое сообщение:

Читать далее

«Токен в ссылке украдут через Referer» — устарело пять лет назад. Куда он уходит теперь

Уровень сложностиСредний
Время на прочтение5 мин
Охват и читатели5.4K

Совет про токен в адресе страницы кочует из статьи в статью в одной и той же формулировке: не кладите его в URL, иначе он уедет в заголовке Referer на все сторонние ресурсы, которые подключает ваша страница.

Совет правильный по выводу и неправильный по обоснованию. Через Referer он давно никуда не уезжает. А вот сам токен из URL утекает — просто в других местах, и там его обычно никто не ищет.

Читать далее

Ваша Kubernetes-платформа всё ещё держится на nginx.ingress.kubernetes.io/*? У меня плохие новости

Время на прочтение5 мин
Охват и читатели11K

Статья посвящена завершению поддержки ingress-nginx и рассматривает это событие не просто как необходимость заменить один Kubernetes-компонент на другой, а как повод пересмотреть архитектуру маршрутизации в Kubernetes-платформе. В статье показано, как со временем простой Ingress превращается в набор NGINX-specific annotations и накопленного технического долга, который сложно поддерживать и объяснять. Так же разбираются возможности Gateway API, разделение ответственности между Platform-командой и разработчиками, а также подходы к миграции существующей инфраструктуры. Особое внимание уделяется аудиту текущих Ingress, постепенному внедрению новой модели и отказу от массовой миграции ради миграции. Основная идея статьи — не просто перенести сотни Ingress в HTTPRoute, а использовать изменения для построения более понятной, управляемой и масштабируемой Kubernetes-платформы.

Читать далее

Сертификат истёк, сайт лёг: как быстро вернуть HTTPS и починить автопродление

Уровень сложностиСредний
Время на прочтение16 мин
Охват и читатели10K

В рабочем чате: «Сайт не открывается, сертификат истёк», следом — скриншот с 502. Первый рефлекс — certbot renew и перезагрузить nginx. Иногда помогает. Иногда сайт после этого не поднимается совсем.

Дело в том, что «всё из-за сертификата» — это на самом деле две разные поломки с разными решениями: сертификат не продлился или продлился, но сервер отдаёт старое. В выдаче их валят в кучу, поэтому советы вроде «просто сделай certbot renew» либо не помогают, либо роняют сайт по-настоящему.

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

Найти свою поломку →

Работа с HTTP-заголовками запроса и ответа

Уровень сложностиПростой
Время на прочтение7 мин
Охват и читатели8.3K

Заголовки играют важную роль в работе веб-приложений. Они уточняют свойства запроса или ответа, управляют кэшированием, отвечают за безопасность и помогают отслеживать проблемы. В этой статье посмотрим, как можно управлять заголовками запросов и ответов в сервере Angie.

Читать далее

Автоматическая установка Wordpress на чистый сервер Ubuntu или Debian

Уровень сложностиПростой
Время на прочтение8 мин
Охват и читатели5.3K

Ставить WordPress руками — занятие на полтора часа: веб‑сервер, PHP с десятком расширений, база данных, конфиг Nginx, права на файлы, лимиты загрузки, сертификат. Я устал повторять этот ритуал и собрал скрипт, который делает всё сам и спрашивает только то, что действительно зависит от меня.

Итог, к которому мы придём: работающий сайт с настроенной админкой, ЧПУ‑ссылками, русской локализацией, при желании — с сертификатом Let’s Encrypt, phpMyAdmin и защитой от подбора паролей. Все доступы будут лежать в одном файле на сервере.

Читать далее

Как добавить свой модуль nginx в контрольной панели ispmanager

Уровень сложностиСложный
Время на прочтение12 мин
Охват и читатели6.3K

Многие знают и используют контрольную панель ispmanager для управления сервером, но, возможно, не всем известно, что функционал работы панели можно расширить самостоятельно и адаптировать для выполнения своих специфических задач.

В этой статье я хочу показать, как можно расширить возможности ispmanager — с помощью механизма плагинов. Они позволяют добавлять в панель собственный функционал: новые пункты меню, формы, отчёты, автоматизированные действия до и после стандартных операций, а также выводить данные из внешних систем прямо в интерфейс панели.

Предлагается доработать ispmanager, а именно:

Читать далее

Автоматизация wildcard-сертификатов

Уровень сложностиСредний
Время на прочтение16 мин
Охват и читатели7.6K

Рано или поздно в инфраструктуре появляется задача автоматического обновления TLS-сертификатов. В простом случае она решается установкой certbot: один домен, один сервер, cron-задание и дальше можно не вспоминать об этом годами.

Сложности начинаются, когда инфраструктура вырастает…

Читать далее

Ближайшие события

Работа с переменными в Angie

Уровень сложностиПростой
Время на прочтение6 мин
Охват и читатели6.8K

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

Читать далее

Use-As-Dictionary: как мы перестали отдавать один и тот же бандл по пять раз в день

Уровень сложностиПростой
Время на прочтение14 мин
Охват и читатели5.6K

У нас в среднем два релиза в день, бандл весит 7,76 МиБ после brotli, и половина клиентов качает его заново по несколько раз в сутки: хеш в имени файла поменялся - значит, кеш мимо. Compression Dictionary Transport (RFC 9842) позволяет объявить вчерашнюю сборку словарём для сегодняшней, и вместо 7,76 МиБ уезжает 15 КБ.

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

Читать далее

Приложение течёт, а утечки нет: как оптимизатор картинок Next.js съел 4-гигабайтный VPS

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели9.3K

История про то, как я три дня искал утечку памяти в Node-приложении, не нашёл — и был прав, что не нашёл. А ещё про то, что у каждого починенного пункта тут оказывался свой счёт: фикс памяти через месяц вернулся жалобой на скорость, а разбор скорости вскрыл третью проблему, о которой я не думал вовсе.

Читать далее

У nginx сжатие заголовков одностороннее

Уровень сложностиСложный
Время на прочтение24 мин
Охват и читатели11K

Стенд: один nginx, одно HTTP/3-соединение, четыре одинаковых запроса подряд. Меряем размер сжатого блока заголовков в обе стороны.

Ответ (nginx → клиент): 131, 131, 131, 131 байт. Запрос (клиент → nginx): 246, 8, 8, 8.

Ответ — константа: сколько запросов ни повтори, столько же байт. Запрос со второго раза схлопывается в тридцать раз. В HTTP/2 к тому же серверу — та же константа.

Между тем динамическая таблица HPACK и QPACK и есть половина смысла обоих протоколов: повторяющийся заголовок отправляется один раз, дальше идут ссылки на номер. Клиент ей пользуется. Сервер не пользуется ни в одном из двух — в HTTP/2 выставляет её размер в ноль, в HTTP/3 не открывает encoder-поток вовсе.

Разбор по фиксированным тегам: nginx 1.31.3, quic-go, Cloudflare quiche, ls-qpack, Google QUICHE. Две реализации из пяти таблицу всё-таки ведут. И приёмная половина — та, которой сервер сам не пользуется, но обязан обслуживать, — в мае принесла nginx use-after-free с оценкой 9.2.

Читать далее

nginx -s reload может не применить конфиг

Уровень сложностиСложный
Время на прочтение21 мин
Охват и читатели9.2K

Пока идёт бинарный апгрейд nginx, systemctl reload nginx не применяет конфиг так, как вы думаете: в лучшем случае к половине процессов сервера, в худшем — вообще никуда. Код возврата ноль в обоих случаях, в error.log пусто. Что именно у вас — решает одна строчка в юните: -s reload бьёт по pid-файлу, а он после USR2 принадлежит новому мастеру; kill -s HUP $MAINPID бьёт по старому, а тот конфиг вообще не перечитывает, и это описано в документации nginx — в разделе про обновление исполняемого файла, куда по другому поводу не заходят.

Это первая из пяти проверок. Я взял пять ходовых утверждений про reload в nginx, померил каждое на стенде — и получил результаты по обе стороны: три подтвердились, два развалились. Развалившиеся оказались интереснее.

Не работают ровно те страшилки, что про слушающий сокет: listen ... reuseport бесшовность не ломает (inode’ы сокетов до и после reload одни и те же — их держит мастер, а не воркер), паузы в accept при reload не существует вовсе (msleep(100) стоит ПЕРЕД QUIT), а значит и арифметика про переполнение backlog на reload — про нагрузку, а не про reload.

Зато подтвердилось то, о чём почти не пишут. keepalive_min_timeout оставляет уходящего воркера в живых, и тот обслуживает запросы, которых в момент reload ещё не существовало — по старому конфигу. А ngx_close_idle_connections не различает направление соединения, поэтому каждый reload сбрасывает пул keepalive к бэкендам — и с 1.29.7 это касается всех, у кого есть блок upstream: пул там включён по умолчанию, 32 соединения на воркер.

Правило из первой части — «соединение, открытое до reload, нового конфига не увидит» — приходится переформулировать: держится старого конфига не соединение, а процесс.

В конце — Traefik, у которого reload’а нет вовсе, и который умеет не применить конфиг своим способом: кольцевой буфер на одно сообщение и двухсекундный дроссель.

nginx release-1.31.3, traefik v3.7.10, все опыты в репозитории, запуск одной командой.

Читать далее

nginx не умеет reload. Он умеет fork

Уровень сложностиСложный
Время на прочтение17 мин
Охват и читатели13K

Деплой делает nginx -s reload. Команда возвращает ноль, nginx -T показывает новый конфиг, в error.log ровно одна строка — reconfiguring. А keep-alive соединение, открытое секундой раньше, в этот момент закрывается.

Само по себе это не ошибка: сервер вправе закрыть простаивающий keep-alive когда угодно. Ошибку даёт гонка — FIN уходит в тот момент, когда клиент уже записал в сокет следующий запрос. Идемпотентный он повторит, POST — нет.

Разбор по исходникам на фиксированных тегах: nginx release-1.31.3, httpd 2.4.68, traefik v3.7.10, плюс замер всех четырёх (с HAProxy) на одном стенде в одном прогоне. Выясняется, что мастер nginx конфиг не перечитывает вообще: он строит новый цикл целиком и форкает новых воркеров, а старым остаётся ровно то, что у них было. Apache приходит к тому же контракту через счётчик поколений, HAProxy — через замену процесса. А у одного из четырёх второй запрос в том же самом сокете возвращает уже новый конфиг — и причина не та, о которой вы подумали.

Внутри: почему документация nginx сама создаёт половину недоразумения; почему WebSocket и SSE не попадают под ngx_close_idle_connections и держат старого воркера сколько угодно долго, а HTTP/2 попадает всегда и получает GOAWAY; как сигнал родителя у Apache доезжает до конкретного соединения через пять звеньев; и таблица из двенадцати клеток, в которой четыре реализации расходятся ровно в одной.

Со стендом (один docker build, один docker run), полными выводами ps и тремя claims-*.tsv, где каждое утверждение о коде проверяется скриптом.

Читать далее

proxy_pass и fastcgi_pass — одна машина

Уровень сложностиСложный
Время на прочтение11 мин
Охват и читатели9.7K

У директив proxy_* и fastcgi_* совпадает 46 опций из 53 — буферизация, таймауты, кеш, next_upstream, с точностью до префикса и вплоть до значений по умолчанию. Два независимо написанных модуля так не сходятся.

Они и не независимы. Всё, чем proxy_pass отличается от fastcgi_pass, — девять указателей на функции в ngx_http_upstream_t. Соединение, таймауты, повторы, буферизация и отдача клиенту лежат в общих 7352 строках ngx_http_upstream.c, и восемь модулей — от proxy до свежего tunnel — дёргают один и тот же код.

Только контракт из этих девяти указателей врёт в обе стороны. Один из них, abort_request, ставят все восемь модулей — а машинерия не вызывает его ни разу: ноль вызовов во всём дереве и ни одного коммита с вызовом за всю публичную историю, с импорта 0.1.14 в январе 2005-го. Другой, pipe->input_filter, в контракте не объявлен вовсе — но обязателен, как только включена буферизация, и вызывается без проверки на NULL.

Разбираем по тегу release-1.31.3 со ссылками файл:строка: все места вызова каждого колбэка, включая тот, который разбирает заголовок не из сокета, а из файла кеша; матрица «кто какие указатели ставит» по всем восьми модулям; два сценария падения с разными стек-трейсами. Плюс свой рабочий upstream-модуль на 335 строк, собранный и проверенный curl'ом, и tunnel — самый маленький из восьми, приехавший в open source в апреле.

Читать далее
1
23 ...