how to create a reverse proxy with haproxy

Огляд

Дізнайтеся, як налаштувати зворотний проксі за допомогою 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.
  • Детальні журнали та сторінка статистики в реальному часі забезпечують спостережливість.

Підсумок: HAProxy спрощує вашу архітектуру, підвищує безпеку і продуктивність, а також спрощує масштабування


Переваги та недоліки HAProxy

Плюси (чому HAProxy блищить)

  • Висока продуктивність і низькі накладні витрати (керований подіями, багатопотоковий).
  • Інтелектуальні функціїL4 + L7 (пропуск TCP/SNI або повна маршрутизація/перезапис HTTP).
  • Надійне балансування навантаження та перевірка працездатності (round-robin, leastconn, хешування; активні перевірки, обхід відмови).
  • Функції безпеки (завершення TLS, HSTS, ACL, обмеження швидкості за допомогою stick-таблиць, дозвіл/заборона IP).
  • Спостережуваність (багаті логи, сокет/сторінка статистики в реальному часі; доступні експортери 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/AAAA, що вказує на публічну 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 сертифікат (давайте зашифруємо)

Ми дозволимо 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 (повний ланцюжок + приватний ключ)

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 демон за замовчуванням log global mode http option httplog timeout connect 5s timeout client 60s timeout server 60s http-reuse safe # Фронтенд: слухати на 80/443, перенаправляти на HTTPS, маршрутизувати ACME і трафік додатків frontend fe_https bind :80 bind :443 ssl crt /etc/haproxy/certs/example.com.pem alpn h2,http/1.1 # Примусовий HTTPS http-запит схема перенаправлення https unless { ssl_fc } # Базовий заголовок безпеки http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" if { ssl_fc } # Зберегти інформацію про клієнта для вашого додатку опція forwardfor заголовок X-Forwarded-For http-запит set-header X-Forwarded-Proto https if { ssl_fc } http-request set-header X-Forwarded-Host %[req.hdr(host)] # Просте обмеження швидкості: 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 # Маршрутизація ACME HTTP-01 викликів на локальний certbot (використовується при продовженні) acl acme path_beg /.well-known/acme-challenge/ use_backend be_acme if acme # Спрямувати домен на вихідний бекенд acl host_example hdr(host) -i example.com use_backend be_app if host_example default_backend be_app # Бекенд: ваш початковий сервер backend be_app balance leastconn option httpchk GET /health http-check expect status 200 server app1 10.0.0.10:8080 check # Бекенд для обслуговування ACME викликів (окремий хук certbot) backend be_acme server local 127.0.0.1:8081

Чому це працює

  • HAProxy завершує TLS на :443 і перенаправляє :80 → HTTPS.
  • Звичайний трафік йде до вашого джерела за адресою 10.0.0.10:8080.
  • Лише /.well-known/acme-challenge/* перенаправляється на крихітний локальний веб-сервер, який запускається Certbot під час поновлення.

Крок 4 – Запуск, перезавантаження та перевірка

#

 Перевірка конфігурації sudo haproxy -c -f /etc/haproxy/haproxy.cfg # Увімкнення та запуск sudo systemctl enable --now haproxy # Перезавантаження після редагувань/оновлень sudo systemctl reload haproxy

Крок 5 – Оновлення без участі користувача

Дозвольте Certbot ненадовго прив’язатися до :8081, поки HAProxy тримає відкритим :80/:443:

# Зазвичай обробляється таймером systemd; безпечно запускати вручну для тестування 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) Кілька джерел за іменем хоста

# Додати у фронтенд: acl host_api hdr(host) -i api.example.com use_backend be_api if host_api # Визначити бекенд API: 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 пасивний (джерело обробляє 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.

global log /dev/log local0 defaults mode http log global option httplog timeout connect 5s timeout client 60s timeout server 60s frontend public_http bind :80 option forwardfor default_backend app backend app server app1 10.0.0.10:8080 check

Швидкі перевірки та усунення несправностей

# DNS має вказувати на HAProxy dig +short example.com # HTTP має перенаправляти на HTTPS (301) curl -I http://example.com # HTTPS має обслуговувати вміст curl -I https://example.com # Дивіться заголовки, які отримує програма (в логах програми): # X-Forwarded-For, X-Forwarded-Proto, X-Forwarded-Host

Поради брандмауера

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

Заключні зауваження

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

Важливе зауваження:Якщо ви не впевнені, як правильно налаштувати сервер, ми наполегливо рекомендуємо найняти професіонала для завершення конфігурації. Важливо переконатися, що всі налаштування виконані точно, включаючи перевірку портів брандмауера, щоб переконатися у відсутності блокування портів. Важливо мати хоча б базове розуміння брандмауерів і команд Linux, щоб ефективно керувати процесом конфігурації. Зверніть увагу, що ми не несемо відповідальності за будь-які збитки або проблеми, які можуть виникнути в процесі конфігурації. Вся інформація, надана тут, призначена лише для отримання технічних знань і навчання. Дякуємо за розуміння