Как HAProxy выбирает, какой сертификат обслуживать?

У меня есть сервер HAProxy 1.5.9, который будет обслуживать либо сертификат, подписанный самозаверяющим центром сертификации, либо сертификат Let's Encrypt, в зависимости от того, какое имя сервера указано. Это мой файл конфигурации:

defaults
  mode tcp
  option clitcpka

listen ft_app
  bind *:5000 ssl crt /certs/private.pem ca-file /app/certs/self-signed-ca.pem crt /certs/self-signed.pem crt /app/certs/lets-encrypt.pem ciphers AES:ALL:!aNULL:!eNULL:!3DES:!DES:!RC4:!DHE:!EDH:!MD5:!PSK:!aECDH:@STRENGTH no-sslv3 no-tlsv10 no-tlsv11

  mode tcp
  option tcplog
  tcp-request inspect-delay 10s

  use_backend app_http if HTTP
  default_backend app_tcp

backend app_http
  mode http
  option httplog
  balance roundrobin

  reqadd X-Forwarded-Proto:\ https
  cookie SRVID insert indirect nocache
  http-check expect status 200

  server app_4 10.10.10.4:15672 cookie app_4 check inter 10s rise 2 fall 2
  server app_3 10.10.10.3:15672 cookie app_3 check inter 10s rise 2 fall 2
  server app_2 10.10.10.2:15672 cookie app_2 check inter 10s rise 2 fall 2
backend app_tcp
  option tcp-check
  server app_4 10.10.10.4:5672 check inter 10s rise 2 fall 2
  server app_3 10.10.10.3:5672 check inter 10s rise 2 fall 2
  server app_2 10.10.10.2:5672 check inter 10s rise 2 fall 2

Оно работает. Я не понимаю, как именно HAProxy выбирает сертификат для обслуживания. Я предполагаю, что захватывает 'имя_сервера' из метаданных сертификата. Если да, то какое именно поле и как мне его изучить, openssl x509 -in ca.pem -text -noout Кажется, нет подозреваемых.

2 ответа

Я понял. RTFM. Из документов HAProxy:

https://cbonte.github.io/haproxy-dconv/1.7/configuration.html

Сертификаты будут представлены клиентам, которые предоставляют действительное поле индикации имени сервера TLS, соответствующее одному из их CN или альтернативных субъектов. Поддерживаются подстановочные знаки, когда вместо первого компонента имени хоста используется подстановочный знак '*' (например: *.example.org соответствует www.example.org, но не www.sub.example.org).

Если клиент не предоставляет SNI, или библиотека SSL не поддерживает расширения TLS, или если клиент предоставляет имя хоста SNI, которое не соответствует ни одному сертификату, то будет представлен первый загруженный сертификат. Это означает, что при загрузке сертификатов из каталога настоятельно рекомендуется сначала загрузить сертификат по умолчанию в виде файла или убедиться, что он всегда будет первым в каталоге.

Таким образом, он использовал имя CN или alt или по умолчанию первый предоставленный сертификат. Я проверил CN, который не совпадает, но затем я нашел альтернативное имя:

        X509v3 Subject Alternative Name: 
            DNS:myhost.example.com

Это соответствует домену, к которому я подключаюсь, когда получаю этот сертификат! Поэтому в моем случае Haproxy выбирает сертификат, используя альтернативные имена, поскольку CN не является полным доменным именем.

Имя сервера в сертификате TLS - это сначала "Общее имя", отображаемое как Subject: ... CN=www.example.com

Если у вас есть сертификат, содержащий более одного имени сервера, он называется сертификатом SAN https://en.m.wikipedia.org/wiki/Subject_Alternative_Name

И дополнительные имена серверов, которые действительны с этим сертификатом

DNS Name: example.com
DNS Name: www.example.om
DNS Name: ...

Записи.

С помощью индикации имени сервера от клиента HAProxy может сопоставить запрошенный URL с доступными сертификатами.

Если клиент не использует sni или не соответствует сертификату, HAProxy, вероятно, использует первый сертификат по умолчанию (и клиент получает ошибку несоответствия сертификата

Другие вопросы по тегам