how to create a reverse proxy

Обзор

Узнайте, как настроить обратный прокси с помощью HAProxy на VPS, чтобы скрыть реальный IP-адрес сервера, повысить производительность и защитить свои приложения от третьих лиц. Как создать обратный прокси с HAProxy, чтобы скрыть реальный IP сервера происхождения?


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

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

Короче говоря, обратный прокси – это тихая рабочая лошадка, которая обеспечивает бесперебойную работу, пока ваше происхождение остается приватным


Обратный прокси с HAProxy: Как это работает

HAProxy – это мощный L4/L7 прокси и балансировщик нагрузки. Клиентские запросы сначала попадают на HAProxy, где

  • TLS (HTTPS) может быть завершен.
  • Добавляются такие заголовки, как X-Forwarded-For, X-Forwarded-Proto, и X-Forwarded-Host.
  • Трафик направляется на бэкенды по имени хоста, пути или по пользовательским правилам.
  • Доступны проверки работоспособности, автоматическое восстановление после отказа, ограничения скорости, сжатие, легкое кэширование, WebSockets и gRPC pass-through.
  • Подробные журналы и страница статистики в реальном времени обеспечивают наблюдательность.

Итог: HAProxy упрощает вашу архитектуру, повышает безопасность и производительность, а также делает масштабирование простым


Плюсы и минусы HAProxy

Плюсы (почему HAProxy сияет)

  • Высокая производительность и низкие накладные расходы (управляемые событиями, многопоточные).
  • Интеллектуальные возможности L4 + L7 (TCP/SNI passthrough или полная HTTP-маршрутизация/переписывание).
  • Надежная балансировка нагрузки и проверка работоспособности (round-robin, leastconn, hashing; активные проверки, обход отказа).
  • Функции безопасности (завершение TLS, HSTS, ACL, ограничение скорости с помощью stick-таблиц, разрешение/запрет IP-адресов).
  • Наблюдаемость (богатые журналы, живая статистика socket/page; доступны экспортеры Prometheus).
  • Надежность (изящная перезагрузка с нулевым временем простоя; проверено в бою).
  • Малая занимаемая площадь (работает практически везде: Linux/BSD/контейнеры).

Минусы (компромиссы)

  • Кривая обучения (мощная, но многословная конфигурация).
  • Автоматизация сертификации не встроена (используйте Certbot/lego или Data Plane API).
  • Ручное обнаружение сервисов по умолчанию (для динамических бэкендов нужны шаблоны/API).
  • Ограниченное встроенное кэширование/статический сервис (при необходимости используйте CDN/Varnish/Nginx).
  • Отсутствие встроенного WAF (используйте отдельный WAF или HAProxy Enterprise).
  • Сложные переписывания могут стать многословными.
  • Ограниченная поддержка Windows (лучше всего использовать Linux/BSD).

Что вам понадобится

  • VPS/публичный сервер для HAProxy (обратный прокси).
  • Ваш оригинальный сервер (например, 10.0.0.10:8080).
  • Домен (например, example.com) с DNS A/AAA, указывающий на публичный IP сервера HAProxy.

Совет по конфиденциальности: Чтобы действительно скрыть IP-адрес происхождения, убедитесь, что он недоступен для публичного доступа, закройте его брандмауэром, чтобы он принимал трафик только от HAProxy-сервера, и избегайте DNS-записей, которые раскрывают происхождение


Шаг 1 – Установите HAProxy

Ubuntu/Debian

sudo apt update
sudo apt install -y haproxy

RHEL/Alma/Rocky

sudo dnf install -y haproxy

Шаг 2 – Получение сертификата TLS (Let’s Encrypt)

Мы позволим Certbot получить сертификат и свяжем его для HAProxy

Установите certbot и получите сертификат (одноразовый)

# Ubuntu/Debian
sudo apt install -y certbot
sudo certbot certonly --standalone -d example.com --agree-tos -m you@example.com --non-interactive

Создайте PEM-бандл HAProxy (fullchain + privkey)

sudo mkdir -p /etc/haproxy/certs
sudo bash -c 'cat /etc/letsencrypt/live/example.com/fullchain.pem 
              /etc/letsencrypt/live/example.com/privkey.pem 
              > /etc/haproxy/certs/example.com.pem'
sudo chmod 600 /etc/haproxy/certs/example.com.pem

Автоматическое восстановление и перезагрузка HAProxy при обновлении

sudo bash -c 'cat >/etc/letsencrypt/renewal-hooks/deploy/haproxy.sh' <<'EOF'
#!/usr/bin/env bash
cat /etc/letsencrypt/live/example.com/fullchain.pem 
    /etc/letsencrypt/live/example.com/privkey.pem 
    > /etc/haproxy/certs/example.com.pem
systemctl reload haproxy
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/haproxy.sh

Шаг 3 – Минимальная, готовая к производству конфигурация HAProxy (HTTPS + редирект)

Замените example.com и IP/порт вашего бэкенда, где отмечено.

# /etc/haproxy/haproxy.cfg
global
  log /dev/log local0
  maxconn 50000
  daemon

defaults
  log global
  mode http
  option httplog
  timeout connect 5s
  timeout client  60s
  timeout server  60s
  http-reuse safe

# Frontend: listen on 80/443, redirect to HTTPS, route ACME and app traffic
frontend fe_https
  bind :80
  bind :443 ssl crt /etc/haproxy/certs/example.com.pem alpn h2,http/1.1

  # Force HTTPS
  http-request redirect scheme https unless { ssl_fc }

  # Basic security header
  http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" if { ssl_fc }

  # Preserve client info for your app
  option forwardfor header X-Forwarded-For
  http-request set-header X-Forwarded-Proto https if { ssl_fc }
  http-request set-header X-Forwarded-Host %[req.hdr(host)]

  # Simple rate cap: 100 requests / 10s per IP
  stick-table type ip size 100k expire 10m store http_req_rate(10s)
  http-request track-sc0 src
  acl too_fast sc0_http_req_rate gt 100
  http-request deny status 429 if too_fast

  # Route ACME HTTP-01 challenges to local certbot (used during renewals)
  acl acme path_beg /.well-known/acme-challenge/
  use_backend be_acme if acme

  # Route your domain to the origin backend
  acl host_example hdr(host) -i example.com
  use_backend be_app if host_example
  default_backend be_app

# Backend: your origin server
backend be_app
  balance leastconn
  option httpchk GET /health
  http-check expect status 200
  server app1 10.0.0.10:8080 check

# Backend to serve ACME challenges (certbot standalone hook)
backend be_acme
  server local 127.0.0.1:8081

Почему это работает

  • HAProxy завершает TLS на :443 и перенаправляет на :80 → HTTPS.
  • Обычный трафик идет к вашему источнику по адресу ###ATP_NOTR_21_CODE_TAG_NOTR_ATP##.
  • Только ###ATP_NOTR_22_CODE_TAG_NOTR_ATP## направляется на крошечный локальный веб-сервер, который Certbot будет запускать во время обновлений.

Шаг 4 – Запуск, перезагрузка и проверка

# Validate config
sudo haproxy -c -f /etc/haproxy/haproxy.cfg

# Enable and start
sudo systemctl enable --now haproxy

# Reload after edits/renewals
sudo systemctl reload haproxy

Шаг 5 – Обновления без рук

Пусть Certbot ненадолго привяжется к :8081, пока HAProxy держит открытым :80/:443:

# Typically handled by systemd timer; safe to run manually for testing
sudo certbot renew --deploy-hook "/etc/letsencrypt/renewal-hooks/deploy/haproxy.sh" 
  --http-01-port 8081 --pre-hook "systemctl start haproxy" --post-hook "systemctl start haproxy"

Во время обновления Certbot отвечает на вызов на порту 8081; HAProxy уже направляет этот путь на 127.0.0.1:8081.


Вариации (выберите то, что вам нужно)

A) Несколько источников по имени хоста

# Add in frontend:
acl host_api hdr(host) -i api.example.com
use_backend be_api if host_api

# Define an API backend:
backend be_api
  balance roundrobin
  option httpchk GET /healthz
  server api1 10.0.0.21:9000 check
  server api2 10.0.0.22:9000 check

B) TLS passthrough (origin обрабатывает TLS/mTLS)

Используйте режим TCP с маршрутизацией SNI. Здесь нет переписывания заголовков или функций L7.

frontend fe_tcp
  mode tcp
  bind :443
  tcp-request inspect-delay 5s
  tcp-request content accept if { req_ssl_hello_type 1 }
  use_backend be_tls_app if { req_ssl_sni -i example.com }

backend be_tls_app
  mode tcp
  server app_tls 10.0.0.10:443 check

C) Минимальный обратный прокси-сервер только для HTTP (без TLS)

Только для внутреннего использования/тестирования – для производства используйте HTTPS. ###ATP_NOTR_11_CODE_TAG_NOTR_ATP##


Быстрые проверки и устранение неполадок

# DNS should point to HAProxy
dig +short example.com

# HTTP should redirect to HTTPS (301)
curl -I http://example.com

# HTTPS should serve content
curl -I https://example.com

# See headers the app receives (in your app logs):
# X-Forwarded-For, X-Forwarded-Proto, X-Forwarded-Host

Советы по брандмауэру

  • Заблокируйте ваш источник, чтобы он принимал трафик только от HAProxy-сервера (например, с помощью ufw, firewalld или групп безопасности облака).
  • Опционально заблокируйте прямой публичный доступ к IP-адресу происхождения на уровне провайдера.

Заключительные замечания

  • Устанавливайте таймауты, разумные для ваших рабочих нагрузок (для WebSockets/gRPC могут потребоваться более высокие).
  • Выставляйте в приложении конечную точку /health для httpchk.
  • Планируйте развертывание с нулевым временем простоя: отключите сервер (disabled) на время развертывания, а затем снова включите.

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