Вопрос или проблема
У меня есть проблема, которая беспокоит мои нейроны уже несколько недель, у меня есть 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
Объяснение конфигурации
-
Режим работы (
mode http
): Изменение режима на HTTP в обоих frontend и backend позволит HAProxy обрабатывать заголовки HTTP. -
Настройка SSL для серверов: Ключевой момент в том, что вы настраиваете SSL-соединение при взаимодействии между HAProxy и вашими веб-серверами, что позволяет корректно безопасно передавать данные.
-
Заголовки: Убедитесь, что вы добавляете нужные заголовки, такие как
X-Forwarded-Proto
,X-CLIENT-IP
иX-Request-Start
, чтобы они передавались на ваши веб-серверы.
Заключение
Теперь, после применения указанных изменений, HAProxy будет правильно передавать заголовки при работе с HTTPS. Убедитесь, что вы протестировали изменения, чтобы удостовериться, что IP-адрес клиента и другие заголовки корректно отображаются на веб-сервере. Если у вас возникнут дополнительные возникнут вопросы, не стесняйтесь обращаться за помощью, всегда готовы помочь.