クライアント証明書による認証は、追加の機器などを必要とせずに比較的確実にアクセスを制限できるため便利です。またサーバー証明書と異なり、自前発行の証明書でもブラウザーのエラーにならないため、セキュリティ意識を下げる危険が少ない点も手軽と言えます。CA証明書発行→クライアント証明書発行の手間が問題にならなければ、期限切れのつどCA証明書から作り直すことも可能です。
今回は、nginxにクライアント証明書認証を設定した際に、サーバーから証明書を要求する第一歩目のリクエストが動作しなかったケースをレポートします。
nginxに設置するサーバー側のCA証明書の設定によって、ブラウザへのクライアント証明書要求がスタートせず、証明書を選択するダイアログが表示されない場合があります。
この場合の挙動は、認証モードの設定により以下の2パターンのエラーが返っています。
ssl_verify_client: on
→ 400 Bad Requestエラーssl_verify_client: optional
→ 403 Forbiddenエラー
原因は、CA証明書のBasic Constraintsの設定でした。
ファイルの内容を確認すると、適切に動作する証明書ファイルはCA: TRUE
になっています。
X509v3 extensions:
X509v3 Basic Constraints:
CA:TRUE
一方、要求がスタートしなかったファイルはCA: FALSEに設定されています。
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
なお、証明書ファイルの内容は、openssl x509 -text -noout -in some_cert_file_name
コマンドで表示できます。
また、ブラウザなどのクライアント側にインストールする証明書ファイルはCA: FALSE
で問題ありません。
debianのopensslパッケージで作成されるCA証明書ではとくに設定することなく、CA: TRUE
の証明書が生成されます。
ただし、証明書にはCA証明書のほかに、サーバー証明書(一般的なSSL証明書)・クライアント証明書があるため、ファイル種別を混同した場合、このような原因の分かりづらいエラーに遭遇することがあります。
ブラウザを再起動してアクセスしたり、数種類のブラウザでアクセスしても400 Bad Requestになり証明書の要求もない場合、同様のケースの可能性があります。
設定切り替えの方法
CAのモード設定は、以下のとおり、openssl.cnfのuser_certセクションで指定できます。
[ user_cert ]
basicConstraints=CA:TRUE
Chuma Takahiro