Я хочу, чтобы мой веб-сервер Apache принимал SSL-соединения, ТОЛЬКО ЕСЛИ клиент представляет собой определенный сертификат клиента SSL. Другими словами, разрешен только ОДИН клиент, и он ДОЛЖЕН использовать определенный сертификат клиента (который у меня тоже есть).
Этот сертификат клиента (назовем его «MyClientCertificate») является обычным сертификатом PEM, выпущенным центром сертификации (назовем его «MyCA»), для которого у меня также есть его сертификат.
Вот как я настроил свой виртуальный хост Apache для этой цели (я сообщаю только о параметрах, связанных с проверкой клиента SSL):
SSLVerifyClient require
SSLCACertificatePath /etc/ssl/certs
SSLCACertificateFile /etc/ssl/client/MyClientCertificate.pem
SSLCADNRequestFile /etc/ssl/client/MyClientCertificate.pem
SSLVerifyDepth 1
Пояснения к вариантам (или, по крайней мере, к моим намерениям ...):
Похоже, это сработало: Apache требует сертификат клиента, отклоняет соединение, если указанный сертификат клиента не предоставлен, и принимает его, если он есть. Однако недавно клиент (который является для меня поставщиком) решил сменить свой сертификат клиента на новый (назовем его MyNewClientCertificate.pem) с 2048-битным шифрованием вместо 1024-битной глубины старого. Проблема вот в чем:
Новый сертификат выдается тем же ЦС, что и старый. Поставщик предполагает, что моя конфигурация Apache, вероятно, принимает все подключения от клиентов, которые представляют сертификат, выпущенный этим ЦС, вместо того, чтобы выполнять сопоставление самого сертификата клиента.
Если это так, что я делаю не так в своей конфигурации? Должен ли я снизить SSLVerifyDepth до 0? (но разве это не означает, что сертификат должен быть самоподписанным?) Или мне нужно что-то изменить в директивах SSLCACertificateFile / SSLCADNRequestFile?
Поскольку эта система находится в производстве, у меня нет возможности выполнить все тесты, которые я могу придумать, но я должен попытаться внести целенаправленные изменения, чтобы как можно быстрее получить правильный результат. Вот почему я был бы признателен за любую помощь по этой теме.
Вы можете сопоставить конкретный сертификат клиента, используя SSLRequire
директива для сопоставления с полным DN субъекта или только с частью CN из сертификата клиента:
SSLRequire %{SSL_CLIENT_S_DN} eq "C=AU, ST=Some-State, L=Springfield, O=ServerFault.com, OU=Moderators, CN=HBruijn/emailAddress=hbruijn@serverfault.com"
SSLRequire %{SSL_CLIENT_S_DN_CN} eq "HBruijn/emailAddress=hbruijn@serverfault.com"
Использовать openssl x509 -in client.crt -text
для отображения строки темы.
Более полная конфигурация будет:
SSLVerifyClient none
SSLCACertificateFile conf/ssl.crt/ca.crt
SSLCACertificatePath conf/ssl.crt
<Directory /usr/local/apache2/htdocs/secure/area>
SSLVerifyClient require
SSLVerifyDepth 5
SSLOptions +FakeBasicAuth
SSLRequireSSL
SSLRequire %{SSL_CLIENT_S_DN_CN} eq "HBruijn/emailAddress=hbruijn@serverfault.com"
</Directory>