web-dev-qa-db-ja.com

クライアントSSL証明書の検証エラー:(27:証明書が信頼されていません)

中間CA(自己作成)を使用しているときに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>"

私が理解しているように、opensslのエラータイプ27はX509_V_ERR_CERT_UNTRUSTED、または特定の目的のために信頼されていない証明書に関するある種の問題ですが、これ以上詳しく説明することはできません。

個々の証明書とバンドルされた証明書はすべてopenssl verifyで正しく検証されているようです(クライアント証明書は中間証明書またはバンドルに対して検証でき、中間証明書はルート証明書に対して検証されます。つまり、考えられるすべての組み合わせですべて有効です。 )。

クライアント証明書を検証するには、ルートCAと中間CAに正しい拡張子を設定する必要があります。カスタム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

(実際、それらが正しく設定されていないと、OS XのSafariとMailでは、本当に厳格になる傾向があるため、まったく送信できませんでした)。

多くの同様の質問で、ssl_verify_depthを値2に設定することが推奨されています(中間証明書とルート証明書の両方を検証するため)が、これは役に立たないようです。

2
Haravikk

私は同じ設定をしていて、この正確な問題を診断しようとしています。証明書はApacheインスタンスで問題なく機能しましたが、nginxが問題でした。これが私が思いついた解決策です。

ssl_client_certificateをルート証明書に向けます。あなたの中間ではありません。次に、nginxが深さ2まで検証することも確認します。クライアント証明書のパラメーターとして証明書チェーンファイルを使用しようとしましたが、それでも機能しませんでした。なぜhasが証明書に署名した中間者ではなくルートになるのか理解できません。しかし、これは機能します。

完全を期すために、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>;
}
4
lcarsos