Вопрос или проблема
Я настраиваю haproxy, чтобы он действовал в качестве посредника между интернетом и рядом сервисов, работающих в изолированном кластере k8s.
Я уже успешно протестировал подключение к бэкенду через простой http, но сейчас я пытаюсь обработать компонент SSL, и почему-то, что бы я ни пробовал, я получаю следующее в логах:
Jan 22 11:10:22 jake haproxy[170526]: 95.214.55.185:34832 [22/Jan/2025:11:10:21.968] xanadu-ingress-front/3: SSL handshake failure (error:0A000076:SSL routines::no suitable signature algorithm)
Попытка устранить проблему с помощью openssl s_client
дает мне следующее (IP-адреса и DNS-имена изменены ради конфиденциальности):
shadur@luminosity:~$ openssl s_client --connect teapot.example.com:443
Connecting to 1.2.3.4 CONNECTED(00000003)
40E7B2BBBA7F0000:error:0A000410:SSL routines:ssl3_read_bytes:ssl/tls alert handshake failure:../ssl/record/rec_layer_s3.c:907:SSL alert number 40
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 335 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
This TLS version forbids renegotiation.
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
конфигурационный файл 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
stats timeout 30s
user haproxy
group haproxy
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# generated 2025-01-22, Mozilla Guideline v5.7, HAProxy 3.1.2, OpenSSL 3.4.0, intermediate config
# https://ssl-config.mozilla.org/#server=haproxy&version=3.1.2&config=intermediate&openssl=3.4.0&guideline=5.7
# intermediate configuration
ssl-default-bind-curves X25519:prime256v1:secp384r1
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options prefer-client-ciphers ssl-min-ver TLSv1.2 no-tls-tickets
ssl-default-server-curves X25519:prime256v1:secp384r1
ssl-default-server-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
ssl-default-server-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-server-options ssl-min-ver TLSv1.2 no-tls-tickets
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
ssl-dh-param-file /etc/ssl/private/dhparam
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
crt-store company
crt-base /etc/ssl/certs/
key-base /etc/ssl/private/
load crt "company.com-full.pem" key "company.nl.key" alias "company"
load crt "company.net-full.pem" key "company.net.key" alias "company.net"
frontend xanadu-ingress-front
bind 1.2.3.4:80
bind 1:2:3:4:5:6:7:8:80 transparent
bind 1.2.3.4:443 ssl crt-list /etc/ssl/crt-lists/company.list alpn h2,http/1.1
http-request redirect scheme https unless { ssl_fc }
default_backend xanadu-ingress-back
option httplog
backend xanadu-ingress-back
mode http
server xanadu 172.16.41.80:80 check
Я уверен, что упускаю что-то очень простое и очевидное, но не могу понять, что именно. Любая помощь будет оценена.
Я действительно упустил что-то важное, просто не в том месте, где ожидал.
Оказывается, haproxy очень требователен к порядку сертификатов в ‘полном’ PEM; правильный порядок это серверный сертификат, за которым следует сертификат CA, и на самом деле он не говорит, что есть проблема, если вы ошиблись в порядке, просто не предлагает рукопожатие, когда что-то подключается с SSL.
Ответ или решение
Ошибка, связанная с HAProxy и сообщением "no suitable signature algorithm" (нет подходящего алгоритма подписи), может быть сложной для устранения, особенно в случаях, когда проблема скрыта в других участках конфигурации. Давайте разберем её, используя формулу TEA (теория, пример, применение), для понимания сути ошибки и методов её устранения.
Теория
Ошибки SSL, а особенно те, которые связаны с ошибкой "no suitable signature algorithm", часто указывают на проблему совместимости между сервером и клиентом. Основные причины таких ошибок включают:
-
Несоответствие алгоритмов подписи: Сервер и клиент могут не поддерживать те же алгоритмы подписи. Это может произойти, если списки предпочтительных шифров не пересекаются.
-
Проблемы с сертификатом: Неправильный порядок или отсутствие сертификатов в предоставленной цепочке может привести к подобным ошибкам.
-
Проблемы с конфигурацией: Конфигурация HAProxy содержит множество элементов, которые могут неверно взаимодействовать или быть неправильно настроены для работы с SSL/TLS.
Пример
Согласно предоставленным данным, проблема возникала из-за неправильного порядка сертификатов в файле PEM. Правильный порядок включает сначала серверный сертификат, а затем сертификаты промежуточных удостоверяющих центров (CA).
Вот пример конфигурации HAProxy, которая могла бы приводить к ошибке:
frontend xanadu-ingress-front
bind 1.2.3.4:443 ssl crt-list /etc/ssl/crt-lists/company.list alpn h2,http/1.1
...
Эта строка указывает, что HAProxy должен выполнить SSL handshake используя сертификаты, предоставленные в списке crt-list
, но если их порядок неправильный, будут возникать ошибки.
Применение
-
Проверка порядка сертификатов: Вам необходимо убедиться, что в файле PEM серверный сертификат идет первым, за которым следуют промежуточные сертификаты CA. Это критично для успешного проведения SSL handshaking.
-
Проверка поддержки шифров и алгоритмов: Убедитесь, что списки шифров и алгоритмов совпадают между сервером и клиентами, и они поддерживают нужные протоколы. Проверьте настройки параметров
ssl-default-bind-ciphers
иssl-default-bind-ciphersuites
, чтобы проверить поддержку необходимых шифров. -
Тестирование с OpenSSL: Проверьте соединение с помощью команды
openssl s_client
для выявления проблем SSL. Это поможет увидеть более детальную информацию о том, что блокирует handshake. -
Обновление конфигурации HAProxy: Убедитесь, что каждый сегмент конфигурации HAProxy обновлен для поддержки необходимых обновлений сертификатов и алгоритмов. Это включает в себя не только глобальные параметры, но и специфические для
frontend
иbackend
настройки.
ssl-default-bind-ciphers ECDHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_256_GCM_SHA384
ssl-default-server-options ssl-min-ver TLSv1.2 no-tls-tickets
Исправление ошибки SSL в HAProxy может потребовать тщательной проверки и обновления ваших сертификатов и конфигураций, приведя их в соответствие с современными стандартами безопасности. Не забывайте обновлять документацию и проводить тестирование после каждой значительной конфигурационной правки.
И помните, что успех решения подобных проблем часто зависит от скрупулезного внимания к деталям и оперативной адаптации к изменениям в технологиях безопасности.