Принудительная проверка клиента в 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

Пояснения из вариантов (или, по крайней мере, из моих намерений ...):

  • с "SSLVerifyClient require" Я заставляю Apache всегда выполнять проверку клиента и отклонять соединение, если оно не удается
  • / etc / ssl / certs содержит PEM сертификаты MyCA (правильно установлены в системе с необходимым хешированием + процесс симлинков),пока сертификаты всех других известных центров сертификации Apache могут распознать
  • с помощью SSLCACertificateFile, я добавляю сертификат MyClientCertificate в список сертификатов CA в / etc / ssl / certs как сам по себе доверенный сертификат и с SSLCADNRequestFile Я говорю, что мой сервер должен запрашивать у клиента только этот сертификат (и только он), а не весь список сертификатов CA в SSLCACertificatePath + SSLCACertificateFile
  • с SSLVerifyDepth 1. Я говорю, что разрешенный сертификат клиента подписан центром сертификации, который входит в число тех, которые распознаются сервером (в SSLCACertificatePath)

Это похоже сработало: Apache требует сертификат клиента, отклоняет соединение, если указанный сертификат клиента не предоставлен, и принимает его, если он есть.m добавляя сертификат MyClientCertificate в список сертификатов CA в / etc / ssl / certs, как доверенный сертификат сам по себе, и с помощью SSLCADNRequestFile я говорю, что мой сервер должен запрашивать только этот сертификат (и только он) клиенту, не весь список сертификатов CA в SSLCACertificatePath + SSLCACertificateFile

  • с "SSLVerifyDepth 1" Я говорю, что разрешенный сертификат клиента подписан ЦС, который входит в число тех, которые распознаются сервером (в SSLCACertificatePath)
  • Это казалось для работы: Apache требует сертификат клиента, отклоняет соединение, если указанный сертификат клиента не предоставлен, и принимает его, если он есть.m добавляя сертификат MyClientCertificate в список сертификатов CA в / etc / ssl / certs, как доверенный сертификат сам по себе, и с помощью SSLCADNRequestFile я говорю, что мой сервер должен запрашивать только этот сертификат (и только он) клиенту, не весь список сертификатов CA в SSLCACertificatePath + SSLCACertificateFile

  • с "SSLVerifyDepth 1" Я говорю, что разрешенный сертификат клиента подписан ЦС, который входит в число тех, которые распознаются сервером (в SSLCACertificatePath)
  • Это казалось для работы: Apache требует сертификат клиента, отклоняет соединение, если указанный сертификат клиента не предоставлен, и принимает его, если он есть.я говорю, что мой сервер должен запрашивать у клиента только этот сертификат (и только его), а не весь список сертификатов CA в SSLCACertificatePath + SSLCACertificateFile

  • с «SSLVerifyDepth 1». Я говорю, что разрешенный сертификат клиента подписан CA, который входит в число тех, которые распознаются сервером (в SSLCACertificatePath)
  • Казалось, что это сработало: Apache требует сертификат клиента, отклоняет соединение, если указанный сертификат клиента не предоставлен, и принимает его, если он есть.я говорю, что мой сервер должен запрашивать у клиента только этот сертификат (и только его), а не весь список сертификатов CA в SSLCACertificatePath + SSLCACertificateFile

  • с «SSLVerifyDepth 1». Я говорю, что разрешенный сертификат клиента подписан CA, который входит в число тех, которые распознаются сервером (в SSLCACertificatePath)
  • Казалось, что это сработало: Apache требует сертификат клиента, отклоняет соединение, если указанный сертификат клиента не предоставлен, и принимает его, если он есть.m, говоря, что разрешенный сертификат клиента подписан ЦС, который входит в число тех, которые распознаются сервером (в SSLCACertificatePath)

    Это похоже сработало: Apache требует сертификат клиента, отклоняет соединение, если указанный сертификат клиента не предоставляется и примите это, если это так.m, говоря, что разрешенный сертификат клиента подписан ЦС, который входит в число тех, которые распознаются сервером (в SSLCACertificatePath)

    Это похоже сработало: Apache требует сертификат клиента, отклоняет соединение, если указанный сертификат клиента не предоставляется и примите это, если это так. Однако недавно клиент (который является для меня поставщиком) решил сменить свой сертификат клиента на новый (назовем его MyNewClientCertificate.pem) с 2048-битным шифрованием вместо 1024-битной глубины старого. Проблема заключается в следующем:

    • поставщик заявляет, что он изменил свой сертификат клиента и теперь использует новый сертификат для аутентификации.
    • поставщик уверенно заявляет, что он представляет себя ТОЛЬКО с новым сертификатом, а не с обоими новыми и старый
    • Я еще не изменил свою конфигурацию Apache (следовательно, мой Apache все еще настроен на запрос старого сертификата)
    • НО мой Apache принимает соединения клиента поставщика без каких-либо проблем !! Я ожидал, что он начнет выходить из строя, пока я не изменю его конфигурацию, чтобы заменить MyClientCertificate. pem ссылки с MyNewClientCertificate.pem

    Новый сертификат выдается тем же ЦС, что и старый. Поставщик предполагает, что моя конфигурация Apache, вероятно, принимает все подключения от клиентов, которые представляют сертификат, выданный этим ЦС, вместо того, чтобы выполнять сопоставление с самим сертификатом клиента.

    Если это так, то что я делаю неправильно в моем конфигурация? Следует ли мне снизить SSLVerifyDepth до 0? (но разве это не говорит о том, что сертификат должен быть самоподписанным?) Или мне нужно что-то изменить в директивах SSLCACertificateFile / SSLCADNRequestFile?

    Поскольку эта система находится в производстве, у меня нет возможности выполнять все тесты, которые я могу придумать, но я должен попытаться внести целенаправленные изменения, чтобы получить правильный результат как можно быстрее. Вот почему я был бы признателен за любую помощь по этой теме.

    2
    задан 5 January 2016 в 12:30
    1 ответ

    Вы можете сопоставить конкретный сертификат клиента, используя директиву 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>
    
    2
    ответ дан 3 December 2019 в 11:34

    Теги

    Похожие вопросы