HAPROXY: обратный прокси с завершением TLS

Вопрос или проблема

Я новичок в 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

Пояснение конфигурации:

  1. global и defaults: В этом разделе определяются основные параметры, такие как логирование и настройки времени ожидания.

  2. 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.
  3. ACL и использование бекендов:

    • acl letsencrypt-acl: Определяет правило, чтобы обрабатывать автоматические запросы Let’s Encrypt для получения сертификатов.
    • use_backend letsencrypt-backend: Если запрос соответствует правилам ACL, он будет перенаправлен на специальный бэкенд для Let’s Encrypt.
  4. backend www-backend:

    • Определены серверы, к которым будет перенаправлен трафик после TLS-терминации. Используется round-robin для распределения нагрузки между серверами.

Заключение

С помощью приведенной конфигурации HAProxy можно успешно обрабатывать HTTPS-запросы и делать редиректы к HTTP-бекендам. Важно, чтобы путь к сертификату был правильным, и все IP-адреса серверов бэкенда были корректно указаны. Настройки, такие как X-Forwarded-Proto, обеспечивают, что ваши бэкенд-приложения будут знать, через какой протокол осуществляется входящий запрос.

Не забудьте протестировать конфигурацию и перезапустить HAProxy после внесения изменений. Удачи с вашим проектом!

Оцените материал
Добавить комментарий

Капча загружается...