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

Принудительная проверка клиента в Apache только для определенного сертификата клиента

Я хочу, чтобы мой веб-сервер 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>