エラーメッセージ
verify error:num=18:self-signed certificate
別の表記
- verify error:num=18:self signed certificate
- Verify return code: 18 (self-signed certificate)
- error 18 at 0 depth lookup: self-signed certificate
OpenSSL 3.x は「self-signed」、1.1.1 は「self signed」と出力します。s_client は「verify error:num=18:…」と「Verify return code: 18 (…)」を表示し、openssl verify は「error 18 at 0 depth lookup: …」を表示します。
OpenSSL CLI (openssl s_client / openssl verify) — X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
このエラーの意味
OpenSSL のエラー 18(X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)は、depth 0 の証明書が自己署名(発行者が自分自身)であり、トラストストアにも含まれていないことを示します。上位に CA がないため、中間証明書やバンドルでは解決できません。この証明書を直接信頼するか、CA が発行した証明書に置き換える必要があります。
発生する理由
サーバーが自己署名証明書を使っている
よくある開発用サーバー、アプライアンス、管理画面、インストールしたばかりのサービスは、自動生成された証明書で動作を始めることがよくあります。
不明な名前に対してデフォルトの証明書が返されている
ときどきリバースプロキシや Ingress は、設定のない名前に対して自己署名のデフォルト証明書で応答します。SNI とルーティングを確認してください。
ルート証明書に対して openssl verify を実行した
ときどき-CAfile root.pem を付けずに openssl verify root.pem を実行すると、自己署名のルートであれば、有効なものであってもエラー 18 が報告されます。
修正方法
- 1.
サブジェクトと発行者が同一であることを確認する
サブジェクトと発行者が同じであれば、その証明書は自己署名です。想定される値と比較すべきなのは、その証明書のフィンガープリントです。
bash echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \ | openssl x509 -noout -subject -issuer -fingerprint -sha256 # subject == issuer: self-signed - 2.
テスト用にその証明書だけを信頼する
証明書そのものを -CAfile として指定すると、OpenSSL はその証明書だけを受け入れます。先に、信頼できる経路でフィンガープリントを確認してください。
bash # Trust this exact certificate for a check (after confirming the fingerprint out of band) echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null | openssl x509 -out api.pem echo | openssl s_client -connect api.example.com:443 -servername api.example.com -CAfile api.pem 2>&1 | grep 'Verify return code' - 3.
ルートをそれ自身で検証する
自己署名のルートは、それ自体がトラストアンカーである場合にのみ検証に成功します。-CAfile として指定してください。
bash # Verifying a root CA certificate itself needs the root as its own trust anchor openssl verify -CAfile root.pem root.pem # root.pem: OK