はじめに
プライベート認証局 とは何なのか、引いては認証局・サーバ証明書とは一体何に用いられるものなのかという事について、実際にプライベート認証局を構築することで理解を整理したいと思います。
以前httpsが何故安全なのかという理由をざっくりとまとめた記事がありますので、こちらと併せて読むとより理解が深まると思います。
認証局と証明書
自分はこれまで電子署名関連の知識が曖昧なままWEBサーバをいくつも公開してきました。電子署名とはなりすましやデータ改ざんを防ぐための技術のことです。私達のブラウザには信頼できる認証局と呼ばれる外部ホストからダウンロードしてきた証明書というものが自動でインストールされています。
Webページを見るなどしてWebサーバにアクセスする時に、そのサーバが本当に信頼出来るのかどうかを、サーバが発行した証明書とブラウザが持っている証明書を照らし合わせて判断しているのです。
プライベート認証局
しかしながら時折開発の現場などでは、本来の認証局を利用して証明書を発行せずに、信頼できるWebサーバを構築したいことがあります。セキュリティ関連の検証であればなおのことです。そんな一時的に信頼できるWebサーバのふりを実現するための技術がプライベート認証局と呼ばれるものになります。通称オレオレ認証局です。
今回の様な学習目的や個人利用のサーバ運用であれば、サーバ証明書を発行する認証局は自分で立ててしまう場合もあるのです。
おおまかな構築の流れ
- プライベート認証局の設定
- プライベート認証局の証明書作成
- サーバ証明書作成
少し調べてみると証明書の作成にCAスクリプトを使用していたり、opensslコマンドを使用していたりと色々な方法があるように見えますが、結局はCAスクリプトの中でopensslコマンドを打っているだけなのでどちらも基本的には同じです。
プライベート認証局 構築手順
プライベート認証局 の構築と言っても大体のLinux OSであれば自動化ツールが備わっているので設定ファイルを一部編集するだけで構築する事が出来ます。
1. プライベート認証局 の設定ファイル作成
標準の設定ファイルをコピーして、それを今回立てるプライベート認証局 用に編集していきます。
※CA/サーバ/クライアント用証明書の設定ファイルコピー元は全て同じです。
# yum install openssl
# cp /etc/pki/tls/openssl.cnf /etc/pki/tls/openssl-ca.cnf
# vi /etc/pki/tls/openssl-ca.cnf
# diff openssl.cnf openssl-ca.cnf
73c73
< default_days = 365 # how long to certify for
---
> default_days = 3650 # how long to certify for
172c172
< basicConstraints=CA:FALSE
---
> basicConstraints=CA:TRUE
178c178
< # nsCertType = server
---
> nsCertType = sslCA, emailCA
190c190
< # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
---
> keyUsage = cRLSign, keyCertSign
↑変更前と変更後の差分を出力しました。
- default_days:
- 有効期限
- basicConstraints=CA:TRUE :
- [ usr_cert ]セクション
- 各ブラウザ/メールソフト等に証明書と認識させる
- nsCertType = sslCA, emailCA:
- [ usr_cert ]セクション
- CA用
- keyUsage = cRLSign, keyCertSign:
- [ usr_cert ]セクション
- 証明失効リストの検証と鍵署名用(鍵の用途)
2.プライベート認証局 の証明書作成
まずはプライベート認証局 の秘密鍵を作成する。
# pwd
/root/CA (任意のディレクトリ)
# openssl genrsa -des3 -out ./ca.key 2048 -config /etc/pki/tls/openssl-ca.cnf
Generating RSA private key, 2048 bit long modulus
................................................................+++
..................................................+++
e is 65537 (0x10001)
Enter pass phrase for ./ca.key:【CA秘密鍵パスフレーズ】
Verifying - Enter pass phrase for ./ca.key:【CA秘密鍵パスフレーズ】
# ls
ca.key
# chmod 400 ca.key
先程の秘密鍵を使用してプライベート認証局 の証明書を作成する。
# openssl req -new -x509 -days 3650 -sha256 -key ./ca.key -out ./ca.crt -config /etc/pki/tls/openssl-ca.cnf
Enter pass phrase for ./ca.key:【CA秘密鍵パスフレーズ】
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) []:Tokyo
Locality Name (eg, city) [Default City]:Shinjuku
Organization Name (eg, company) [Default Company Ltd]:Momozo Company Ltd
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:XXX.XXX.XXX.XXX
Email Address []:XXXXXXX@example.com
※Common Nameのみ必須でホスト名を入力。各値はブラウザで証明書を開いた際表示される。更新の通知などがEmail Address宛に送信される。
# ls
ca.crt ca.key
※ちなみにこのコマンドでは設定ファイルの[ req ]セクションが読まれます。
次にブラウザにインポートする用にder形式の証明書も作成する。
# openssl x509 -inform pem -in ./ca.crt -outform der -out ./ca.der
# ls
ca.crt ca.der ca.key
# cp ca.key /etc/pki/CA/private/
# co ca.crt /etc/pki/CA/
# cp ca.crt /usr/share/pki/ca-trust-source/anchors/
# update-ca-trust extract
※各ディレクトリに配置。3つ目はCentOSにも信頼させるために実行する。
後々必要になるファイルもここで作成しておく。
# touch /etc/pki/CA/index.txt
# echo '1000' > /etc/pki/CA/serial
- index.txt:
- 署名した証明書の情報を保存するインデックスファイル
- serial:
- 証明書のラベル付けに使用するシリアルファイル
3.サーバ証明書の設定ファイル作成
CAと同様に設定ファイルをコピーして サーバ証明書用に編集する。
# cp /etc/pki/tls/openssl.cnf /etc/pki/tls/openssl-server.cnf
# vi /etc/pki/tls/openssl-server.cnf
# diff openssl.cnf openssl-server.cnf
73c73
< default_days = 365 # how long to certify for
---
> default_days = 3650 # how long to certify for
178c178
< # nsCertType = server
---
> nsCertType = server
- default_days:
- 有効期限
- nsCertType = server:
- [ usr_cert ]セクション
- サーバ証明書用
4.サーバ証明書作成
サーバ証明書の秘密鍵を作成する。
# pwd
/root/SV (任意のディレクトリ)
# openssl genrsa 2048 > server.key
Generating RSA private key, 2048 bit long modulus
..................+++
................+++
e is 65537 (0x10001)
※-des3オプションで生成された鍵にパスフレーズで暗号化を掛けることも可能
# ls
server.key
# chmod 400 server.key
証明書署名要求を作成する。
# openssl req -new -key server.key -sha256 -config /etc/pki/tls/openssl-server.cnf > server.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) []:Tokyo
Locality Name (eg, city) [Default City]:Shinjuku
Organization Name (eg, company) [Default Company Ltd]:Momozo Company Ltd
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:XXX.XXX.XXX.XXX
Email Address []:XXXXXXXXX@example.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
# ls
server.csr server.key
先程作成したプライベート認証局にて署名を行う。
# openssl ca -in server.csr -keyfile /etc/pki/CA/private/ca.key -cert /etc/pki/CA/ca.crt -out server.crt -config /etc/pki/tls/openssl-server.cnf
Using configuration from /etc/pki/tls/openssl-server.cnf
Enter pass phrase for /etc/pki/CA/private/ca.key:
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 4096 (0x1000)
Validity
Not Before: Jan 25 13:53:51 2020 GMT
Not After : Jan 22 13:53:51 2030 GMT
Subject:
countryName = JP
stateOrProvinceName = Tokyo
organizationName = Momozo Company Ltd
commonName = xxx.xxx.xxx.xxx
emailAddress = XXXXXXXXXXXXX@example.com
~ 中略(csrの内容が表示される) ~
Certificate is to be certified until Jan 22 13:53:51 2030 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
# ls
server.crt server.csr server.key
5.Webサーバ設定(Apache)
サーバ証明書とその秘密鍵を管理しやすい場所に移動する。
# mkdir -p /etc/httpd/conf.d/certs/xxx.xxx.xxx.xxx (任意のディレクトリ)
# mv server.crt /etc/httpd/conf.d/certs/xxx.xxx.xxx.xxx/
# mv server.key /etc/httpd/conf.d/certs/xxx.xxx.xxx.xxx/
設定ファイルを編集する。
# cp /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf.org
# vi /etc/httpd/conf.d/ssl.conf
# diff /etc/httpd/conf.d/ssl.conf.org /etc/httpd/conf.d/ssl.conf
59,60c59,60
< #DocumentRoot "/var/www/html"
< #ServerName www.example.com:443
---
> DocumentRoot "/var/www/html"
> ServerName xxx.xxx.xxx.xxx:443
100c100
< SSLCertificateFile /etc/pki/tls/certs/localhost.crt
---
> SSLCertificateFile /etc/httpd/conf.d/certs/xxx.xxx.xxx.xxx/server.crt
107c107
< SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
---
> SSLCertificateKeyFile /etc/httpd/conf.d/certs/xxx.xxx.xxx.xxx/server.key
サービスを再起動する。
# systemctl restart httpd
6.ブラウザに証明書をインストール
ブラウザに今回作成したCA証明書をインポートせずにWebサーバにアクセスすると次のような状態になるかと思います。今回はFirefoxを使用します。
セキュリティ設定から証明書をインポートすると次のようになります。