ひとつのホスト内で、ディレクトリ毎に別のクライアント証明書でアクセス制限をする話。
例えば、https://www.exsample.jp/users1/ は、HOGE1 というクライアント証明書を PC にインポートしている人だけ、https://www.exsample.jp/users2/ は HOGE2 というクライアント証明書を PC にインポートしている人だけがアクセス可能とする。
手順としては、プライベート CA 認証局はそのまま使用し、クライアント証明書の作成のみを追加で行う。
今回は、Common Name のみを変更(HOGE1→HOGE2)したクライアント証明書を追加で作成した。
今更だが手順は、
- クライアント証明書の作成(この時、以前作ったのとは別の Common Name にする)
- クライアント証明書にプライベート CA 認証局の署名を入れる
- 署名を入れたクライアント証明書と秘密鍵を元に PKCS#12 フォーマットのファイルを作成(クライアントに配布するクライアント証明書)
- クライアント証明書から-----BEGIN CERTIFICATE-----~-----END CERTIFICATE-----を抜き出し別途保存(例:HOGE2.pem)
という感じ。
証明書を作成したら、ssl.conf の編集。認証を行うディレクトリそれぞれのディレクティブを記述。
<Directory "/var/www/html/users1">SSLRequireSSLSSLVerifyClient requireSSLVerifyDepth 1SSLRequire %{SSL_CLIENT_CERT} eq file("/etc/pki/CA/client/certs/HOGE1.pem")</Directory>
<Directory "/var/www/html/users2">SSLRequireSSLSSLVerifyClient requireSSLVerifyDepth 1SSLRequire %{SSL_CLIENT_CERT} eq file("/etc/pki/CA/client/certs/HOGE2.pem")</Directory>
こんな感じ。
クライアント(PC)から送られてくる証明書の内容と、-----BEGIN CERTIFICATE-----~-----END CERTIFICATE-----の部分を抜き出して保存している pem ファイルの内容を完全一致でチェックし、合っていなければアクセスを許さない。
つまり、各ディレクトリ毎に合ったクライアント証明書でアクセスしなければエラーとなる。
Organization Name と Common Name の両方が証明書と一致しているか等、チェック方法は他にもあるが、相当サーバのマシンスペックに問題がある場合でなければ、証明書の内容全体で確認する上記の方法が確実でいいんじゃないかと思う。
問題は「両方のディレクトリにアクセスしたい」人。
例えば、自 PC に HOGE1 と HOGE2 の二つのクライアント証明書をインポートしておき、 https://www.exsample.jp/users1/ にアクセスする時は HOGE1 の証明書を使い、users2 にアクセスする時は HOGE2 を使い・・・という具合にユーザの意志で証明書を切り替えることができないようだ。
う~ん。
なので、最初に HOGE2 で users2 にアクセスした人は、users1 にアクセスした時も HOGE2 の証明書が使われてしまいエラーになってしまう。
これ、何か良い方法あるのかね?
CA 局も作り直せば、どの証明書を使うか改めて聞いてくるとかあるんかな?
やっぱ、両方にアクセスできるクライアント証明書を別途発行するしかないのかね?
ちなみに、Chrome と Firefox で確認しました。