HTTPS + SVN でクライアント証明書を使ってみよう

今回の記事は、SVNのレポジトリに外部からアクセスする際にHTTPSを使用していると、認証が色々と面倒なので、クライアント認証を使用してみましょうという主旨です。

クライアント証明書による認証とは?

SSH の鍵認証のように、登録済みのファイルを持っている人しかアクセスできなくする方法です。

すごく単純ですが、ユーザ名とパスワードがあってもだめで、正しい証明書を持っているユーザのみがアクセスできる方法です。

とはいっても証明書はオレオレ証明局になってしまうので、ご利用は計画的にお願いします。

最終的にはどうなるの?

SVNのレポジトリにHTTPSでアクセスするすべてのマシンにクライアント証明書をインストールします。

パスワードは使ってもいいし、使わなくてもいいです。

手順

1. 証明局(CA)の立ち上げ

CA とは、Certificate Authorityの略です。
証明局と言っていますが、openssl がインストールされているマシンであれば、割と簡単に立ち上げることができます。

openssl に含まれているコマンド群で必要なことは全部できます。

大抵の場合opensslはインストールされているかと思いますが、インストールされていない場合は yum などでインストールしておきましょう。


# yum install openssl

a. CA に必要な証明書を作る


# vi /etc/pki/tls/openssl.cnf

ここでは、2行修正します。
[ CA_default ] の 「dir = ../../CA」を「dir = /etc/pki/CA」と適当な絶対パスに変更します。
[ v3_ca ] の 「basicConstraints = CA:FALSE」を「basicConstraints = CA:TRUE」と適当な絶対パスに変更します。

一つめは、単に相対パスがいやなので、修正しているだけです。2つめは、CAを最初に作るときだけ修正するようです。


# cd /etc/pki/tls/misc
# ./CA -newca

最初にエンターを押せば鍵と証明書が作成されます。
次にCA秘密鍵パスワードを入力します。このパスワードは厳重に保管されなければならないパスワードですね。
証明書の情報については、適当に入れておきましょう。
最後にCA秘密鍵パスワードを入力すれば、CAの元になる証明書は作成されます。


JP, Tokyo, Bunkyo, Asial Corp, system, ca.asial.co.jp, hoge@example.com, 空2つ

上記の場合、日本の東京の文京にある、アシアル株式会社のシステム部がこのCAを管理しているらしい。管理しているサーバ名は ca.asial.co.jp で、hoge@example.com で連絡が取れる、という意味になります。


# vi /etc/pki/tls/openssl.cnf

[ v3_ca ] の「basicConstraints = CA:TRUE」を「basicConstraints = CA:FALSE」に戻しておきましょう。

これで、CA側の準備は整いました。

2. 証明書要求ファイルの作成

これはどのサーバでやってもかまいません。CA のサーバ上でやってもいいし、クライアントマシンでやってもいいです。



<pre wp-pre-tag-5=""></pre>
nbsp;openssl genrsa -out joe-client.key 1024
<pre wp-pre-tag-5=""></pre>
nbsp;openssl req -new -key joe-client.key -out joe-client.csr
JP, Tokyo, Bunkyo Asial Corp, system, joe.local, joe@example.com, 空2つ

これで joe-client.csr という証明書要求ファイル(CSRファイル)ができたので、そのファイルを CA のサーバ上にSCPなりなんなりでコピーしておきます。

3. 署名

CSR ファイルは /var/certification/joe/joe-client.csr とします。


# cd /var/certification/joe
# openssl ca -out joe-client-ca.crt -infiles joe-client.csr
   秘密鍵パスワードを入力します
   y を2回入力します

この joe-client-ca.crt を CSRファイルを作成したマシンに移します。

4. 証明書のパッケージ作成

joe-client-ca.crt だけでは、ブラウザに設定したり、svn で使用することができません(おそらく)。

使用するためには、PKCS#12 というフォーマットに落とし込む必要があります。



<pre wp-pre-tag-7=""></pre>
nbsp;cat joe-client.key joe-client-ca.crt | openssl pkcs12 -export -out joe-client.p12 -name "Joe client key" 

適当にパスワードを指定してください。
この joe-client.p12 をブラウザ・Windows・svn で指定することになります。

5. サーバ側の設定

せっかく作った証明書もSSLをちゃんと設定してあげないと、使うことができません。
このCAを使ったクライアント認証をしたい場合の設定が以下になります。

まず、どのCAが署名した証明書を許可するのか、というのを指定する必要があります。一般的にはVerisignとかが署名してたら信頼できると思いますが、その場合でもApacheにVerisignの情報を教えてあげないとチェックできません。

今回はオレオレCAの情報を指定します。そのためには、/etc/pki/CA/cacert.pem を使用します。同じサーバ上なので、普通に cp すればオッケーです。


# cp /etc/pki/CA/cacert.pem /etc/pki/tls/certs/my-ca.crt

このファイルを Apache の ssl.conf で指定します。


SSLCACertificateFile /etc/pki/tls/certs/my-ca.crt
SSLVerifyClient require
SSLVerifyDepth  10

最初の SSLCACertificateFile はどのCAが署名した証明書だったら許可するのか、ということを指定します。今回は自分のCAですよね?だから、自分のCAのファイルを指定します。

ここで、注意なのが SSLCertificateFile とは全く関係がないということです。SSLCertificateFile はブラウザがアクセスしているサーバが正しい善いサーバなのかを「ブラウザ」が検証するためのものです。

SSLCACertificateFile は「サーバ」が正しい善いクライアントからのアクセスかを検証するためのものです。なので、この2つは全くの別物なんです。

これで、HTTPDを再起動すれば、SSLでのアクセスに対して、クライアント認証が要求されます。

ブラウザにも設定しておかないと、再起動した瞬間からアクセスできなくなってしまうので気をつけてください。

6. ブラウザの設定

IE の場合
Windows に joe-client.p12 をダウンロードしてきて、ダブルクリックで指示に従えばおそらく問題ないです。。

Firefox の場合
ツール -> オプション
詳細タブ -> 暗号化タブ -> 証明書を表示
あなたの証明書タブ -> インポート

ダウンロードした joe-client.p12 をインポートすれば問題ないです。

Linux の svn コマンドを使う場合
# vi ~/.subversion/servers
[global]
ssl-client-cert-file=/home/joe/certification/client.p12

みたいにすればよい。

Windows で TortoiseSVN を使う場合
アクセスしたときにファイルを参照するから、joe-client.p12 を指定すれば大丈夫です。

ここからも重要ですが、期間を制限された証明書を発行する場合は、/etc/pki/tls/openssl.cnfのdefault_days を 365(1年)から30とかにするとよいです。

HTTPSでアクセスするマシンを制限する場合は、結構有用だったりする知識なので、一度ローカルなどで試してみるとよいかもしれません。