クライアント証明書を要求するサイトの構築(Apache+OpenSSL)その1 の続き。
p12キーのOUの値からアクセス許可判定をする。
/etc/apache2/sites-enabled/default-ssl.conf
#httpアクセスが来たらhttpsに転送する。
<VirtualHost *:80>
ServerName democa.local
ServerAlias localhost
DocumentRoot /var/www/html
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteCond %{SERVER_NAME} !localhost
RewriteRule ^(.*)?$ https://%{HTTP_HOST}$1 [R,L]
</VirtualHost>
<VirtualHost _default_:443>
SSLEngine On
SSLCertificateFile /opt/demoCA/cert.pem
SSLCertificateKeyFile /opt/demoCA/nokey.pem
SSLCACertificateFile /opt/demoCA/cacert.pem
#SSLCARevocationFile /opt/demoCA/crl.pem
<Location />
SSLVerifyClient require
SSLRequire ( \
%{SSL_CLIENT_S_DN_OU} eq "kitamura" \
or %{SSL_CLIENT_S_DN_OU} eq "konaimura" \
or %{SSL_CLIENT_S_DN_OU} eq "imakitamura" \
# or %{REMOTE_ADDR} =~ m/^10\.0\.2\.15$/ \
)
</Location>
DocumentRoot /var/www/html
</VirtualHost>
アクセスさせたくないp12キーを持った人に対しては、以下の行を削除しapacheをreloadすれば良い。
- or %{SSL_CLIENT_S_DN_OU} eq "imakitamura" \
またこの方法を応用するとLocationごとにユーザーのアクセス許可ができる。
設定 | 備考 |
---|---|
SSLCertificateFile | pem か cer か crt を指定 |
SSLCertificateKeyFile | .keyを指定 |
SSLCACertificateFile | .p12を発行したCAの証明書 |
動作確認
動作確認
$ openssl s_client -connect localhost:443
- サーバーの証明書ファイルを入れ替えても、apacheをリスタートしないと反映されません。
-
unable to write 'random state'
と表示された場合、sudo rm $HOME/.rnd
拡張子対応表
拡張子 | 備考 | メモ |
---|---|---|
.key | 秘密鍵 | ---BEGIN RSA PRIVATE KEY--- |
.csr | CA(信頼された機関)に署名要求するもの。消してOK | Certificate Signing Request |
.crt | CAが.csrに「このサーバは確かに存在する」と署名したもの | Certificate |
.pem | 秘密鍵(.key),証明書(.crt),CAの中間証明書(.cer)を連結したもの | ------BEGIN CERTIFICATE------ |
.p12 | .pemをパスワード暗号化 | &0� �� � |
.crl | 証明書失効リスト | Certification Revocation List |
証明書の情報を表示
cert_info.sh
#!/bin/sh
set -u
if [ $# -eq 0 ];then
echo "チェック対象のファイル名を指定してください。"
exit 1
fi
if [ $# -gt 1 ];then
echo "チェック対象のファイルは一つにしてください。"
exit 1
fi
if [ ! -e "$1" ];then
echo "チェック対象のファイルが見つかりません。"
exit 1
fi
for mech in rsa req x509 crl
do
openssl $mech -text -in $1 && echo "[上のコマンド#] openssl $mech -text -in $1"
done
使い方
$ cert_info.sh /var/pkg/ssl/OpenSolaris_extras.key.pem
$ cert_info.sh test_client.cer
有効期限を表示
$ openssl s_client -connect qiita.com:443 | openssl x509 -noout -dates
phpでの判定
$_SERVER["SSL_CLIENT_S_DN"] // クライアント証明書のサブジェクト
$_SERVER["SSL_CLIENT_S_DN_CN"] // クライアント証明書のCN(CommonName)
SSL_CLIENT_S_DN ---- 証明書 Subject
SSL_CLIENT_S_DN_C ---- 国名
SSL_CLIENT_S_DN_ST ---- 都道府県名
SSL_CLIENT_S_DN_L ---- 都市名
SSL_CLIENT_S_DN_O ---- 組織名
SSL_CLIENT_S_DN_OU ---- 部署名
注意点
-
SSL_CLIENT_V_END
は日付が2038年を超えるとBad time value
になる様子。