Я использую apache2 (2.2.3) для обслуживания сайта, на котором я хочу, чтобы клиенты аутентифицировались с помощью сертификатов. Поскольку мне нужно только убедиться, что пользователь, представляющий конкретный сертификат, является тем же пользователем, который представил этот сертификат в прошлом, ЦС, подписывающий сертификат, не имеет значения. Однако кажется, что использование SSLVerifyClient require
требует SSLCACertificateFile ...
(или SSLCACertificatePath ...
), и тогда apache будет принимать только сертификаты, подписанные ЦС в этом файле / пути. Есть ли способ заставить apache принимать любой сертификат клиента, независимо от выдающего / поющего ЦС? (т.е. убедитесь, что у клиента есть соответствующий закрытый ключ для представленного открытого ключа, но не утруждайте себя проверкой выдающего / подписывающего ЦС)
Как вы обнаружили, вы можете отключить проверку сертификата на уровне подтверждения SSL / TLS в Apache Httpd, используя SSLVerifyCLient optional_no_ca
.
Вторая проблема, с которой вы столкнетесь в том, что вы пытаетесь сделать, - это заставить клиента отправить сертификат. Поскольку ваш сертификат не предназначен для использования в PKI, он может быть самоподписанным и иметь разных издателей.
При запросе клиентского сертификата сервер отправляет CertificateRequest
Сообщение TLS клиенту во время хендхаса. Это сообщение содержит certificate_authorities
список:
Список известных имен приемлемых центров сертификации. Эти отличительные имена могут указывать желаемое отличительное имя для корневого CA или для подчиненного CA; таким образом, это сообщение может использоваться для описания как известных корней, так и желаемого пространства авторизации. Если список certificate_authorities пуст, то клиент МОЖЕТ отправить любой сертификат соответствующего ClientCertificateType, если только не существует противоположной внешней договоренности.
Браузеры используют это, чтобы выбрать, какой сертификат клиента отправлять (если есть).
(Обратите внимание, что часть о пустом списке есть только в спецификации, начиная с TLS 1.1. SSL 3.0 и TLS 1.0 ничего не говорят об этом, и на практике это также будет работать.)
У вас есть два варианта для этого.
Если ожидаемые клиентские сертификаты будут самоподписанными, все они будут иметь разных издателей. Поскольку вы не знаете, чего ожидать, серверу нужно будет отправить пустой список. Для этого используйте SSLCADNRequestFile
директива и укажите его на файл, содержащий только пустую строку (если я хорошо помню, это не работает с полностью пустым файлом).
Второй (менее чистый) вариант. Это согласование DN эмитента, общего для всех ожидаемых клиентских сертификатов, независимо от того, действительно ли они были выпущены этим сертификатом CA (или существует ли этот CA). Поступая так, вы значительно нарушите модель PKI (больше).
Если вы согласны с DN эмитента, например CN=Dummy CA
(например). Кто угодно может создать самозаверяющий сертификат, используя CN=Dummy CA
как Subject DN (и Issuer DN), возможно, с разными ключами. Хотя SSLCADNRequestFile
Предполагается, что директива будет настроена с сертификатами для создания списка, они вообще не используются для проверки сертификата клиента, это просто сложный (но естественный в контексте других директив) способ настройки certificate_authorities
список. Если вы как услуга помещаете самозаверяющий сертификат с этими именами в SSLCADNRequestFile
, это сделает CertificateRequest
Использование сообщения TLS CN=Dummy CA
в certificate_authorities
list (на данном этапе это просто имена, а не сертификаты). После этого клиент сможет получить свой собственный сертификат с DN эмитента. CN=Dummy CA
, может ли его подпись быть проверена этим сертификатом (теми же ключами) или нет, поскольку на этих этапах проверка подписи в любом случае не выполняется.
При этом помните, что с SSLVerifyCLient optional_no_ca
, подлинная проверка сертификата не выполняется (я полагаю, вы могли бы проверить SSL_CLIENT_VERIFY
переменная, если ваша ручная проверка - это просто резервное решение для PKI, которое вы все равно настроили). Все, что вы будете знать на этом этапе, это то, что у клиента есть закрытый ключ для сертификата открытого ключа, который он представил (гарантированный TLS. CertificateVerify
message): вам нужно будет выполнить некоторую форму проверки, если вы хотите, чтобы была какая-то аутентификация. (Вы не можете доверять какому-либо содержимому сертификата, то есть какой-либо привязке между его открытым ключом и именами / атрибутами, которые он содержит.)
Это не сработает для файлов, но вы можете сделать это для приложения (например, PHP / CGI / ... даже Java, если вы передадите сертификат прокси-серверу Java). Один из основных способов - иметь заранее известный список открытых ключей, или вы можете просмотреть идеи в FOAF + SSL / WebID.
С помощью SSLVerifyCLient optional_no_ca
(вместо того require
) заставляет apache не проверять выдающий ЦС (и, следовательно, не требуется файл сертификата ЦС или путь). Это позволяет клиенту / пользователю не отправлять сертификат, поэтому проверка того, использовался ли сертификат, должна выполняться отдельно.
(Видимо, я просто не успел внимательно прочитать mod_ssl
документация.)