Настройка обратного прокси на Nginx: пошаговое руководство с примерами конфигураций для 2026 | AdminWiki

Настройка обратного прокси на Nginx: пошаговое руководство с примерами конфигураций для 2026

02 августа 2026 11 мин. чтения

Обратный прокси на Nginx - это промежуточный сервер, который принимает запросы от клиентов и перенаправляет их на один или несколько внутренних серверов (бэкендов). Клиент взаимодействует только с прокси и не знает о существовании бэкендов. В отличие от прямого прокси, где клиент знает о прокси и использует его для доступа к внешним ресурсам, здесь инициатива исходит снаружи, а прокси защищает внутреннюю сеть.

Это руководство даёт готовую рабочую конфигурацию Nginx для проксирования HTTP и HTTPS-трафика. Вы скопируете приведённые примеры, адаптируете под свои домены и порты, и получите работающий reverse proxy за 10 минут. Все примеры проверены на Nginx 1.26 в 2026 году.

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

Что такое обратный прокси и зачем он нужен

Обратный прокси принимает HTTP/HTTPS-запрос на своём публичном интерфейсе, анализирует заголовки и URI, затем направляет запрос на бэкенд-сервер. Ответ от бэкенда возвращается клиенту через прокси. С точки зрения клиента, ответ пришёл от прокси-сервера.

Пять ключевых задач, которые решает эта архитектура:

  • Балансировка нагрузки. Прокси распределяет входящие запросы между пулом бэкендов через директиву upstream, предотвращая перегрузку одного сервера. Алгоритмы round-robin, least_conn и ip_hash позволяют выбрать стратегию под характер трафика.
  • SSL-терминация. Шифрование и расшифровка HTTPS выполняются на прокси, а общение с бэкендами идёт по HTTP. Это снижает нагрузку на приложения и упрощает управление сертификатами - они хранятся в одном месте.
  • Кэширование. Nginx сохраняет ответы бэкенда и отдаёт их повторно без обращения к приложению. Для API с редко меняющимися данными это даёт прирост скорости ответа в 10-50 раз.
  • Сокрытие бэкендов. Клиент не знает IP-адреса, порты и структуру внутренней сети. Все запросы идут на один публичный IP прокси-сервера.
  • Централизованное логирование и безопасность. Весь трафик проходит через одну точку, где можно применять rate limiting, фильтрацию по IP, Web Application Firewall и собирать единый access_log.

Если вы проектируете инфраструктуру с нуля, обратите внимание на готовые конфигурации Nginx для микросервисов 2026 - там разобрана маршрутизация через location, proxy_pass и rewrite без конфликтов правил.

Базовая настройка обратного прокси для HTTP

Минимальная конфигурация обратного прокси состоит из одного блока server с директивой proxy_pass. Nginx слушает порт 80, принимает запросы и передаёт их на бэкенд, который работает на localhost:3000.

Установка Nginx на Ubuntu/Debian выполняется двумя командами:

sudo apt update
sudo apt install nginx

После установки создайте файл конфигурации в /etc/nginx/sites-available/ с именем вашего домена или сервиса. Не редактируйте default - создайте отдельный файл, это упростит отладку и откат.

Пример конфигурации с пояснениями

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        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;
    }
}

Разбор директив:

  • listen 80; - Nginx принимает соединения на 80-м порту, стандартный порт HTTP.
  • server_name example.com; - директива определяет, для какого доменного имени применяется этот блок. Замените example.com на ваш домен.
  • location / {} - блок обрабатывает все URI, начинающиеся с /. Символ / после proxy_pass означает, что URI из запроса будет добавлен к адресу бэкенда.
  • proxy_pass http://127.0.0.1:3000; - адрес бэкенд-сервера. Трафик уходит на локальный порт 3000. Для удалённого сервера укажите его IP.
  • proxy_set_header Host $host; - передаёт оригинальный заголовок Host от клиента. Бэкенд видит домен, к которому обращался пользователь, а не 127.0.0.1.
  • proxy_set_header X-Real-IP $remote_addr; - передаёт реальный IP-адрес клиента. Подробнее об этом в разделе про передачу IP.
  • proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - добавляет IP клиента в цепочку прокси. Если перед Nginx стоит ещё один прокси, заголовок будет содержать оба адреса.
  • proxy_set_header X-Forwarded-Proto $scheme; - информирует бэкенд, по какому протоколу пришёл запрос (http или https). Критично для приложений, которые формируют абсолютные ссылки.

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

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Команда nginx -t проверяет конфигурацию на ошибки. Если вывод содержит «syntax is ok» и «test is successful», можно применять изменения через reload. Reload не разрывает активные соединения, в отличие от restart.

Базовая схема покрывает 80% задач проксирования. Если вам нужны готовые конфигурации для других сценариев - кеширование, защита API, SSL/TLS 1.3 - используйте проверенные конфигурации Nginx для стандартных задач 2026 с комментариями для быстрого внедрения.

Настройка обратного прокси с HTTPS и SSL-терминацией

HTTPS-прокси принимает зашифрованные соединения на порту 443, расшифровывает их и передаёт на бэкенд по HTTP. Для этого нужен SSL-сертификат. В production-средах используют бесплатные сертификаты от Let's Encrypt, которые обновляются автоматически.

Конфигурация для HTTPS добавляет директиву listen 443 ssl и пути к файлам сертификата и ключа:

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    location / {
        proxy_pass http://127.0.0.1:3000;
        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 https;
    }
}

server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

Ключевые моменты этой конфигурации:

  • http2 в директиве listen включает протокол HTTP/2, который ускоряет загрузку страниц за счёт мультиплексирования запросов в одном соединении.
  • ssl_protocols TLSv1.2 TLSv1.3; - разрешены только современные версии TLS. TLSv1.0 и TLSv1.1 отключены, так как содержат известные уязвимости.
  • X-Forwarded-Proto https; - жёстко задано значение https, так как клиент подключается по защищённому протоколу. Бэкенд, работающий по HTTP, будет знать, что оригинальный запрос был шифрованным.
  • Редирект с HTTP на HTTPS - второй блок server на 80-м порту возвращает 301-й редирект на тот же URI, но с https. Это гарантирует, что все клиенты перейдут на защищённое соединение.

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

Certbot - утилита от Electronic Frontier Foundation, которая получает сертификаты Let's Encrypt и автоматически обновляет их. Установка на Ubuntu:

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com

Certbot сам найдёт блоки server_name в конфигурации Nginx, запросит сертификат и пропишет пути к файлам. Для автоматического обновления добавьте задание в cron:

echo "0 3 * * * /usr/bin/certbot renew --quiet --post-hook 'systemctl reload nginx'" | sudo crontab -

Эта команда запускает проверку каждую ночь в 3:00. Если срок сертификата подходит к концу, Certbot обновит его и перезагрузит Nginx для применения новых файлов.

Если бэкенд тоже работает по HTTPS, измените proxy_pass на https://127.0.0.1:3000 и добавьте директиву proxy_ssl_verify off, если сертификат бэкенда самоподписанный. В production-среде лучше настроить взаимную проверку сертификатов, но это тема для отдельного руководства.

Для глубокого понимания SSL-терминации и балансировки с готовыми конфигурациями без HAProxy рекомендую руководство по Nginx Reverse Proxy в Linux, где разобраны решения ошибок 502, 413, 504 и дана таблица диагностики.

Проксирование по URI: маршрутизация на разные бэкенды

Один публичный домен может обслуживать несколько приложений, распределённых по разным портам или серверам. Nginx маршрутизирует запросы на основе URI через блоки location. Это стандартный паттерн для микросервисных архитектур, где фронтенд и API живут на разных бэкендах.

Пример конфигурации с тремя приложениями за одним доменом:

server {
    listen 80;
    server_name apps.example.com;

    location /app1/ {
        proxy_pass http://192.168.1.10:3000/;
        proxy_set_header Host $host;
    }

    location /app2/ {
        proxy_pass http://192.168.1.20:4000/;
        proxy_set_header Host $host;
    }

    location / {
        proxy_pass http://192.168.1.30:8080;
        proxy_set_header Host $host;
    }
}

Два критичных правила, которые предотвращают ошибки маршрутизации:

  1. Слеш в конце proxy_pass. Если URI в location заканчивается на /, то и proxy_pass должен заканчиваться на /. Тогда часть URI, соответствующая location, будет вырезана из запроса к бэкенду. Запрос /app1/page пойдёт на бэкенд как /page. Без слеша - как /app1/page.
  2. Порядок location. Nginx проверяет location в следующей последовательности: сначала точные совпадения (=), затем префиксные с наивысшим приоритетом, затем регулярные выражения (~ и ~*). Если два префиксных location подходят под запрос, выбирается самый длинный. Размещайте более специфичные location выше общих.

Обработка статических файлов и API

Типовой сценарий: одностраничное приложение (React, Vue) отдаёт статику, а запросы к /api проксируются на бэкенд. Конфигурация разделяет трафик по префиксу:

server {
    listen 80;
    server_name spa.example.com;
    root /var/www/spa/dist;
    index index.html;

    location /api/ {
        proxy_pass http://127.0.0.1:5000/api/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location / {
        try_files $uri $uri/ /index.html;
    }
}

Директива try_files пытается найти запрошенный файл на диске, затем папку, и если ничего не найдено - отдаёт index.html. Это нужно для клиентской маршрутизации SPA-фреймворков. Все запросы, не начинающиеся с /api/, обрабатываются как статика.

Для более сложных сценариев с балансировкой по GeoIP и заголовкам используйте руководство по интеллектуальной маршрутизации в Nginx с готовыми конфигурациями 2026 года.

Передача реального IP-адреса клиента

Когда запрос проходит через обратный прокси, бэкенд по умолчанию видит IP-адрес прокси, а не клиента. Это ломает логирование, геолокацию, ограничения по IP и любые механизмы, завязанные на адрес пользователя. Решение - заголовки X-Real-IP и X-Forwarded-For.

Nginx передаёт реальный IP через два заголовка:

  • X-Real-IP - содержит один IP-адрес клиента. Простой и поддерживается большинством приложений.
  • X-Forwarded-For - содержит цепочку IP-адресов, если запрос прошёл через несколько прокси. Формат: client, proxy1, proxy2. Бэкенд должен взять первый IP из списка, отбросив доверенные адреса прокси.

Конфигурация Nginx для передачи обоих заголовков:

location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

Переменная $remote_addr всегда содержит IP того, кто подключился к Nginx. Если перед Nginx нет других прокси, это IP клиента. $proxy_add_x_forwarded_for добавляет $remote_addr к существующему заголовку X-Forwarded-For, пришедшему от вышестоящего прокси.

Настройка на стороне бэкенда зависит от технологии. Для Apache используется модуль mod_remoteip с директивами RemoteIPHeader X-Forwarded-For и RemoteIPTrustedProxy 127.0.0.1. Для Node.js/Express - настройка app.set('trust proxy', true). Для PHP за FastCGI - директивы в пуле PHP-FPM или чтение $_SERVER['HTTP_X_REAL_IP'] в коде приложения.

Модуль ngx_http_realip_module

Этот модуль модифицирует IP-адрес клиента на уровне Nginx, заменяя $remote_addr значением из заголовка. Это нужно, когда за Nginx стоит ещё один прокси, и вы хотите, чтобы Nginx видел реальный IP для своих ACL и логирования.

set_real_ip_from 10.0.0.0/8;
set_real_ip_from 172.16.0.0/12;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

Директива set_real_ip_from задаёт доверенные сети, с которых Nginx принимает заголовок X-Forwarded-For. real_ip_recursive on включает рекурсивный поиск: Nginx проходит цепочку адресов справа налево и выбирает первый адрес, не принадлежащий доверенным сетям. Это правильный способ получить IP клиента, когда перед Nginx стоит CDN или балансировщик.

Типовые ошибки и их решение

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

ОшибкаПричинаРешение
502 Bad GatewayБэкенд не запущен, не слушает указанный порт, или брандмауэр блокирует соединениеПроверить статус бэкенда: systemctl status service. Проверить, что порт слушается: ss -tlnp | grep PORT. Проверить iptables/nftables.
504 Gateway TimeoutБэкенд не ответил за время, заданное в proxy_read_timeout (по умолчанию 60 секунд)Увеличить таймаут: proxy_read_timeout 120s. Оптимизировать медленный эндпоинт бэкенда.
WebSocket не работаетОтсутствуют заголовки Upgrade и Connection, необходимые для установки WebSocket-соединенияДобавить: proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";
Неправильный редиректБэкенд формирует Location с http:// и своим внутренним портом, а клиент должен получить https://Директива proxy_redirect http://backend:port https://domain; исправляет заголовок Location в ответе бэкенда.
Конфликт locationЗапрос попадает не в тот блок location из-за неправильного порядка или модификаторовИспользовать модификатор = для точных совпадений, ^~ для приоритетных префиксных. Проверить порядок через nginx -T | grep location.
413 Request Entity Too LargeРазмер тела запроса превышает client_max_body_size (по умолчанию 1 МБ)Увеличить лимит: client_max_body_size 100m; в блоке server или location.

Диагностика с помощью логов

Логи Nginx - основной инструмент поиска причин ошибок. Включите детальное логирование для конкретного location, чтобы видеть заголовки и тело запросов при отладке:

location /api/ {
    proxy_pass http://127.0.0.1:5000;
    access_log /var/log/nginx/api_access.log;
    error_log /var/log/nginx/api_error.log debug;
}

Уровень debug в error_log даёт максимально подробную информацию: какие заголовки передаются, какой бэкенд выбран, сколько времени заняло соединение. Не держите debug включённым на production-сервере постоянно - это генерирует гигабайты логов в сутки при активном трафике. Включайте точечно на время диагностики.

Для быстрого анализа ошибок используйте grep по кодам ответа в access_log:

grep ' 502 ' /var/log/nginx/access.log | tail -20
awk '$9 >= 500 {print $0}' /var/log/nginx/access.log | tail -20

Практические сценарии использования

Обратный прокси встраивается в типовые инфраструктурные паттерны. Три сценария, которые покрывают большинство случаев в работе DevOps-инженера.

Балансировка нагрузки через upstream. Когда один экземпляр приложения перестаёт справляться, запускают несколько копий и распределяют трафик между ними:

upstream backend_pool {
    least_conn;
    server 192.168.1.10:3000 max_fails=3 fail_timeout=30s;
    server 192.168.1.11:3000 max_fails=3 fail_timeout=30s;
    server 192.168.1.12:3000 backup;
}

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://backend_pool;
        proxy_set_header Host $host;
    }
}

least_conn выбирает сервер с наименьшим количеством активных соединений - оптимально для приложений с долгими запросами. max_fails=3 и fail_timeout=30s означают: после трёх неудачных попыток соединения сервер исключается из пула на 30 секунд. Сервер с флагом backup получает трафик только когда все основные серверы недоступны.

Кэширование ответов. Для API, которые возвращают редко меняющиеся данные, кэш на стороне Nginx снижает нагрузку на бэкенд в разы:

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m max_size=1g inactive=60m;

server {
    listen 80;
    server_name api.example.com;

    location /api/ {
        proxy_cache api_cache;
        proxy_cache_valid 200 10m;
        proxy_cache_valid 404 1m;
        proxy_cache_key "$scheme$request_method$host$request_uri";
        add_header X-Cache-Status $upstream_cache_status;
        proxy_pass http://127.0.0.1:5000;
    }
}

proxy_cache_path задаёт хранилище на диске. keys_zone выделяет 10 МБ оперативной памяти под индекс ключей, этого хватает примерно на 80 000 записей. Заголовок X-Cache-Status помогает отлаживать кэш: HIT означает попадание, MISS - промах, BYPASS - кэш отключён для этого запроса.

Nginx и Docker Compose

В среде Docker обратный прокси маршрутизирует трафик на контейнеры по их именам в сети Docker. Имя контейнера разрешается во внутренний IP автоматически. Пример docker-compose.yml с Nginx и двумя сервисами:

version: '3.8'
services:
  nginx:
    image: nginx:1.26
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - app1
      - app2
    networks:
      - proxy_net

  app1:
    image: myapp:v1
    networks:
      - proxy_net

  app2:
    image: myapp:v2
    networks:
      - proxy_net

networks:
  proxy_net:
    driver: bridge

Конфигурация Nginx для этой схемы использует имена контейнеров в proxy_pass:

server {
    listen 80;

    location /app1/ {
        proxy_pass http://app1:3000/;
    }

    location /app2/ {
        proxy_pass http://app2:4000/;
    }
}

Docker DNS автоматически разрешает app1 и app2 в IP-адреса контейнеров в сети proxy_net. При перезапуске контейнера IP меняется, но имя остаётся прежним - Nginx не нужно перезагружать.

Если вы работаете с модульной архитектурой Nginx и подключаете сторонние расширения, изучите полный гид по модулям Nginx - там разобрана сборка динамических расширений и рекомендации по безопасности для production-среды.

Для быстрого развёртывания инфраструктуры под обратный прокси удобно использовать облачные VDS, где можно гибко менять ресурсы по мере роста нагрузки. Timeweb Cloud предоставляет серверы, базы данных и Kubernetes в одном интерфейсе с поминутной тарификацией.

Поделиться:
Сохранить гайд? В закладки браузера