エラーメッセージ
verify error:num=19:self-signed certificate in certificate chain
別の表記
- verify error:num=19:self signed certificate in certificate chain
- error 19 at 2 depth lookup: self-signed certificate in certificate chain
OpenSSL 3.x は「self-signed」、1.1.1 は「self signed」と出力します。openssl verify はこれを「error 19 at <depth> depth lookup: …」として報告します。この depth は、チェーン内でのルートの位置です。
OpenSSL CLI (openssl s_client / openssl verify) — X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
このエラーの意味
OpenSSL のエラー 19(X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN)は、ピアから送られてきた自己署名のルート証明書までチェーンを構築できたものの、そのルートがトラストストアにないことを示します。エラー 18 とは異なり実際の CA 階層があり、エラー 20 とは異なり欠けているものはありません。ルートをローカルで信頼する必要があるか、そうでなければ接続が傍受されているかのどちらかです。
発生する理由
TLS を検査するプロキシ
よくある企業のプロキシは、独自のルートをチェーンに含めて送信します。最上位の証明書のサブジェクトに自社名やセキュリティベンダー名が記載されていれば、その接続は検査されています。
サーバーがルートを送信するプライベート CA
よくある社内サービスは、ルートを含む完全なチェーンを送信することがよくあります。それでも、クライアント側にはトラストアンカーとしてルートをインストールしておく必要があります。
想定したトラストストアを使わずにテストした
ときどき-CAfile が間違ったファイルを指している状態や、ストアに自社のルートがないイメージの中でテストすると、正しく設定された社内サービスに対してもこのコードが出ます。
修正方法
- 1.
ルートとそのフィンガープリントを特定する
返されたチェーンを分割し、各証明書のサブジェクト、発行者、SHA-256 フィンガープリントを出力してください。ルートのフィンガープリントを、IT チームや PKI チームが公開している値と比較してください。
bash openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \ | awk '/BEGIN CERT/{n++} {print > ("cert" n ".pem")}' for f in cert[0-9]*.pem; do openssl x509 -in "$f" -noout -subject -issuer -fingerprint -sha256 2>/dev/null; done - 2.
正しいルートでテストしてからインストールする
公開されているルートを -CAfile に指定して「Verify return code: 0 (ok)」になれば、そのルートをシステムのストアにインストールしてください。
bash echo | openssl s_client -connect api.example.com:443 -servername api.example.com \ -CAfile corp-root-ca.pem 2>&1 | grep 'Verify return code' sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt && sudo update-ca-certificates - 3.
サーバー管理者:リーフ証明書と中間証明書だけを送信する
ルートを送信しても、ハンドシェイクのたびにバイト数が無駄になるだけで、ルートが信頼されるようにはなりません。代わりに、ルートをクライアントに配布してください。
bash # Server owners: the root does not belong in the served chain cat server.pem intermediate.pem > fullchain.pem
関連するエラー
verify error:num=18:self-signed certificateOpenSSL CLI (openssl s_client / openssl verify)verify error:num=20:unable to get local issuer certificateOpenSSL CLI (openssl s_client / openssl verify)curl: (60) SSL certificate problem: self-signed certificate in certificate chaincurl (OpenSSL backend)self-signed certificate in certificate chainNode.js tls / https / fetch