してみるテストロゴ
Apache 2.4系でHTTP/2サーバを構築してみるテスト。

プライベートルート証明書・中間証明書・サーバ証明書の作り方

[2016年12月8日版]

プライベート認証局を作ってみようと思います。

一般の認証局のルート証明書は、OSやブラウザにインストールされた状態で、パソコンやスマートフォンが出荷されています。そのため、他人のパソコンやスマートフォンに対しても効力のある証明書を発行できます。

一方、プライベート認証局のルート証明書は、OSやブラウザに含まれて出荷されるわけではないので、他人のパソコンやスマートフォンに対するサービスには使用できません。

自分で、プライベート認証局のルート証明書をOSやブラウザにインストールしてから使うことになります。

 

きっかけとしては、Cisco社のWebVPNを利用するため、OpenSSLを使って、自分で簡単な認証局を作ってみました。

WebVPNを使いたい方は、このページを読んでから、以下のページをご覧ください。

認証局を作って、プライベートルート証明書から、サーバ証明書を生成する方法は、各所で紹介されておりますが、中間証明書を作成する例はあまり見かけません。

WebVPNは使わないよ、という方も、中間証明書にご興味のある方はご覧頂ければ幸いです。

認証局(CA)構築方針

ということで、まず、認証局の構築方針を定めます。

 

いわゆるエントリー系のCiscoのルータに、標準で付いてくるWebVPNのライセンス数が2だったりすることが多いので、少人数で利用することを念頭におきます。

そのため不特定多数に証明書の失効を知らせる必要性は低いはずです。

Online Certificate Status Protocol (OCSP)や、失効リスト(CRL)を運用しないことにします。

 

ルート証明書の有効期限については短すぎると不便です。一旦クライアントのパソコンにインストールしたら、放置したいところです。

 

そこで、考え得る最長の製品寿命より少し長い期間とするのが良いでしょう。

ルータ向けにしか署名しない場合、ルータの保守期限が5年なら、5年より少し長い程度の長さが良いでしょう。

ルート証明書を、無線LANのRADIUSサーバなどで共用し、PEAP等を使用することになる場合は、無線LANアクセスポイントか、RADIUSサーバの製品寿命も考慮して決めてください。

 

サーバ証明書は、Baseline Requirements v.1.0によって、最長39ヶ月となっているので、それを超えない3年程度の長さにします。

サーバ証明書は、Baseline Requirements v.1.4.4によって、最長825日となっているので、それを超えない2年程度の長さにします。

中間証明書をどちらの長さにするかは、悩ましいところですが、ルート証明書が5年程度なら、ルート証明書と同じにします。

 

今回作る認証局は、認証局と言っても、ルート証明書と中間証明書の有効期間に渡って、秘密鍵を保持して、外部に漏らさない環境とっいった、認証局としての最低限の要件とします。

とはいえ、ある程度は、通信できないと不便です。

イントラネットには接続できるけど、ファイアウォール外との通信を遮断したマシン、といったところが落としどころでしょうか。

そんなマシンが用意できたら、OpenSSLをインストールします。

あとは、パーミッションがしっかりしたフォルダが必要です。

ということで、以下のディレクトリを掘ります。

$ sudo su
# cd /usr/local/etc
# mkdir ca
# chmod 600 ca

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

プライベートルート証明書の作成

まずは、プライベートルート証明書の秘密鍵(ca.key)を作成します。

# cd /usr/local/etc/ca
# openssl genrsa -out ca.key -des3 2048
Generating RSA private key, 2048 bit long modulus
.......+++
....................+++
e is 65537 (0x10001)
Enter pass phrase for ca.key:(ca.keyのパスフレーズ)

Verifying - Enter pass phrase for ca.key:(ca.keyのパスフレーズ)[確認]

#

RSA暗号の秘密鍵(ca.key)の中身は、素数(prime)が2つ等です。

上記の例では、-des3でパスフレーズを入れています。

このファイルは、非常に重要なので、-des3以外に、OpenSSLが、 -aes128, -aes192, -aes256といった、AES暗号化に対応していたら、なるべく強い暗号(つまりaes256)で暗号化することをオススメします。

openssl_ca_root_key

続いて、この秘密鍵(ca.key)から、ルート証明書(ca.pem)を作成します。やることは、以下の図の通りです。

サーバ証明書を発行するときには、csrを作成しますが、ルート証明書は、いきなり署名します。

openssl_root_pem

この図をコマンドラインにすると、以下のコマンドになります。

有効期間は、5年(1825日)です。

# openssl req  -new -x509 -key ca.key -sha256  -days 1825 -extensions v3_ca  -out ca.pem  -subj "/C=JP/ST=Tokyo/O=example corp./CN=example root 2016"
Enter pass phrase for ca.key:(ca.keyのパスフレーズ)
#

一応、中身を確認します。

# openssl x509 -noout -text -in ca.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
	(…省略…)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=JP, ST=Tokyo, O=example corp., CN=example root 2016
        Validity
            Not Before: MMM DD HH:MM:SS YYYY GMT
            Not After : MMM DD HH:MM:SS YYYY GMT
        Subject: C=JP, ST=Tokyo, O=example corp., CN=example root 2016
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
	(…省略…)
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier:
	(…省略…)
            X509v3 Authority Key Identifier:
	(…省略…)

            X509v3 Basic Constraints:
                CA:TRUE
    Signature Algorithm: sha256WithRSAEncryption
	(…省略…)

このca.pemが、このプライベート認証局のルート証明書になります。

# cat ca.pem
-----BEGIN CERTIFICATE-----
(…省略…)
-----END CERTIFICATE-----

上記の、-----BEGIN CERTIFICATE----- から、-----END CERTIFICATE-----までの、紫色の背景の部分のテキストを、コピーしてクライアント機にテキストファイルとして貼り付けてください。

このとき-----BEGIN CERTIFICATE----- と-----END CERTIFICATE-----の行も含めます。

Windowsの場合、拡張子を.cerとすると、右クリックからインストールできるようになります。

中間証明書の作成

次に、中間証明書の秘密鍵(inca.key)を作ります。

# openssl genrsa -out inca.key -des3 2048
Generating RSA private key, 2048 bit long modulus
...............................................................................+++
............+++
e is 65537 (0x10001)
Enter pass phrase for inca.key:(inca.keyのパスフレーズ)
Verifying - Enter pass phrase for inca.key:(inca.keyのパスフレーズ[確認])

# 

これは、さきほどと同様です。

上記の例では、-des3でパスフレーズを入れています。

このファイルも、非常に重要なので、OpenSSLが、 -aes128, -aes192, -aes256といった、AES暗号化に対応していたら、なるべく強い暗号(つまりaes256)で暗号化することをオススメします。

openssl_inca_key

次に、中間証明書のCSR(Certificate Signing Request)を作ります。

openssl_inca_csr

プライベートルート証明書は、いきなり署名しましたが、中間証明書は、上位のルート証明書から署名するため、いったん、CSRを生成する必要があります。

# openssl req -new -key inca.key -sha256 -outform PEM -keyform PEM -out inca.csr  -subj "/C=JP/ST=Tokyo/O=example corp./CN=example Inter CA 2016"
Enter pass phrase for inca.key:(inca.keyのパスフレーズ)
# 

一応、CSRの中身を確認します。

# openssl req -noout -text -in inca.csr
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=JP, ST=Tokyo, O=example corp., CN=example Inter CA 2016
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
	(…省略…)
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha256WithRSAEncryption
	(…省略…)
# 

このCSRをもとに、証明書(inca.pem)を作成します。

準備として、中間証明書のための設定ファイルを用意します。

# vi openssl_sign_inca.cnf
/usr/local/etc/ca/openssl_sign_inca.cnf
[ v3_ca ]
basicConstraints = CA:true, pathlen:0
keyUsage = cRLSign, keyCertSign
nsCertType = sslCA, emailCA

この設定は、中間証明書の用途を決めるもので、今回は、サーバ証明書と、電子メール証明書の署名に使えるようにします。

今回の設定のキモと言えます。

 

さて、設定ファイルができたらextfileオプションに設定ファイルを指定して、コマンドを実行します。有効期間は、5年(1825日)です。

# openssl x509 -extfile openssl_sign_inca.cnf -req -in inca.csr -sha256 -CA ca.pem -CAkey ca.key -set_serial 01  -extensions v3_ca  -days 1825 -out inca.pem
Signature ok
subject=/C=JP/ST=Tokyo/O=example corp./CN=example Inter CA 2016
Getting CA Private Key
Enter pass phrase for ca.key:(ca.keyのパスフレーズ)
# 

一連のコマンドを図面化すると、以下のようになります。

openssl_inca_pem

つまり、CSRから、証明書を作り、上位の証明書であるca.pemと、その秘密鍵のca.keyを使って、署名をかけます。

サーバ証明書の作成

ついにサーバ証明書の作成に入ります。

この操作は、サーバの台数(WebVPNのルータなども含みます)というか、使用するFQDN(ドメイン名)ないしはIPアドレスの数、だけ実行します。

 

まずは、例によって、サーバ証明書の秘密鍵(server.key)を作ります。

今回は、Cisco社のWebVPNを想定してるので、先ほどの認証局のディレクトリ内で、サーバ証明書を作ります。

サーバ証明書の秘密鍵(server.key)は、ルータにインストールする際に、暗号化されている必要があります。

そのため、ここでは、DES3暗号で、暗号化しておきます。

 

イントラネットのWebサーバなどの用途であれば、Webサーバの秘密鍵とCSRはWebサーバ上で生成して、CSRだけを今回作った認証局のディレクトリに持ってきて、サーバ証明書生成して、Webサーバにを戻すといった運用が良いでしょう。

ということで、これまでの作業は認証局サーバでの作業でしたが、秘密鍵は、Webサーバで作ります。

 

以下、まず、Webサーバにログインします。


$ sudo su
# mkdir /usr/local/apache2/conf/ssl/
# cd /usr/local/apache2/conf/ssl/
# openssl genrsa  -out server.key -des3 2048
Generating RSA private key, 2048 bit long modulus
......................................................+++
...........+++
e is 65537 (0x10001)
Enter pass phrase for server.key:(server.keyのパスフレーズ)
Verifying - Enter pass phrase for server.key:(server.keyのパスフレーズ[確認])

# 

これは、さきほどと同様です。

openssl_server_key

次に、サーバ証明書のCSR(Certificate Signing Request)を作ります。

今回は、設定フィルを読み込ませずに作ります。

# openssl req -new -key server.key -outform PEM -keyform PEM  -sha256 -out server.csr  -subj "/C=JP/ST=Tokyo/O=example corp./CN=vpn.example.com"
Enter pass phrase for server.key:(server.keyのパスフレーズ)
# 

一応、CSRの中身を確認します。

# openssl req -noout -text -in server.csr
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=JP, ST=Tokyo, O=example corp., CN=vpn.example.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
	(…省略…)
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha256WithRSAEncryption
	(…省略…)
# 

この証明書は、以下の図のような関係となっています。

openssl_server_csr

CSRを作ったら、中間証明書(inca.pem)とその秘密鍵(inca.key)で署名した証明書を作ります。

# cat server.csr
-----BEGIN CERTIFICATE REQUEST-----
(…省略…)
-----END CERTIFICATE REQUEST----- #

の上記内容を、SSHターミナルのコピー&ペーストで、認証局サーバに持っていきます。

WebサーバのSSHターミナルで、コピーだけしておきます。

サーバ証明書への署名

ということで認証局サーバにログインします。

$ sudo su
# cd /usr/local/etc/ca
# vi server.csr

さきほどコピーした内容を、貼り付けて、server.csrファイルを作ります。

/usr/local/etc/ca/server.csr
-----BEGIN CERTIFICATE REQUEST-----
(…省略…)
-----END CERTIFICATE REQUEST-----

WebサーバのCSRを/usr/local/etc/ca/server.csrに貼り付けたら、いよいよ署名です。

CAオプションと、CAKeyオプションに中間証明書と、その秘密鍵を設定することが重要です。

サーバ証明書は、Baseline Requirements v.1.4.4によって、最長825日となっているので、それを超えない2年程度の長さにします。

# openssl x509 -req -in server.csr -sha256 -CA inca.pem -CAkey inca.key -set_serial 01 -days 730 -out vpn.pem
Signature ok
subject=/C=JP/ST=Tokyo/O=example corp./CN=vpn.example.com
Getting CA Private Key
Enter pass phrase for inca.key:(inca.keyのパスフレーズ)

まとめると、以下の図のようになります。

openssl_server_pem
[拡大]

以上で、ルート証明書(ca.pem)、中間証明書(inca.pem)、サーバ証明書(server.pem)を生成することができました。

ルート証明書(ca.pem)は、クライアント機にインストールし、中間証明書(inca.pem)と、サーバ証明書(server.pem)は、サーバ機にインストールします。

Cisco社のVPN用途で、利用する場合や、以下のリンクをご覧下さい。

証明書のApacheへのインストール

VPN用途ではなく、WebサーバのApacheで利用する場合の設定は、以下のようになります。

# vi /usr/local/apache2/conf/extra/httpd-ssl-vhosts.conf
/usr/local/apache2/conf/extra/httpd-ssl-vhosts.conf
<VirtualHost *:443>

	SSLEngine on

	SSLCertificateFile "/usr/local/apache2/conf/ssl/server.pem"
	SSLCertificateKeyFile "/usr/local/apache2/conf/ssl/server.key"
	SSLCertificateChainFile "/etc/letsencrypt/der_keys/inca.pem"

	DocumentRoot "/var/https/example.com/htdocs/"
	ServerName example.com:443
	ServerAdmin webmaster@example.com
    
	<Directory /var/https/example.com/htdocs>
		Options -Indexes
		AllowOverride All
		Require all granted
	</Directory>
	<FilesMatch "\.(cgi|shtml|phtml|php)$">
		SSLOptions +StdEnvVars
	</FilesMatch>
    
	ErrorLog "|/usr/local/apache2/bin/rotatelogs -l /var/log/https/example.com/error_log.%Y%m%d 86400"
	CustomLog "|/usr/local/apache2/bin/rotatelogs -l /var/log/https/example.com/access_log.%Y%m%d 86400" combined
	CustomLog "|/usr/local/apache2/bin/rotatelogs -l /var/log/https/example.com/ssl_request_log.%Y%m%d 86400" "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
    
 </VirtualHost>

クライアント機へのインストールは以下をご覧ください。

[NEXT] >> プライベートルート証明書のクライアント機へのインストール

©Copyrights 2015-2023, non-standard programmer

このサイトは、あくまでも私の個人的体験を、綴ったものです。 軽く参考程度にご利用ください。