Вопрос или проблема
Я новичок в HAProxy и хочу использовать его для перенаправления входящих HTTPS-запросов на свои HTTP-бэкенд-серверы.
Я знаю, как это можно сделать с помощью Nginx, вот так:
#SSL для всех
server {
listen 443 ssl ;
server_name www.example.com;
absolute_redirect off;
proxy_redirect off;
access_log /var/log/nginx/example.com-ssl-access.log;
error_log /var/log/nginx/example.com-ssl-error.log;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1 ;
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
location / {
proxy_pass http://bo.example.com;
}
}
Но я не знаю, как сделать это с помощью HAProxy?
Я уже пробовал несколько вариантов. Но каждый раз я получал только перенаправления HTTPS на HTTPS.
Можете помочь мне?
Это моя текущая конфигурация HAProxy:
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 5s
user haproxy
group haproxy
daemon
tune.ssl.default-dh-param 2048
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
stats enable
stats hide-version
stats refresh 30s
stats uri /hastats
frontend www-http
# Порт прослушивания - 80
bind *:80
# Режим работы
mode http
reqadd X-Forwarded-Proto:\ http
# Тест URI, чтобы проверить, является ли это запросом letsencrypt
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
use_backend letsencrypt-backend if letsencrypt-acl
# Установить бэкенд по умолчанию
default_backend www-backend
# Включить отправку заголовка X-Forwarded-For
#option forwardfor
#option httpchk GET /
# log reqs http
#option httplog
# acl
#acl prod_acl hdr(host) prod.local
#use_backend apache_backend_servers if prod acl
# Определить frontend ssl
frontend www-ssl
bind *:443 ssl crt /etc/haproxy/certs/example.com.pem
reqadd X-Forwarded-Proto:\ https
default_backend www-backend
# Определить бэкенд
backend www-backend
mode http
option httpchk
option forwardfor except 127.0.0.1
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme http if { hdr(Host) -i example.com } { ssl_fc }
balance roundrobin
# Определить бэкенд-серверы
server web1 XXX.XXX.XXX.101 check inter 3s port 80
server web2 XXX.XXX.XXX.102 check inter 3s port 80
backend letsencrypt-backend
server letsencrypt 127.0.0.1:8080
Я подготовил чистый рабочий пример, из которого вы можете настроить чистую конфигурацию и добавить необходимые функции. В общем, чему я учу людей, изучающих различные приложения и темы, так это тому, что они должны уметь понимать основную функцию каждой строки конфигурации.
Это можно достичь, прочитав документацию по этой теме и логически размышляя.
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
user haproxy
group haproxy
daemon
tune.ssl.default-dh-param 2048
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
frontend www
bind *:80
bind *:443 ssl crt /etc/ssl/localcerts/apache-full.pem
option forwardfor
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
use_backend letsencrypt-backend if letsencrypt-acl
default_backend www-backend
backend www-backend
option httpchk
balance roundrobin
server web1 10.0.0.1:80 check inter 3s
server web2 10.0.0.2:80 check inter 3s
backend letsencrypt-backend
server letsencrypt 127.0.0.1:8080
В приведенном выше примере TLS правильно завершается и проксируется как простой HTTP к вышестоящим серверам.
Заголовок “X-Forwarded-Proto” устанавливается в “https”, если запрос пришел по HTTPS. В противном случае он будет “http”.
Проверка 4 уровня вышестоящих серверов не требует дополнительного порта, потому что, если порт определен с IP, он автоматически будет использоваться в качестве порта проверки.
Ответ или решение
Полный ответ по теме HAPROXY: реверсивный прокси с завершением TLS
HAProxy является мощным инструментом для управления трафиком, и его можно использовать для обработки HTTPS-запросов и их перенаправления к HTTP-бекендам сервера. Ниже приведен пример конфигурации HAProxy, который полностью соответствует вашему запросу.
Пример конфигурации HAProxy
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 5s
user haproxy
group haproxy
daemon
tune.ssl.default-dh-param 2048
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
frontend www
bind *:80
bind *:443 ssl crt /etc/ssl/localcerts/example.com.pem
option forwardfor
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
use_backend letsencrypt-backend if letsencrypt-acl
default_backend www-backend
backend www-backend
option httpchk
balance roundrobin
server web1 10.0.0.1:80 check inter 3s
server web2 10.0.0.2:80 check inter 3s
backend letsencrypt-backend
server letsencrypt 127.0.0.1:8080
Пояснение конфигурации:
-
global и defaults: В этом разделе определяются основные параметры, такие как логирование и настройки времени ожидания.
-
frontend www:
- bind :80 и bind :443: Данный фрагмент конфигурации устанавливает прослушивание на портах 80 и 443, где 443 используется для HTTPS с сертификатом, указанным по пути
/etc/ssl/localcerts/example.com.pem
. - option forwardfor: Эта опция добавляет заголовок
X-Forwarded-For
, который передает оригинальный IP адрес клиента. - http-request set-header X-Forwarded-Proto: Настройка заголовка
X-Forwarded-Proto
для определения, пришел ли запрос через HTTPS или HTTP.
- bind :80 и bind :443: Данный фрагмент конфигурации устанавливает прослушивание на портах 80 и 443, где 443 используется для HTTPS с сертификатом, указанным по пути
-
ACL и использование бекендов:
- acl letsencrypt-acl: Определяет правило, чтобы обрабатывать автоматические запросы Let’s Encrypt для получения сертификатов.
- use_backend letsencrypt-backend: Если запрос соответствует правилам ACL, он будет перенаправлен на специальный бэкенд для Let’s Encrypt.
-
backend www-backend:
- Определены серверы, к которым будет перенаправлен трафик после TLS-терминации. Используется round-robin для распределения нагрузки между серверами.
Заключение
С помощью приведенной конфигурации HAProxy можно успешно обрабатывать HTTPS-запросы и делать редиректы к HTTP-бекендам. Важно, чтобы путь к сертификату был правильным, и все IP-адреса серверов бэкенда были корректно указаны. Настройки, такие как X-Forwarded-Proto
, обеспечивают, что ваши бэкенд-приложения будут знать, через какой протокол осуществляется входящий запрос.
Не забудьте протестировать конфигурацию и перезапустить HAProxy после внесения изменений. Удачи с вашим проектом!