HAProxy не передает заголовки с HTTPS

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

У меня есть проблема, которая беспокоит мои нейроны уже несколько недель, у меня есть HAProxy LB + 2 веб-сервера. Идея заключается в том, чтобы знать реальный IP-адрес компьютера, который обращается к узлу haproxy, для этого у меня есть следующая конфигурация:

LB : 10.0.0.1 - haproxy.example.test
Web1 : 10.0.0.2 - web1.example.test
Web2 : 10.0.0.3 - web2.example.test

Сертификат установлен на каждом из веб-узлов, и он работает нормально, за исключением того, что заголовки не передаются.

haproxy.cfg

global
   log /dev/log local0
   log /dev/log local1 notice
   chroot /var/lib/haproxy
   stats timeout 30s
   user haproxy
   group haproxy
   daemon

defaults
   log global
   option forwardfor
   option httplog
#   option dontlognull
   timeout connect 5000
   timeout client 50000
   timeout server 50000

frontend http_front
   bind *:80
   stats uri /haproxy?stats
   default_backend http_back

frontend https_front
   bind *:443
   default_backend https_back

backend http_back
   balance roundrobin
   mode http
   http-request add-header X-CLIENT-IP %[src]
   http-request set-header X-Request-Start t=%Ts%ms
   server web1 10.0.0.2:80 check
   server web2 10.0.0.3:80 check

backend https_back
   balance roundrobin
   mode tcp
   option forwardfor
   http-request set-header X-Forwarded-Port %[dst_port]
   http-request add-header X-Forwarded-Proto https if { ssl_fc }
   http-request set-header X-Forward-For %[src]
   http-request add-header X-CLIENT-IP %[src]
   http-request set-header X-Request-Start t=%Ts%ms
   server webs1 10.0.0.2:443 check
   server webs2 10.0.0.3:443 check

Если я обращаюсь к 10.0.0.1 (haproxy.example.test) через HTTP, я получаю ожидаемые заголовки:

HTTP_X_CLIENT_IP    65.28.121.161
HTTP_X_REQUEST_START    t=1557918661669
HTTP_X_FORWARDED_FOR    65.28.121.161

Но если я обращаюсь через HTTPS, ни один из этих заголовков не передается в Apache…

Я пробовал все и не могу разобраться, гуглил недели безуспешно. У кого-нибудь есть идея, почему это происходит?

ОБНОВЛЕНИЕ:

Спасибо за то, что направили меня на правильный путь, решение заключается в следующей конфигурации:

global
   log /dev/log local0
   log /dev/log local1 notice
   chroot /var/lib/haproxy
   stats timeout 30s
   user haproxy
   group haproxy
   daemon

defaults
   log global
   option forwardfor
   option httplog
   option dontlognull
   timeout connect 5000
   timeout client 50000
   timeout server 50000


frontend localhost
    bind *:80
    bind *:443 ssl crt /etc/haproxy/haproxy.crt
    mode http
    redirect scheme https if !{ ssl_fc }
    default_backend nodes

backend nodes
    mode http
    balance roundrobin
    option forwardfor
    option httpchk HEAD / HTTP/1.1\r\nHost:localhost
    server web01 10.0.0.2:80 check
    server web02 10.0.0.3:80 check
    http-request set-header X-Forwarded-Port %[dst_port]
    http-request add-header X-Forwarded-Proto https if { ssl_fc }

HAProxy будет Negotiировать защищенное соединение и передавать трафик как http, вместо https, на веб-серверы.

Это было основано на этой замечательной статье https://serversforhackers.com/c/using-ssl-certificates-with-haproxy

С уважением,

Хуго Феррейра

Конечная конфигурация

   log /dev/log local0
   log /dev/log local1 notice
   chroot /var/lib/haproxy
   stats timeout 30s
   user haproxy
   group haproxy
   daemon

defaults
   log global
   option forwardfor
   option httplog
   option dontlognull
   timeout connect 5000
   timeout client 50000
   timeout server 50000


frontend localhost
    bind *:80
    bind *:443 ssl crt /etc/haproxy/haproxy.crt
    mode http
    redirect scheme https if !{ ssl_fc }
    default_backend nodes

backend nodes
    mode http
    balance roundrobin
    option forwardfor
    option httpchk HEAD / HTTP/1.1\r\nHost:localhost
    server web01 10.0.0.2:80 check
    server web02 10.0.0.3:80 check
    http-request set-header X-Forwarded-Port %[dst_port]
    http-request add-header X-Forwarded-Proto https if { ssl_fc }

HAProxy будет Negotiировать защищенное соединение и передавать трафик как http, вместо https, на веб-серверы.

Это было основано на этой замечательной статье https://serversforhackers.com/c/using-ssl-certificates-with-haproxy

Ответ или решение

Решение проблемы передачи заголовков через HAProxy с использованием HTTPS

В вашем вопросе упоминается проблема с передачей заголовков, таких как IP-адрес клиента, от HAProxy к веб-серверам, когда запросы поступают по протоколу HTTPS. Это достаточно распространённая задача, и ниже я изложу, как правильно настроить HAProxy для корректной работы с HTTPS и передачи нужных заголовков.

Причины проблемы

По умолчанию, HAProxy может не передавать заголовки через указываемый вами режим TCP в конфигурации backend для HTTPS. Когда вы используете mode tcp, HAProxy просто передаёт данные сквозь соединение до сервера, не изменяя их. Это значит, что заголовки, которые вы пытаетесь добавить, не будут применяться.

Решение

Для решения вашей проблемы нужно изменить режим работы HAProxy на HTTP для обработки HTTPS-соединений. Это позволит HAProxy правильно добавлять заголовки, которые вы хотите передать на ваши веб-серверы. Ниже представлена исправленная конфигурация HAProxy, которая решает проблему:

global
   log /dev/log local0
   log /dev/log local1 notice
   chroot /var/lib/haproxy
   stats timeout 30s
   user haproxy
   group haproxy
   daemon

defaults
   log global
   option forwardfor
   option httplog
   option dontlognull
   timeout connect 5000
   timeout client 50000
   timeout server 50000

frontend https_front
    bind *:443 ssl crt /etc/haproxy/haproxy.crt
    mode http
    option http-server-close
    default_backend https_back

backend https_back
    mode http
    balance roundrobin
    option forwardfor
    server web1 10.0.0.2:443 check ssl verify none
    server web2 10.0.0.3:443 check ssl verify none
    http-request set-header X-Forwarded-Port %[dst_port]
    http-request add-header X-Forwarded-Proto https if { ssl_fc }
    http-request add-header X-CLIENT-IP %[src]
    http-request set-header X-Request-Start t=%Ts%ms

Объяснение конфигурации

  1. Режим работы (mode http): Изменение режима на HTTP в обоих frontend и backend позволит HAProxy обрабатывать заголовки HTTP.

  2. Настройка SSL для серверов: Ключевой момент в том, что вы настраиваете SSL-соединение при взаимодействии между HAProxy и вашими веб-серверами, что позволяет корректно безопасно передавать данные.

  3. Заголовки: Убедитесь, что вы добавляете нужные заголовки, такие как X-Forwarded-Proto, X-CLIENT-IP и X-Request-Start, чтобы они передавались на ваши веб-серверы.

Заключение

Теперь, после применения указанных изменений, HAProxy будет правильно передавать заголовки при работе с HTTPS. Убедитесь, что вы протестировали изменения, чтобы удостовериться, что IP-адрес клиента и другие заголовки корректно отображаются на веб-сервере. Если у вас возникнут дополнительные возникнут вопросы, не стесняйтесь обращаться за помощью, всегда готовы помочь.

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

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