Carpe Diem

備忘録。https://github.com/jun06t

クライアント証明書でアクセスコントロール

SSLでの証明書はサーバ側が発行するもの、というのが普通の認識ですが、当然クライアント側でも自己証明のために証明書を発行することができます。

このクライアント証明書を用いてちょっとしたユーザのアクセス制御を用いることができます。

サーバー側で「クライアント証明書を持ってないとアクセスできない」という設定ができるので、所持している特定のグループ以外は排除できます。一種のログイン認証ですね。パスワードを覚える手間がないのでクライアントにやさしいです。

 

 

◆作成手順

本来の使用法でしたらこれは

クライアント側で証明書要求を作成し、認証局(サーバ)に送る

認証局で証明書要求に署名、できたクライアント証明書をクライアントに送る

クライアント側でブラウザにインストールする

いう流れです。

が、全てのクライアントがそういったスキルがあるわけでもないのでサーバ側で作成することもあります。今回はサーバ側で全てやります。つまり

サーバ側でクライアント用の証明書要求を作成

開設した認証局で署名

できたクライアント証明書を、クライアント(目的の人物ら)に配布

クライアントはそれを受け取ってインストール

ということです。単にアクセス制御したいだけなので後者の方法で十分です。

 

◆インストール

$ sudo aptitude install openssl

 

◆クライアントの秘密鍵の作成

クライアント側で秘密鍵と証明書要求(中間証明書)を作成します。

# mkdir /etc/ssl/CA # cd /etc/ssl/CA $ sudo openssl genrsa -aes256 -out client.key 2048

Enter pass phrase for client.key:yyyy # パスフレーズ設定

Verifying - Enter pass phrase for client.key:yyyy # 確認再入力

 

パスフレーズの削除

$ sudo openssl rsa -in client.key -out client.key

Enter pass phrase for client.key:yyyy # さきほどのパスフレーズを入力

writing RSA key

 

秘密鍵から証明書要求の作成

$ sudo openssl req -new -days 3650 -key client.key -out client.csr

Country Name (2 letter code) [AU]:JP # 国

State or Province Name (full name) [Some-State]:Tokyo # 地域(県)

Locality Name (eg, city) :Tokyo # 都市

Organization Name (eg, company) [Internet Widgits Pty Ltd]:○○ # 組織名

Organizational Unit Name (eg, section) :IT Solution # 組織の部門

Common Name (eg, YOUR name) :www.○○○.com # サーバーのFQDN(ホスト名)

Email Address :xxx@yahoo.co.jp # 管理者アドレス

 

認証局の開設

クライアントの証明書に署名するための認証局をサーバ側で開設します。

この認証局に署名されている=このクライアントは本物である

というチェックができるようになるわけです。

詳細は「ブラウザにルート証明書のインストール」を確認してください。こちらではコマンドのみを記します。

 

$ cd /usr/lib/ssl/misc $ sudo ./CA.sh –newca

Enter PEM pass phrase:zzzz ← 任意。認証局秘密鍵のパスワードになる

Verifying - Enter PEM pass phrase:zzzz

Country Name (2 letter code) [AU]:JP # 国

State or Province Name (full name) [Some-State]:Tokyo # 地域(県)

Locality Name (eg, city) :Tokyo # 都市

Organization Name (eg, company) [Internet Widgits Pty Ltd]:○○ # 組織名

Organizational Unit Name (eg, section) :IT Solution # 組織の部門

Common Name (eg, YOUR name) :www.○○○.com # サーバーのFQDN(ホスト名)

Email Address :xxx@yahoo.co.jp # 管理者アドレス

 

◆証明書要求に署名

クライアント証明書の署名要求ファイル(CSR)をCAで署名します。

$ cd /usr/lib/ssl/misc

$ sudo openssl ca -config /etc/ssl/openssl.cnf -in /etc/ssl/CA/client.csr -keyfile /usr/lib/ssl/misc/demoCA/private/cakey.pem -cert /usr/lib/ssl/misc/demoCA/cacert.pem -out /etc/ssl/CA/client.crt

 

もし failed to update database TXT_DB error number 2 が出たら demoCA/index.txt を削除して空ファイルを作ればOKです。下記を行なって再実行してください。

$ sudo rm demoCA/index.txt $ sudo touch demoCA/index.txt

 

◆クライアント証明書をブラウザにインストールできる形式に変換

クライアント証明書は PKCS#12形式 にする必要があります。

# openssl pkcs12 -export -inkey /etc/ssl/CA/client.key -in /etc/ssl/CA/client.crt -certfile /usr/lib/ssl/misc/demoCA/cacert.pem -out /etc/ssl/CA/client.p12

 

◆クライアント証明書をブラウザにインストール

Firefoxの場合

ツール→オプション→詳細→暗号化→証明書を表示 あなたの証明書タブ→インポート で、先程の client.p12 をインポートします。

 

Chromeの場合

設定→詳細設定を表示 HTTPS/SSLの証明書の管理→自分の証明書→インポート で、先程の client.p12 をインポートします。

 

Apache の設定

$ sudo emacs -nw /etc/apache2/sites-available/default-ssl

#SSLCACertificateFile /etc/apache2/ssl.crt/ca-bundle.crt

SSLCACertificateFile /usr/lib/ssl/misc/demoCA/cacert.pem

#SSLVerifyClient require

SSLVerifyClient require

編集したらリロードします。

$ sudo service apache2 reload

 

◆確認

クライアント証明書がない状態だと

SSL peer was unable to negotiate an acceptable set of security parameters. (エラーコード:ssl_error_handshake_failure_alert)

clientssl01.png

となります。 クライアント証明書があると、「It works」と表示されました。

 

◆補足

Apache でCA証明書の指定がないと以下のように

Peer does not recognize and trust the CA that issued your certificate. (エラーコード:ssl_error_unknown_ca_alert)

clientssl02.png

と表示されます。必ず指定しましょう。

 

ソース:

クライアント証明書ってなんだろう?その2

Apacheのクライアント認証をしてみた。

Apache2.2 SSLクライアント認証の設定 [Ubuntu]

SSL用証明書の作成(Linux編)