Я столкнулся с проблемой при настройке экземпляра 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
Клиенты подключаются через сертификаты, которые соответствуют следующему сертификату цепочка:
сертификат клиента -> промежуточный сертификат1 -> промежуточный сертификат2 (он должен стать новым якорем доверия) -> корневой сертификат ЦС
При использовании этой конфигурации подключение к HAProxy через сертификат клиента приводит к следующей ошибке:
13 февраля, 09:17:26 my-forwarder haproxy [108]:
Если я укажу корневой сертификат CA в качестве якоря доверия (параметр конфигурации ca-file в конфигурации HAProxy), квитирование TLS может быть установлено успешно. Однако я хочу принимать только сертификаты, которые были подписаны промежуточным сертификатом 2 ветви сертификатов -> корневым сертификатом CA , а не, например, каким-то другим промежуточным сертификатом -> корневым сертификатом 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 = промежуточный сертификат2
ошибка 2 при поиске глубины 2: невозможно получить сертификат эмитента
Добавление сертификата корневого ЦС к -CAfile приводит к:
$ openssl verify -CAfile <(cat test-certificate-chain.pem root-ca.pem) test-cert.pem
test-cert.pem: ОК
Единственные два варианта, которые я смог придумать для решения этой проблемы, следующие:
Я пока не удовлетворен с точки зрения уровня безопасности при использовании любого из вышеперечисленных вариантов. Поэтому мне было бы любопытно узнать, есть ли более «чистое» решение этой проблемы.
Кто-нибудь еще сталкивался с подобной проблемой?
Спасибо!
Обновление: я решил проблему несколько иначе, так как не смог найти способ доверять промежуточному (не 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 (cn) (подробности см. В документации ).
Реализовав это, я, к сожалению, смог сопоставить только отличительное имя (DN) издатель / родительский сертификат клиента (промежуточный сертификат 1), а не его прародитель (промежуточный сертификат 2).
Тем не менее я надеюсь, что это кому-то поможет ..