Я настраиваю Apache для аутентификации по смарт-карте. Вход со смарт-картой основан на клиентских SSL-сертификатах, обрабатываемых драйвером ОС.
В настоящее время у меня только один поставщик смарт-карт, но в будущем их может быть несколько. Я не уверен, как Apache 2.2. обрабатывает сертификаты на стороне клиента для каждого местоположения. Я провел небольшое тестирование, и почему-то показалось, что только последняя директива SSLCACertificateFile будет эффективной, и это звучит неправильно.
Возможно ли иметь разные SSLCACertificateFile для каждого местоположения в Apache (2.2, 2.4), как описано ниже, или протокол SSL каким-то образом ограничивает то, что у вас не может быть более одного SSLCACertificateFile для каждого IP-адреса?
Пример потенциальной конфигурации ниже, как я хочу обрабатывать несколько SSLCACertificateFile на одном сервере, чтобы пользователи могли входить в систему с разными смарт-картами.
<VirtualHost 127.0.0.1:443>
# Real men use mod_proxy
DocumentRoot "/nowhere"
ServerName local-apache
ServerAdmin you@example.com
SSLEngine on
SSLOptions +StdEnvVars +ExportCertData
# Server-side HTTPS configuration
SSLCertificateFile /etc/apache2/certificate-test/server.crt
SSLCertificateKeyFile /etc/apache2/certificate-test/server.key
# Normal SSL site traffic does not require verify client
SSLVerifyClient none
SSLVerifyDepth 999
# Provider 1
<Location /@@smartcard-login>
SSLVerifyClient require
SSLCACertificateFile /etc/apache2/certificate-test/ca.crt
# Apache does not natively pass forward headers
# created by SSLOptions +StdEnvVars,
# so we pass them forward to Python using RequestHeader
# from mod_headers
RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e
RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e
</Location>
# Provider 2
<Location /@@smartcard-login-provider-2>
# For real
SSLVerifyClient require
SSLCACertificateFile /etc/apache2/certificate-test/provider2.crt
# Apache does not natively pass forward headers
# created by SSLOptions +StdEnvVars,
# so we pass them forward to Python using RequestHeader
# from mod_headers
RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e
RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e
</Location>
# Connect to Plone ZEO client1 running on fg
ProxyPass / http://localhost:8080/VirtualHostBase/https/local-apache:443/folder_sits/sitsngta/VirtualHostRoot/
ProxyPassReverse / http://localhost:8080/VirtualHostBase/https/local-apache:443/folder_sits/sitsngta/VirtualHostRoot/
</VirtualHost>
Как ответил Властимил Зима, вы действительно можете использовать SSLRequire
для этого (по крайней мере, если вы хотите / должны делать разницу между двумя центрами сертификации). В противном случае достаточно просто объединения двух сертификатов в один (как спросил Кертис: да, вы можете просто объединить сертификаты, чтобы сделать что-то вроде этой работы). И, глядя на ваш пример, достаточно просто комбинирования.
С SSLRequire
вы можете проверить эмитента (при условии, что CN разные), например:
<Location /locationone>
SSLRequire %{SSL_CLIENT_I_DN_CN} == "THE CN OF THE FIRST ISSUER"
</location>
<Location /locationtwo>
SSLRequire %{SSL_CLIENT_I_DN_CN} == "THE CN OF THE SECOND ISSUER"
</location>
И чтобы это работало, вам все равно нужно объединить 2 сертификата CA в один.
Директива SSLCACertificateFile
имеет контекст виртуального хоста, поэтому он повлияет на весь виртуальный хост, даже если он вставлен в Location
. Вам нужно использовать SSLRequire
чтобы проверить, использует ли клиент правильный сертификат для определения местоположения.
http://httpd.apache.org/docs/2.2/mod/mod_ssl.html#sslrequire