У меня возникли трудности с аутентификацией клиента nginx при использовании промежуточного ЦС (созданного самостоятельно).
Хотя один и тот же комплект сертификатов (промежуточные + корневые сертификаты в одном файле .pem) отлично работает для аутентификации клиентов в IMAP (dovecot) и SMTP (postfix), я просто не могу заставить его работать с nginx. Вместо этого я получаю следующую ошибку:
[info] 23383#23383: *14583139 client SSL certificate verify error: (27:certificate not trusted) while reading client request headers, client: 82.39.81.156, server: <hostname>, request: "GET /mailboxes HTTP/1.1", host: "<hostname>"
Насколько я понимаю, ошибка типа 27 из openssl - это X509_V_ERR_CERT_UNTRUSTED
, или какая-то проблема с сертификатом, который не является доверенным для определенной цели, однако я не могу объяснить это подробнее.
Кажется, что отдельные и объединенные сертификаты правильно проверяются с помощью openssl verify
(Я могу проверить сертификаты клиента по промежуточному звену или пакету, и промежуточный сертификат проверяется на соответствие корневому сертификату, то есть все это действительно во всех комбинациях, которые я могу придумать).
Мои корневой и промежуточный центры сертификации должны быть настроены с правильными расширениями для проверки моих клиентских сертификатов, вот соответствующий образец моего пользовательского openssl.conf
файл:
[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
Между тем клиентские сертификаты, которые я выдаю, настроены для работы как для аутентификации клиента, так и для шифрования / подписи электронной почты следующим образом:
[ user_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectAltName = email:move
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = critical, clientAuth, emailProtection
(действительно, если бы они не были установлены правильно, Safari и Mail OS X не позволили бы мне их отправлять, поскольку они, как правило, очень строгие).
Для ряда похожих вопросов рекомендована установка ssl_verify_depth
до значения 2 (для проверки как промежуточных, так и корневых сертификатов), но это, похоже, не помогает.
У меня такая же установка, и я пытался диагностировать именно эту проблему. Сертификаты отлично работали на экземпляре apache, но проблема была с nginx. Это решение, которое я придумал.
Укажите свой ssl_client_certificate
в вашем корневом сертификате. Не ваше промежуточное звено. Затем также убедитесь, что nginx проверяет глубину 2. Я пробовал использовать файл цепочки сертификатов в качестве параметра для сертификата клиента, но он все равно не работал. Я не понимаю почему это имеет быть корневым, а не промежуточным, подписавшим сертификат. Но это работает.
Для полноты, вот как выглядят соответствующие части моей конфигурации nginx:
server {
listen 8443 ssl;
server_name www.example.com;
ssl on;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.key;
ssl_client_certificate /path/to/root.ca.cert;
ssl_verify_client on;
ssl_verify_depth 2;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers <snipped-for-length>;
}