gonzo proxy

прокси-сервер

Что такое обратный прокси: принципы работы, настройка и преимущества

Что такое обратный прокси-сервер

Интересная деталь про современный интернет. Когда вы заходите на тот же Amazon или смотрите сериал на Netflix, между вами и контентом работает сложная система реверс прокси серверов. Вы этого не видите, но она есть.

Что такое обратный прокси в техническом плане? Это программное обеспечение, которое встречает HTTP(S) запросы и решает, какому из backend-серверов их передать. Выглядит несложно, правда? Но внутри много интересного. Скажем, connection pooling — прокси создает постоянные соединения с backend-серверами и потом использует их для разных пользователей. Не нужно каждый раз устанавливать новое TCP соединение, экономия времени колоссальная.

А почему вообще "обратный"? Обычный прокси прячет клиента от сервера. Реверс прокси делает наоборот — прячет сервер от клиента. Для пользователя это выглядит как один сервер, хотя за кулисами может работать ферма из сотен машин.

Прямой и обратный прокси – в чем разница

Как работает прямой прокси? Заходите в параметры браузера, находите настройки прокси. Вписываете туда адрес сервера, скажем 192.168.1.100, указываете порт 8080. Готово. Теперь браузер будет ходить в интернет не напрямую, а через этот сервер. Для сайтов вы теперь находитесь по адресу прокси-сервера, а не по своему домашнему IP. Многие так обходят географические блокировки.

Обратный прокси работает с противоположной стороны. Набираете site.com, DNS возвращает IP 1.2.3.4. Но это не сервер с сайтом, а реверс прокси. Он принимает запрос, заглядывает в свои настройки. Видит правила маршрутизации. Все что начинается с /api/* отправляет на сервер A, картинки /images/* на CDN, остальное на сервер B.

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

Как работает обратный (реверс) прокси

Разберем по шагам реальный запрос. Вы набрали example.com/products/123. Браузер делает DNS lookup, получает 5.6.7.8. Это nginx, настроенный как обратный прокси. Отправляет туда GET /products/123 HTTP/1.1.

Nginx парсит запрос. Проверяет location блоки в конфиге. Находит совпадение с location /products. Там написано proxy_pass http://products_backend. Это upstream группа из трех серверов. Nginx выбирает сервер по round-robin (или другому алгоритму), скажем 10.0.0.2 порт 5000.

Открывает соединение к 10.0.0.2 на порт 5000 (или берет из keepalive пула). Модифицирует заголовки, добавляет X-Real-IP, X-Forwarded-For, меняет Host. Отправляет запрос. Получает ответ. Может его закэшировать, если настроено. Отдает клиенту.

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

Первая причина заключается в горизонтальном масштабировании. У вас Rails приложение. Один процесс обслуживает 50 req/sec. Надо 500 req/sec? Запускаете 10 процессов (можно на разных машинах), ставите перед ними nginx. Готово, без изменения кода.

Вторая причина связана со специализацией. Nginx эффективнее отдает статику, чем Ruby/Python/PHP. Настраиваете location /static с sendfile on, tcp_nopush on. Статика летает, приложение не дергается.

Третья причина касается единой точки для cross-cutting concerns. CORS заголовки, rate limiting, gzip сжатие, SSL терминация. Все на прокси. Backend'ы остаются простыми, занимаются только бизнес-логикой.

Основные задачи и преимущества реверс прокси

Балансировка нагрузки

Самый простой случай представляет собой round-robin. Запросы идут по кругу. Первый на server1, второй на server2, третий на server3, четвертый снова на server1. В nginx это выглядит так.

upstream backend {

    server 10.0.0.1:5000;

    server 10.0.0.2:5000;

    server 10.0.0.3:5000;

}

Но round-robin глупый. Не учитывает, что server1 может быть перегружен, пока server2 скучает. Поэтому есть least_conn. Новый запрос идет туда, где меньше активных соединений.

upstream backend {

    least_conn;

    server 10.0.0.1:5000;

    server 10.0.0.2:5000;

}

Еще круче использовать weight'ы. У вас server1 с 32GB RAM, server2 с 8GB. Логично слать на первый в 4 раза больше.

upstream backend {

    server 10.0.0.1:5000 weight=4;

    server 10.0.0.2:5000 weight=1;

}

Кэширование и ускорение доставки контента

Кэш в nginx представляет отдельную тему для диссертации. Базовая настройка выглядит следующим образом.

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

server {

    location / {

        proxy_cache my_cache;

        proxy_cache_valid 200 1h;

        proxy_cache_valid 404 1m;

        proxy_pass http://backend;

    }

}

Параметр levels=1:2 означает двухуровневую структуру папок. Иначе в одной директории будет миллион файлов. Файловая система загнется. 

keys_zone обозначает область в shared memory для хранения ключей кэша. 

max_size задает максимальный размер на диске.

Хитрость заключается в proxy_cache_use_stale. Backend упал? Nginx отдаст устаревший кэш.

proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;

HTTPS-шифрование и безопасность

SSL/TLS handshake жрет CPU как не в себя. RSA 2048 bit требует 0.5ms на handshake на современном CPU. При 1000 новых соединений в секунду половина ядра уйдет только на криптографию.

Обратный прокси https решает проблему. SSL терминируется на nginx, дальше идет plain HTTP.

server {

    listen 443 ssl http2;

    ssl_certificate /etc/ssl/certs/cert.pem;

    ssl_certificate_key /etc/ssl/private/key.pem;

    ssl_session_cache shared:SSL:10m;

    ssl_session_timeout 10m;

    

    location / {

        proxy_pass http://backend;

    }

}

Параметр ssl_session_cache критически важен. Без него каждое соединение требует полный handshake. С ним происходит session resumption, в 10 раз быстрее.

Маскирование внутренней инфраструктуры

Backend'ы могут быть на чем угодно. У вас legacy PHP4 приложение? Спрячьте за nginx, никто не узнает. API на Go, админка на Django, отчеты на .NET? Снаружи выглядит как единый сервис.

Headers можно подчищать. Backend отдает Server Apache/2.2.15 (CentOS)? Перезаписываете.

proxy_hide_header Server;

add_header Server "nginx";

А если работаете с требовательными к IP платформами, придется думать о качестве исходящих соединений. Тут помогают специализированные сервисы типа GonzoProxy. У них 20+ миллионов проверенных резидентских IP, которые не палятся как прокси. Особенно актуально для парсинга и мультиаккаунтинга.

В каких случаях стоит использовать reverse прокси

Для защиты веб-приложений

Rate limiting спасает от тупого брутфорса. Кто-то долбит POST /login? Ограничиваем.

limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

location /login {

    limit_req zone=login burst=5 nodelay;

    proxy_pass http://backend;

}

5 запросов в минуту на IP. Параметр burst=5 позволяет превысить, но не более 5 запросов. nodelay означает не задерживать, сразу 503 отдавать.

ModSecurity (WAF для nginx) фильтрует вообще все подряд. SQL injections, XSS, path traversal. Правила из коробки ловят 90% типовых атак. Но false positives бывают, надо тюнить.

Для масштабируемости и отказоустойчивости

Добавить сервер в nginx просто. Дописать одну строку и reload.

upstream backend {

    server 10.0.0.1:5000;

    server 10.0.0.2:5000;

    server 10.0.0.3:5000;  # новый

}

Никакого downtime. Nginx перечитает конфиг, старые воркеры доработают текущие запросы и умрут, новые начнут с новым конфигом.

Health checks в open source версии nginx примитивные. Только passive. Сервер не ответил max_fails раз подряд, исключается на fail_timeout секунд. В nginx Plus есть active health checks, но это платно.

Для оптимизации корпоративных сетей

Single entry point для всех сервисов. Вместо десятка A-записей в DNS получаете одну. Вместо десятка SSL сертификатов используете один wildcard. Вместо настройки файрвола для каждого сервиса настраиваете только для прокси.

Аутентификацию можно вынести на прокси. Используйте nginx с auth_request модулем.

location /internal/ {

    auth_request /auth;

    proxy_pass http://internal_service;

}

location = /auth {

    internal;

    proxy_pass http://auth_service/verify;

}

Кстати, для распределенных команд с кучей внешних интеграций качественные прокси типа GonzoProxy становятся мастхэв. Когда дергаете API партнеров по 1000 раз в минуту, residential IP с низким fraud score критичны.

Популярные решения

Nginx как обратный прокси

Event-driven архитектура nginx представляет его киллер фичу. Один worker process через epoll (Linux) или kqueue (BSD) обрабатывает тысячи соединений. Apache под нагрузкой форкает процессы и жрет гигабайты RAM. Nginx работает в 100 МБ.

Конфиг nginx читается как DSL. Вложенные блоки, наследование директив. location блоки матчатся по приоритету. Сначала точные (=), потом регулярки (~), потом префиксы.

location = /api/v1/status {  # точное совпадение, максимальный приоритет

    return 200 "OK";

}

location ~ \.php$ {  # регулярка, средний приоритет

    proxy_pass http://php_backend;

}

location /static/ {  # префикс, низкий приоритет

    root /var/www;

}

Apache в роли реверс прокси

Apache с mod_proxy работает иначе. Process-based модель (prefork MPM) или thread-based (worker MPM). Каждый запрос получает отдельный процесс/тред. Прожорливо по памяти, зато изоляция лучше.

Конфигурация через .htaccess представляет палку о двух концах. Удобно для shared хостинга, но performance hit на каждый запрос. Apache перечитывает .htaccess файлы по всему пути.

<VirtualHost *:80>

    ProxyPreserveHost On

    ProxyPass / http://127.0.0.1:8080/

    ProxyPassReverse / http://127.0.0.1:8080/

</VirtualHost>

ProxyPreserveHost важен. Без него backend получит Host 127.0.0.1 вместо оригинального домена.

Настройка обратного прокси в Windows-среде

IIS с ARR (Application Request Routing) является стандартом для Windows. GUI для настройки помогает тем, кто боится консоли. URL Rewrite module довольно мощный, регулярки поддерживает.

<system.webServer>

    <rewrite>

        <rules>

            <rule name="ReverseProxy" stopProcessing="true">

                <match url="(.*)" />

                <action type="Rewrite" url="http://backend/{R:1}" />

            </rule>

        </rules>

    </rewrite>

</system.webServer>

Проблема IIS заключается в производительности. На том же железе nginx обработает в 5-10 раз больше запросов.

Как настроить обратный прокси: пошаговый гайд

Предварительные требования (сервер, доступ, базовые знания)

VPS/VDS минимум составляет 1 CPU, 512 MB RAM для тестов. Для прода берите 2+ CPU, 2+ GB RAM. SSD обязателен если планируете кэширование. Random I/O у HDD убьет производительность.

Доступ нужен root или sudo. Без этого nginx не запустится на портах 80/443 (привилегированные). Можно на 8080 запустить, но тогда придется в URL порт указывать.

Команды, которые точно пригодятся. ss -tulpn покажет какие порты слушаются. journalctl -u nginx выведет логи systemd юнита. nginx -T покажет полную конфигурацию с учетом include. curl -I проверит заголовки ответа.

Настройка обратного прокси в Nginx (пример конфигурации)

Ставим nginx. Для Ubuntu/Debian используйте команду apt update && apt install -y nginx.

Для RHEL/CentOS/Rocky выполните yum install -y epel-release && yum install -y nginx.

Структура конфигов в Debian-based такая. Папка /etc/nginx/sites-available/ содержит конфиги, /etc/nginx/sites-enabled/ содержит симлинки на активные. В RHEL-based все конфиги лежат в /etc/nginx/conf.d/ с расширением .conf.

Пишем конфиг /etc/nginx/sites-available/myapp.

upstream app_backend {

    keepalive 32;  # держать 32 соединения открытыми

    server 127.0.0.1:3000 max_fails=2 fail_timeout=10s;

    server 127.0.0.1:3001 max_fails=2 fail_timeout=10s backup;  # backup сервер

}

server {

    listen 80;

    server_name myapp.com;

    

    # Размеры буферов важны для производительности

    client_body_buffer_size 128k;

    client_max_body_size 10m;

    proxy_buffer_size 4k;

    proxy_buffers 32 4k;

    

    location / {

        proxy_pass http://app_backend;

        proxy_http_version 1.1;  # для keepalive

        proxy_set_header Connection "";  # для keepalive

        

        # Передаем реальный IP клиента

        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 Host $host;

        

        # Таймауты

        proxy_connect_timeout 5s;

        proxy_send_timeout 60s;

        proxy_read_timeout 60s;

    }

    # Статику отдаем напрямую

    location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {

        expires 30d;

        add_header Cache-Control "public, immutable";

        root /var/www/static;

    }

}

Активируем командами ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/ и затем nginx -t && systemctl reload nginx.

Настройка реверс прокси для HTTPS

Certbot представляет самый простой способ получить бесплатный SSL от Let's Encrypt. Установите snap install --classic certbot.

Затем выполните certbot --nginx -d myapp.com -d www.myapp.com --email admin@myapp.com --agree-tos --no-eff-email.

Certbot сам допишет в конфиг SSL настройки. Но лучше подкрутить некоторые параметры.

# Современные протоколы и шифры

ssl_protocols TLSv1.2 TLSv1.3;

ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;

ssl_prefer_server_ciphers off;

# OCSP stapling ускоряет проверку сертификата

ssl_stapling on;

ssl_stapling_verify on;

# HTTP/2 для производительности

listen 443 ssl http2;

Проверка и тестирование работы

Тестируем конфиг перед применением. Это святое. Выполните nginx -t.

Если видите "syntax is ok", можно релоадить. "test failed" означает читайте что не так.

Проверяем, что слушается, командой ss -tulpn | grep nginx. Должны видеть порты 80 и 443.

curl для проверки работает так. Для HTTP используйте curl -I http://myapp.com. Для HTTPS выполните curl -I https://myapp.com. Следим за редиректами через curl -IL http://myapp.com. С кастомным заголовком проверяем curl -H "X-Test: 123" http://myapp.com.

Логи для дебага смотрите командой tail -f /var/log/nginx/access.log для общего лога. Ошибки видны в tail -f /var/log/nginx/error.log. Фильтруем по IP через tail -f /var/log/nginx/access.log | grep "192.168".

Если у вас есть вопрос, напишите нашему менеджеру

написать сейчас

FAQ

Реверс прокси vs VPN: в каких случаях реверс прокси решает задачу лучше?

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

Реверс прокси работает только с HTTP(S). Зато никакого клиента не надо. Работает в любом браузере. Можно тонко настроить. Этот URL публичный, этот требует пароль, этот доступен только из офисной сети.

Короче говоря, VPN используйте когда надо в сеть, реверс прокси когда надо к веб-сервису.

Как работает реверс прокси с WebSocket и чем это отличается от обычного HTTP?

WebSocket начинается как HTTP запрос с заголовками Upgrade websocket и Connection Upgrade. Сервер отвечает 101 Switching Protocols. Дальше по тому же TCP соединению идут фреймы WebSocket.

Для nginx критично прокинуть заголовки правильно.

location /ws/ {

    proxy_pass http://websocket_backend;

    proxy_http_version 1.1;

    proxy_set_header Upgrade $http_upgrade;

    proxy_set_header Connection "upgrade";

    proxy_read_timeout 3600s;  # держать соединение час

    proxy_send_timeout 3600s;

}

Без proxy_read_timeout nginx закроет соединение через 60 секунд по дефолту.

Какие заголовки безопасности должен добавлять обратный прокси?

Минимальный набор, который пройдет любой security audit, включает следующие заголовки.

# Защита от clickjacking

add_header X-Frame-Options "SAMEORIGIN" always;

# Отключаем MIME type sniffing

add_header X-Content-Type-Options "nosniff" always;

# XSS фильтр для старых браузеров

add_header X-XSS-Protection "1; mode=block" always;

# Контролируем передачу referrer

add_header Referrer-Policy "strict-origin-when-cross-origin" always;

# HTTPS only (HSTS)

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

# Content Security Policy самый мощный

add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline';" always;

Параметр always важно добавлять. Он добавляет заголовки даже к ответам с ошибками.

Sticky-sessions за реверс прокси: когда они нужны и как работают с JWT?

Sticky (они же persistent) sessions привязывают клиента к backend серверу. Классический случай представляют PHP сессии в файлах. Пользователь залогинился на server1, сессия записалась в /tmp/sess_abc123. Если следующий запрос уйдет на server2, там этого файла нет. Пользователь разлогинен.

Решения существуют разные. ip_hash в nginx обеспечивает привязку по IP клиента.

upstream backend {

    ip_hash;

    server srv1:80;

    server srv2:80;

}

Проблема в том, что за NAT все клиенты с одним IP.

Cookie-based работает надежнее (nginx Plus, или модуль sticky для open source).

upstream backend {

    server srv1:80;

    server srv2:80;

    sticky cookie srv_id expires=1h;

}

Переделать на stateless с JWT представляет лучшее решение. Токен содержит всю инфу, любой backend может обслужить. Sticky sessions не нужны. Но JWT больше по размеру. Каждый запрос тащит 1-2 КБ токена.

4 min

Поделиться

Готов к стабильному трафику
без банов?

Регистрируйся в GonzoProxy — без KYC, без лимитов,без сгорающего трафика.

👉 Подключиться в 1 клик

Вас так же может заинтересовать

gonzo proxy

прокси-сервер

4 min

Что такое обратный прокси: принципы работы, настройка и преимущества

gonzo proxy

прокси-сервер

6 min

Прокси для TikTok vs VPN: что выбрать для стабильной работы

gonzo proxy

прокси-сервер

5 min

Какие прокси считаются самыми быстрыми и надежными? Обзор популярных решений