Обратный прокси (reverse proxy)
| Где стоит | перед серверами приложений, на стороне сервера |
|---|---|
| Функции | завершение TLS, балансировка, кэш, сжатие, маршрутизация, ограничение частоты |
| Популярные | nginx, HAProxy, Caddy, Traefik, Envoy |
| В облаке | балансировщики нагрузки, CDN, API-шлюзы |
| В Kubernetes | Ingress-контроллеры, Gateway API |
| Передача адреса клиента | X-Forwarded-For, Forwarded (RFC 7239) |
Обратный прокси (англ. reverse proxy) — сервер, который стоит перед одним или несколькими серверами приложений и принимает запросы клиентов вместо них. Клиент обращается к прокси, как к самому сайту, прокси пересылает запрос подходящему внутреннему серверу (бэкенду), получает ответ и возвращает его клиенту. Клиент ничего не знает о бэкендах: их количество, адреса и технологии скрыты.[1]
Обычный (прямой) прокси работает на стороне клиента и выходит в интернет от его имени; обратный — на стороне сервера и представляет сервис перед интернетом. Почти любой сайт работает за обратным прокси — nginx, Caddy, HAProxy, облачным балансировщиком или CDN.
Зачем нужен
| Функция | Что даёт |
|---|---|
| Завершение TLS | сертификаты и шифрование в одном месте; бэкенды работают по обычному HTTP во внутренней сети |
| Балансировка нагрузки | распределение запросов между несколькими экземплярами приложения, исключение упавших |
| Маршрутизация | /api → сервис API, / → фронтенд, admin.example.com → панель управления |
| Кэширование и сжатие | статика и повторяющиеся ответы отдаются без обращения к приложению |
| Защита | ограничение частоты запросов, размеров тел, фильтрация, скрытие внутренней структуры |
| Буферизация | медленные клиенты не занимают процессы приложения |
| Обновления без простоя | переключение трафика между версиями |
Сервер приложения на Python или Node.js обычно не стоит выставлять в интернет напрямую: он хуже справляется с тысячами медленных соединений, TLS, сжатием и атаками, чем специализированный прокси.
Пример: nginx
upstream app {
server 127.0.0.1:8001;
server 127.0.0.1:8002; # два экземпляра приложения
}
server {
listen 443 ssl;
http2 on;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location /static/ {
root /var/www/example; # статику отдаёт сам прокси
expires 30d;
}
location / {
proxy_pass http://app;
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_pass пересылает запросы группе upstream, а заголовки передают бэкенду сведения о настоящем клиенте.[2] В Caddy та же задача решается одной строкой reverse_proxy 127.0.0.1:8001 127.0.0.1:8002, а сертификат выпускается автоматически.
Адрес клиента и заголовки
Для бэкенда все запросы приходят с адреса прокси. Настоящий адрес клиента и исходный протокол передают заголовками X-Forwarded-For, X-Forwarded-Proto и X-Forwarded-Host или стандартным Forwarded (RFC 7239).[3] Бэкенд должен доверять этим заголовкам только от своего прокси: иначе клиент подделает X-Forwarded-For и обойдёт ограничения по IP. Фреймворки для этого имеют настройки доверенных прокси (например, --forwarded-allow-ips в Uvicorn для FastAPI).
Если бэкенд не знает, что исходный запрос был по HTTPS, он может строить ссылки и редиректы на http:// — классическая ошибка «бесконечного редиректа», которую решает X-Forwarded-Proto.
Балансировка
Алгоритмы распределения запросов: по кругу (round robin), по наименьшему числу соединений, по хешу адреса клиента или ключа (чтобы клиент попадал на один и тот же бэкенд). Прокси проверяет здоровье бэкендов — пассивно по ошибкам или активно запросами к /health — и исключает неисправные. Балансировку на уровне TCP (L4) и HTTP (L7) различают по тому, читает ли прокси содержимое запросов (см. Модель OSI).
Популярные решения
| Прокси | Особенности |
|---|---|
| nginx | веб-сервер и прокси, самый распространённый |
| HAProxy | специализированный балансировщик L4/L7, высокая производительность[4] |
| Caddy | автоматический HTTPS, простая конфигурация |
| Traefik | автоматическое обнаружение сервисов в Docker и Kubernetes[5] |
| Envoy | прокси для микросервисов, основа service mesh, динамическая конфигурация через API[6] |
В Kubernetes роль обратного прокси выполняют Ingress-контроллеры и реализации Gateway API (см. Service и Ingress), в облаке — управляемые балансировщики, а API-шлюзы добавляют аутентификацию, квоты и аналитику.
Типичные проблемы
- Ошибки 502 и 504 — прокси не смог получить ответ от бэкенда: приложение упало, недоступно или отвечает дольше тайм-аута (см. Коды состояния HTTP).
- WebSocket и потоковые ответы требуют настройки: передачи заголовков
UpgradeиConnection, отключения буферизации для потоковой генерации. - Ограничение размера тела (
client_max_body_sizeв nginx) — загрузка больших файлов падает с кодом 413. - Двойное сжатие или кэширование персональных ответов — кэш должен учитывать заголовки
Cache-ControlиVary.