どの辺りに需要があるのか解りませんが、SVNのリポジトリにSSL経由でアクセスする際の認証をクライアント証明書で行う方法です。割りとサクっと出来るので、メモがてらに残しておきます。とりあえずSubversionの例で話していますが、クライアント証明書で認証を行うというのは地味に便利です。id+passでの認証より、恐らく安全性は高いと思います。
クライアント証明書とは?
そもそもクライアント証明書とは何でしょうか?クライアント証明書は個人用証明書とも呼ばれて、その名前の通りクライアントが誰かと証明する代物です。ご存知の通り、個人の証明にはID,Passwordが一般的です。ただこれだとID,パスワードの管理の問題や漏洩、代理ログインの問題があります。これに対して、クライアント証明書はPCなりスマートフォンにインストールするので、管理や漏洩の問題は小さいです。
ちなみにクライアント証明書は昔からあるけど、あまり使う機会がない代物だったのかもしれません。一方、最近はスマートフォンの普及でMDM(モバイルデバイス管理)が急速に普及してきたので、耳にする機会も増えたのかもしれません。
必要なもの
- Apache Httpd
- mod_ssl
- mod_dav_svn
- Open SSL
- Subversion
インストール
上記の各モジュールをインストールします。
Redhat/CentOS系だと、yumで一発です。
yum install httpd mod_ssl mod_dav_ssl subversion openssl
オレオレ証明局(CA)の立ち上げ
# vi /etc/pki/tls/openssl.cnf
v3_ca
basicConstraints = critical,CA:true
CAの証明書の作成
# cd /etc/pki/tls/misc/ # ./CA -newca CA certificate filename (or enter to create) Making CA certificate ... Generating a 2048 bit RSA private key ......+++ .............................................................+++ writing new private key to '/etc/pki/CA/private/./cakey.pem' Enter PEM pass phrase: Verifying - Enter PEM pass phrase: ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:JP State or Province Name (full name) []:Osaka Locality Name (eg, city) [Default City]:Osaka Organization Name (eg, company) [Default Company Ltd]:dkfj test Organizational Unit Name (eg, section) []:dkfj test Common Name (eg, your name or your server's hostname) []:dkfj Email Address []:hoge@example.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: Using configuration from /etc/pki/tls/openssl.cnf Enter pass phrase for /etc/pki/CA/private/./cakey.pem: Check that the request matches the signature Signature ok Certificate Details: Serial Number: 9c:da:d3:b2:64:56:49:c7 Validity Not Before: Feb 11 10:49:49 2012 GMT Not After : Feb 10 10:49:49 2015 GMT Subject: countryName = JP stateOrProvinceName = Osaka organizationName = dkfj test organizationalUnitName = dkfj test commonName = dkfj emailAddress = hoge@example.com X509v3 extensions: X509v3 Subject Key Identifier: 6B:DA:63:AE:9F:33:68:B4:91:EB:C1:27:E3:74:46:A6:B4:A3:7F:BA X509v3 Authority Key Identifier: keyid:6B:DA:63:AE:9F:33:68:B4:91:EB:C1:27:E3:74:46:A6:B4:A3:7F:BA X509v3 Basic Constraints: CA:TRUE Certificate is to be certified until Feb 10 10:49:49 2015 GMT (1095 days) Write out database with 1 new entries Data Base Updated
証明証を作ったので、元に戻しておきます。
# vi /etc/pki/tls/openssl.cnf
v3_ca
#basicConstraints = critical,CA:true
秘密鍵と証明書要求ファイル(CSR)の作成
秘密鍵と証明書要求ファイルを作成します。これは、どこで作っても良いです。まぁ同じサーバで作るのが楽でしょう。
$ openssl genrsa -out username-client.key 1024 $ openssl req -new -key username-client.key -out username-client.csr You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:JP State or Province Name (full name) []:Osaka Locality Name (eg, city) [Default City]:Osaka Organization Name (eg, company) [Default Company Ltd]:dkfj test Organizational Unit Name (eg, section) []:dkfj test Common Name (eg, your name or your server's hostname) []:username.local Email Address []:username@example.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:
デジタル証明書(crt)の作成
# openssl ca -out username-client-ca.crt -infiles username-client.csr パスワードを入力して、Yesを2回
ブラウザで使う為のPKCS#12の作成
# cat username-client.key username-client-ca.crt | openssl pkcs12 -export -out username-client.p12 -name "Username client key" Enter Export Password: Verifying - Enter Export Password:
Apacheの設定
ssl.confを編集します。
vi /etc/httpd/conf.d/ssl.conf SSLCACertificateFile /etc/pki/tls/certs/my-ca.crt SSLVerifyClient require SSLVerifyDepth 10
特定のパスのみ適応させたい場合は、SSLVerifyClient requireを全体ではなく
・SSLRequireSSL:接続をSSLに限定する
・SSLVerifyClient:CA局が発行した証明書を持つユーザーのみがhttpsに接続可能となる
SVNのリポジトリの公開例です。
証明書+ID,Pass認証をしています。
<Location /repos> DAV svn SVNParentPath /var/www/svn # Limit write permission to list of valid users. <LimitExcept GET PROPFIND OPTIONS REPORT> # Require SSL connection for password protection. SSLRequireSSL SSLVerifyClient require AuthType Basic AuthName "Authorization Realm" AuthUserFile /path/to/passwdfile Require valid-user </LimitExcept> </Location>
ブラウザの設定
IE の場合:
作成した、*.p12ファイルをクライアント側のPCにダウンロードしてください。
FireFoxの場合:
ツール -> オプション -> 詳細タブ -> 暗号化タブ -> 証明書を表示 -> あなたの証明書タブ -> インポート
Chrome:
IEの証明書をつかうので、インポートしていれば大丈夫です。
使い勝手の話なんですが、意外に便利です。
開発サーバがローカルのネットワークではなく、クラウド上のサーバ等に移動していることは多々あると思います。その時に公開するものの制限によっては、アクセス制限なし・基本認証等のアクセス制限・証明書によるアクセス制限・証明書+アクセス制限・VPNによる遮蔽と色々なレベルがあると思います。証明書だけ入れておけばいいよというレベルのアクセス制限ってのも意外にあるので、利便性の向上につながるのではないでしょうか?特にスマートフォンの開発等では?(オレオレ証明書の壁を超える対策が必要ですが。)