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

ошибка проверки сертификата SSL клиента: (27: сертификат не доверяет)

У меня возникли трудности с аутентификацией клиента 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>;
}