web-dev-qa-db-ja.com

特定のクライアント証明書に対してのみApacheでクライアント検証を実施する

クライアントが特定のSSLクライアント証明書を提示する場合にのみ、Apache WebサーバーにSSL接続を受け入れさせたい。つまり、1つのクライアントのみが許可され、特定のクライアント証明書(私も持っている)を使用する必要があります。

このクライアント証明書(「MyClientCertificate」と呼びましょう)は、CA(「MyCA」と呼びましょう)によって発行される通常のPEM証明書であり、その証明書も持っています。

これは、この目的のためにApache仮想ホストを構成した方法です(SSLクライアント検証に関連するオプションのみを報告しています)。

SSLVerifyClient require
SSLCACertificatePath /etc/ssl/certs
SSLCACertificateFile /etc/ssl/client/MyClientCertificate.pem
SSLCADNRequestFile /etc/ssl/client/MyClientCertificate.pem
SSLVerifyDepth 1

オプションの説明(または少なくとも私の意図の説明...):

  • 「SSLVerifyClientrequire」を使用して、Apacheに常にクライアント検証を実行し、失敗した場合は接続を拒否するように強制します
  • / etc/ssl/certsには、Apacheが認識できる他のすべての有名なCAの証明書である限り、MyCAのPEM証明書(必要なハッシュ+シンボリックプロセスを使用してシステムに適切にインストールされている)が含まれます。
  • sSLCACertificateFileを使用すると、MyClientCertificate証明書を/ etc/ssl/certs内のCA証明書のリストに、それ自体が信頼できる証明書として追加します。SSLCADNRequestFileを使用すると、サーバーはその証明書のみ(およびそれのみ)を要求する必要があると言っています。 SSLCACertificatePath + SSLCACertificateFile内のCA証明書のリスト全体ではなく、クライアントに対して
  • 「SSLVerifyDepth 1」を使用すると、許可されたクライアント証明書は、サーバー(SSLCACertificatePath内)で認識されるものの中にあるCAによって署名されます。

これは機能しているように見えました。Apacheはクライアント証明書を必要とし、指定されたクライアント証明書が提供されていない場合は接続を拒否し、提供されている場合はそれを受け入れます。ただし、最近、クライアント(私のサプライヤーです)は、クライアント証明書を変更することを決定しました。新しいもの(MyNewClientCertificate.pemと呼びましょう)は、古いものの1024ビットの深さではなく、2048ビットの暗号化を使用しています。問題はこれです:

  • サプライヤーは、クライアント証明書を変更し、認証に新しい証明書を使用していると述べています
  • サプライヤは、新しい証明書と古い証明書の両方ではなく、新しい証明書だけを提示していることを確認しています。
  • Apacheの構成をまだ変更していません(したがって、Apacheはまだ古い証明書を要求するように構成されています)
  • しかし、私のApacheは問題なくサプライヤークライアント接続を受け入れています!! MyClientCertificate.pem参照をMyNewClientCertificate.pemに置き換えるように構成を変更するまで、失敗し始めると予想していました。

新しい証明書は、古い証明書と同じCAによって発行されます。サプライヤーは、私のApache構成が、クライアント証明書自体で一致を実行するのではなく、そのCAによって発行された証明書を提示するクライアントからのすべての接続をおそらく受け入れることを示唆しています。

この場合、構成で何が間違っていますか? SSLVerifyDepthを0に下げる必要がありますか? (ただし、これは証明書が自己署名されている必要があるということではありませんか?)または、SSLCACertificateFile/SSLCADNRequestFileディレクティブで何かを変更する必要がありますか?

このシステムは本番環境にあるため、考えられるすべてのテストを実行することはできませんが、できるだけ早く正しい結果が得られるように、焦点を絞った変更を行う必要があります。これが、このトピックに関する助けをいただければ幸いです。

2
Mauro Molinari

SSLRequire ディレクティブを使用して特定のクライアント証明書を照合し、完全なサブジェクトDNまたはクライアントの証明書のCN部分のみと照合できます。

SSLRequire %{SSL_CLIENT_S_DN} eq "C=AU, ST=Some-State, L=Springfield, O=ServerFault.com, OU=Moderators, CN=HBruijn/[email protected]"   

SSLRequire %{SSL_CLIENT_S_DN_CN} eq "HBruijn/[email protected]"

使用する openssl x509 -in client.crt -text件名文字列を表示します。

より完全な設定は次のようになります:

SSLVerifyClient      none
SSLCACertificateFile conf/ssl.crt/ca.crt
SSLCACertificatePath conf/ssl.crt

<Directory /usr/local/Apache2/htdocs/secure/area>
  SSLVerifyClient      require
  SSLVerifyDepth       5
  SSLOptions           +FakeBasicAuth
  SSLRequireSSL
  SSLRequire           %{SSL_CLIENT_S_DN_CN} eq "HBruijn/[email protected]"
</Directory>
3
HBruijn