// Engineering Log
Прокси-серверы: Часть 2 — Nginx
Опубликовано 21.09.2026
// Быстрый маршрут
Эта статья относится к теме Серверы и инфраструктура.
Nginx — веб-сервер и обратный прокси с открытым исходным кодом (лицензия BSD). С 2019 года проектом владеет компания F5. Помимо бесплатной версии существует коммерческая Nginx Plus. Nginx раздаёт статические файлы, принимает HTTPS, проксирует запросы в приложения и распределяет нагрузку между несколькими серверами. В этой части разобрана его работа в роли обратного прокси.
Что умеет бесплатный nginx
- HTTP-прокси — передаёт запросы в приложения по HTTP, FastCGI (PHP-FPM), uwsgi, gRPC.
- TLS-терминация — принимает HTTPS и HTTP/2, в новых версиях и HTTP/3.
- Балансировка — алгоритмы round-robin (по умолчанию),
least_conn,ip_hash,hash, с весами серверов. - Пассивные проверки состояния — если сервер не ответил
max_failsраз заfail_timeout, nginx временно перестаёт отправлять на него запросы. - Кеширование ответов на диск (
proxy_cache). - Ограничение частоты запросов (
limit_req) и числа соединений (limit_conn). - WebSocket — проксируется с версии 1.3.13.
- TCP и UDP — модуль
stream, доступный с версии 1.9.0. Он входит в бесплатную версию; при сборке из исходников его включают флагом--with-stream, в официальных пакетах nginx.org он уже собран, в Debian и Ubuntu ставится пакетомlibnginx-mod-stream.
Nginx Plus добавляет активные проверки состояния серверов (nginx сам периодически запрашивает у них статус), изменение состава серверов через API без перезагрузки, расширенную статистику и техническую поддержку. В бесплатной версии активных проверок нет — это одна из причин выбрать HAProxy, если балансировка важнее всего.
Пример: сайт с HTTPS и WebSocket
Приложение слушает порт 3000 на том же сервере, сертификат выпущен Let’s Encrypt. Конфигурация размещается в /etc/nginx/conf.d/example.ru.conf:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream app {
server 127.0.0.1:3000;
}
server {
listen 80;
server_name example.ru;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
http2 on;
server_name example.ru;
ssl_certificate /etc/letsencrypt/live/example.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.ru/privkey.pem;
client_max_body_size 20m;
location / {
proxy_pass http://app;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 1h;
}
}Что здесь важно:
- блок
mapвыбирает значение заголовкаConnection:upgradeдля WebSocket иcloseдля обычных запросов. ЗаголовкиUpgradeиConnectionне передаются приложению автоматически, их нужно указать явно; - директива
http2 onпоявилась в версии 1.25.1; в более старых версиях HTTP/2 включают параметромlisten 443 ssl http2; proxy_http_version 1.1нужна для WebSocket в версиях nginx до 1.29.7, в которых по умолчанию к приложению используется HTTP/1.0;proxy_read_timeout 1hне даёт nginx закрывать WebSocket-соединение: по умолчанию оно разрывается, если приложение ничего не передаёт 60 секунд.
Перед применением конфигурацию проверяют и затем перечитывают без остановки сервера:
nginx -t && systemctl reload nginxБалансировка между несколькими серверами
upstream app {
least_conn;
server 10.0.0.11:3000 max_fails=3 fail_timeout=30s;
server 10.0.0.12:3000 max_fails=3 fail_timeout=30s;
server 10.0.0.13:3000 backup;
}least_conn отправляет запрос на сервер с наименьшим числом активных соединений. Сервер с тремя неудачами за 30 секунд исключается на те же 30 секунд. Сервер backup получает запросы, только когда основные недоступны. Если приложение хранит сессии в памяти процесса, пользователя нужно закреплять за одним сервером (ip_hash или hash $cookie_...), а лучше вынести сессии в общее хранилище, например Redis.
Ограничение частоты запросов
# в контексте http
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
# в server
location /login {
limit_req zone=login burst=5 nodelay;
limit_req_status 429;
proxy_pass http://app;
}С одного IP-адреса допускается пять запросов в минуту к странице входа с кратковременным запасом ещё в пять. Остальные получают ответ 429. Такое правило заметно затрудняет подбор паролей.
Кеширование ответов приложения
Если приложение отдаёт одинаковые ответы разным посетителям, например каталог или публичный API, nginx может хранить их на диске и не обращаться к приложению при каждом запросе:
# в контексте http
proxy_cache_path /var/cache/nginx/app levels=1:2 keys_zone=app_cache:10m
max_size=1g inactive=60m use_temp_path=off;
# в server
location /catalog/ {
proxy_cache app_cache;
proxy_cache_valid 200 301 10m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://app;
}proxy_cache_use_stale позволяет отдавать устаревшую копию, пока приложение недоступно или обновляет ответ. Заголовок X-Cache-Status показывает, пришёл ли ответ из кеша (HIT) или от приложения (MISS). По умолчанию nginx не кеширует ответы, в которых приложение устанавливает cookie или запрещает кеширование заголовками Cache-Control. Это защищает от ситуации, когда личная страница одного пользователя попадает к другому. Отключать эти проверки стоит только при полной уверенности, что ответ не содержит персональных данных.
Минимальная защита
server_tokens off;убирает номер версии nginx из заголовков и страниц ошибок;- доступ к служебным адресам ограничивают директивами
allowиdenyили паролем (auth_basic); - неизвестные домены лучше не обслуживать сайтом по умолчанию: отдельный блок
serverсlisten 443 ssl default_serverиreturn 444;закрывает соединение для запросов с чужими или пустыми именами. Для такого блока всё равно нужен сертификат, например самоподписанный, или директиваssl_reject_handshake on;(с версии 1.19.4).
TCP-прокси: модуль stream
Блок stream располагается на верхнем уровне nginx.conf, рядом с блоком http, а не внутри него. Пример — доступ к PostgreSQL с резервным сервером:
stream {
upstream postgres {
server 10.0.0.21:5432;
server 10.0.0.22:5432 backup;
}
server {
listen 5432;
proxy_pass postgres;
proxy_connect_timeout 5s;
proxy_timeout 10m;
}
}UDP проксируется так же, в директиве listen добавляется параметр udp. Модуль ssl_preread позволяет в режиме stream прочитать имя сайта из TLS-рукопожатия и направить соединение на нужный сервер, не расшифровывая его. Так на одном порту 443 можно обслуживать несколько сервисов со своими сертификатами.
Типичные ошибки
- Не передан
Host. По умолчанию nginx подставляет в заголовокHostимя изproxy_pass(например,app), и приложение с несколькими доменами отвечает не тем сайтом. Нужна строкаproxy_set_header Host $host. - Не передан
X-Forwarded-Proto. Приложение считает, что его открыли по HTTP, и бесконечно перенаправляет на HTTPS или формирует ссылки сhttp://. - Слеш в конце
proxy_pass.proxy_pass http://app/;вlocation /api/отрезает/api/от пути запроса, аproxy_pass http://app;передаёт путь целиком. Это частая причина ошибок 404 после настройки. - Буферизация потоковых ответов. По умолчанию nginx буферизует ответ приложения. Для потоковой передачи (Server-Sent Events, постепенный вывод ответов нейросетей) буферизацию отключают:
proxy_buffering off;в нужномlocationили заголовкомX-Accel-Buffering: noиз приложения. - Ошибка 413. По умолчанию размер тела запроса ограничен 1 МБ, и загрузка файлов прерывается. Лимит задаёт
client_max_body_size. - Ошибка 504. Приложение отвечает дольше 60 секунд — стандартного значения
proxy_read_timeout. Время увеличивают для конкретногоlocation, а не для всего сайта. - Неверный адрес клиента за вторым прокси. Если перед nginx стоит ещё один прокси или CDN, настоящий адрес восстанавливают модулем
realip:set_real_ip_fromс адресами этого прокси иreal_ip_header X-Forwarded-For.
Форки: freenginx и Angie
- freenginx — форк, который в феврале 2024 года основал Максим Дунин, один из ведущих разработчиков nginx, после разногласий с F5 о политике безопасности. Проект стремится сохранить полную совместимость с nginx.
- Angie — форк, созданный бывшими разработчиками nginx; кодовая база отделена от nginx 1.23.1, лицензия BSD. Разработчик — российская компания «Веб-Сервер». Angie добавляет встроенную статистику, активные проверки состояния серверов и другие возможности, которых нет в бесплатном nginx. Коммерческая версия Angie PRO включена в реестр российского программного обеспечения.
Конфигурации nginx в большинстве случаев переносятся на оба форка без изменений.
Когда выбирать nginx
Nginx — хороший выбор по умолчанию, если нужно опубликовать сайт или приложение: он одновременно раздаёт статические файлы, принимает HTTPS и проксирует запросы, а примеры конфигураций есть почти для любого программного обеспечения. Если основная задача — балансировка между многими серверами с активными проверками, подробной статистикой и тонкими правилами для TCP, удобнее HAProxy.
// Похожая задача
Если у вас похожая ситуация
Эта статья относится к одной из рабочих тем. Можно продолжить чтение по теме, перейти на главную, чтобы понять, чем я занимаюсь, или сразу открыть услуги.
Тема статьи
Серверы и инфраструктура
VPS, Linux, веб-стек, миграции, хостинг, базы данных и базовая эксплуатация.
Часто с этим приходят
- Перенести сайт или сервис на новый сервер
- Настроить Linux, Nginx, базу данных и бэкапы
- Разобраться, почему всё работает нестабильно
// Следующий шаг
Если вам нужна не только статья, а помощь по этой теме, удобнее сразу перейти в услугу. Главная и подборка материалов остаются рядом.
Открыть услуги// Contact
Нужна помощь?
Свяжись со мной и я помогу решить проблему
Написать в TelegramОтвечаю в течение рабочего дня (03:00–13:00 GMT)
Или оставьте заявку здесь:
// Related