Назад | Перейти на главную страницу

OpenSSL / HAProxy проверяет сертификаты клиентов с помощью сертификата, отличного от CA

Я столкнулся с проблемой при настройке экземпляра HAProxy (v1.8.13) со скомпилированной поддержкой OpenSSL для приема только клиентских сертификатов, подписанных сертификат не CA. В частности, я хочу использовать промежуточный сертификат (не самозаверяющий) в качестве якоря доверия при проверке клиентских сертификатов.

Это конфигурация, которую я использую:

frontend myfrontend
     bind *:${PORT} ssl crt /certs/haproxy-server-cert-bundle.pem ca-file /certs/intermediate_cert2.pem verify required

Клиенты подключаются через сертификаты, которые соответствуют следующей цепочке сертификатов:

client certificate -> intermediate cert1 -> intermediate cert2 (this should become the new trust anchor) -> root CA certificate

При использовании этой конфигурации подключение к HAProxy через сертификат клиента приводит к следующей ошибке: Feb 13 09:17:26 my-forwarder haproxy[108]: <ip>:<port> [13/Feb/2019:09:17:26.619] my-forwarder/1: SSL client CA chain cannot be verified

Если я укажу корневой сертификат CA в качестве якоря доверия (ca-файл config в конфигурации HAProxy) рукопожатие TLS может быть установлено успешно. Однако я хочу принимать только сертификаты, подписанные ветвью сертификатов. промежуточный сертификат 2 -> корневой сертификат CA, а не т.е. какой-то другой промежуточный сертификат -> сертификат корневого ЦС.

Я попытался воспроизвести это поведение с помощью простой проверки OpenSSL и с помощью некоторой настройки OpenSSL s_server / s_client. Похоже, что та же проблема существует при использовании этих инструментов.

Некоторые доказательства:

$ openssl verify -CAfile test-certificate-chain.pem test-cert.pem test-cert.pem: C = ..., O = ..., OU = ..., ST = ..., CN = intermediate-cert2 error 2 at 2 depth lookup:unable to get issuer certificate

Добавление сертификата корневого CA к -CAfile приводит к: $ openssl verify -CAfile <(cat test-certificate-chain.pem root-ca.pem) test-cert.pem test-cert.pem: OK

Единственные два варианта, которые мне удалось придумать, чтобы решить эту проблему:

Я пока не удовлетворен уровнем безопасности при использовании любого из вышеперечисленных вариантов. Следовательно, мне было бы любопытно узнать, есть ли «более чистое» решение этой проблемы.

Кто-нибудь еще сталкивался с подобной проблемой?

Спасибо!

Обновление: я решил проблему немного по-другому, так как мне не удалось найти способ доверять промежуточному (не CA) сертификату, не доверяя родительскому (CA) сертификату через проверку цепочки сертификатов через OpenSSL.

Альтернативой было использование мощной функции ACL HAProxy. В частности:

frontend my-frontend
    ...
    acl my_tls_ca_issuer_acl ssl_c_i_dn(cn) -m reg ^<some-regex-matching-the-client-cert's-issuer-cn>$
    tcp-request content reject unless my_tls_ca_issuer_acl

Я настраиваю HAProxy для приема только клиентских сертификатов, выданных объектом, который соответствует заданному регулярному выражению Common Name. Это то, что соответствует ssl_c_i_dn (сп) делает (см. документация подробнее).

К сожалению, реализовав это, я смог сопоставить только отличительное имя (DN) издателя / родительского сертификата клиента (промежуточный сертификат 1), а не его прародителя (промежуточный сертификат 2).

Тем не менее я надеюсь, что это кому-то поможет ..