社内や家庭内でSSLを利用する際、オレオレ証明書で信頼されてない状態で利用するとどうしても支障が出る場合がある。
(RestAPIを使っての通信だったりとか)

そんなときは、LAN内にプライベート認証局を構築して、そこから証明書を発行させることで、(クライアント側にCA証明書をインストールする必要はあるが)信頼された証明書として利用することが可能にだ。今回は、CentOS 7上でプライベート認証局の構築と証明書の発行を行う。

1.OpenSSLの準備をする

まず、以下のコマンドでOpenSSLをインストールする。

yum install -y openssl

プライベートCA認証局を作成するにあたり、CentOS 7では「/etc/pki/tls/」ディレクトリで作業を行う。

[root@BS-PUB-CENT7-01 ~]# ls -la /etc/pki/tls/
合計 12
drwxr-xr-x. 5 root root    76 10月 15 10:41 .
drwxr-xr-x. 9 root root    91  1月  1  2016 ..
lrwxrwxrwx. 1 root root    49  8月 19 08:58 cert.pem -> /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
drwxr-xr-x. 2 root root   112 10月 15 10:42 certs
drwxr-xr-x. 2 root root    69 10月 15 10:42 misc
-rw-r--r--. 1 root root 10923  9月 27 22:28 openssl.cnf
drwxr-xr-x. 2 root root     6  9月 27 22:39 private

2.プライベート認証局の作成

証明書は認可方式なので、一般的には外部の世界的に信頼のおける機関に審査してもらい証明書を発行してもらう必要がある。この発行機関のことを認証局(Certificate Authority。以下CA)といい、認証局の中でもクライアントに最初からインストールされている最上位の認証局はルート認証局(ルートCA)と呼ばれている。

一般的には、ルート認証局から証明された中間認証局(中間CA)が署名する形で証明書が発行されている。今回はプライベート認証局なので、ルート認証局のみを構築する…と言いたいところだったのだが、CentOSやUbuntuではなぜか中間CA証明書がないとうまく証明書が信用がされなかった。このため、中間CA証明書についても作成を行う。

なお、ディレクトリについてはルート認証局のファイルはデフォルトで「/etc/pki/CA」となっているのでそのまま、中間CA証明書については「/etc/pki/ICA」とする。

2-1.ルートCA証明書の作成

まず、プライベート認証局を作成するスクリプト(/etc/pki/tls/misc/CA)の設定ファイル(/etc/pki/tls/openssl.cnf)を編集する。

・73行目: default_days = 3650
・178行目: nsCertType = server # コメントアウトを解除
・250行目: nsCertType = sslCA, emailCA # コメントアウトを解除

次に、以下のコマンドで認証局の作成を開始する。

cd /etc/pki/CA
/etc/pki/tls/misc/CA -newca
[root@BS-PUB-CENT7-01 CA]# /etc/pki/tls/misc/CA -newca
CA certificate filename (or enter to create)
~Enterキーを押下する~
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:~ルートCAのパスワードを入力~
Verifying - Enter PEM pass phrase:~ルート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]:Tachikawa
Organization Name (eg, company) [Default Company Ltd]:Test Company
Organizational Unit Name (eg, section) []:Test
Common Name (eg, your name or your server's hostname) []:ca-test.blacknon.local
Email Address []:

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:~ルートCAのパスワードを入力~
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 17850187192760832369 (0xf7b89aad6ebc9171)
        Validity
            Not Before: Nov  4 03:53:05 2016 GMT
            Not After : Nov  4 03:53:05 2019 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Tokyo
            organizationName          = Test Company
            organizationalUnitName    = Test
            commonName                = ca-test.blacknon.local
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                B5:7E:AA:4C:4A:30:B6:69:AA:98:11:C4:F6:CA:EF:73:07:27:44:6F
            X509v3 Authority Key Identifier:
                keyid:B5:7E:AA:4C:4A:30:B6:69:AA:98:11:C4:F6:CA:EF:73:07:27:44:6F

            X509v3 Basic Constraints:
                CA:TRUE
Certificate is to be certified until Nov  4 03:53:05 2019 GMT (1095 days)

Write out database with 1 new entries
Data Base Updated

作成されたルート認証局の証明書を配布できるよう、derファイルおよびcrtファイルの作成を行う。

cd /etc/pki/CA
openssl x509 -inform pem -in cacert.pem -outform der -out cacert.der
openssl x509 -in cacert.pem -out cacert.crt

2-2.中間認証局の作成

次に、中間認証局の作成をする。
作成前に、中間認証局用のディレクトリ作成およびスクリプト(/etc/pki/tls/misc/ICA)、設定ファイル(/etc/pki/tls/openssl_ica.cnf)の作成・編集を実施する。

mkdir /etc/pki/ICA
cp /etc/pki/tls/openssl{,_ica}.cnf
cp /etc/pki/tls/misc/{,I}CA

スクリプト、設定ファイルそれぞれを以下のように編集する。

●/etc/pki/tls/openssl_ica.cnf

・42行目: dir = /etc/pki/ICA
・332行目: dir = /etc/pki/ICA

●/etc/pki/tls/misc/ICA(追記)

・35行目:
CATOP=/etc/pki/ICA
SSLEAY_CONFIG="-config /etc/pki/tls/openssl_ica.cnf"

ファイル編集後、中間認証局の作成を行う。
まずは、中間認証局からルート認証局への署名要求(CSR)を作成する。

cd /etc/pki/ICA
/etc/pki/tls/misc/ICA -newreq
[root@BS-PUB-CENT7-01 ICA]# /etc/pki/tls/misc/ICA -newreq
Generating a 2048 bit RSA private key
............+++
...............................................................................................+++
writing new private key to 'newkey.pem'
Enter PEM pass phrase:~中間CAのパスワードを入力~
Verifying - Enter PEM pass phrase:~中間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]:
Organization Name (eg, company) [Default Company Ltd]:ICA Test
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:ica-test.blacknon.local
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Request is in newreq.pem, private key is in newkey.pem

ルート認証局でCSRへの署名を行う。

/etc/pki/tls/misc/CA -signCA
[root@BS-PUB-CENT7-01 ICA]# /etc/pki/tls/misc/CA -signCA
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/cakey.pem:~CAのパスワードを入力~
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 17850187192760832371 (0xf7b89aad6ebc9173)
        Validity
            Not Before: Nov  4 06:29:43 2016 GMT
            Not After : Nov  2 06:29:43 2026 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Tokyo
            localityName              = Default City
            organizationName          = ICA TEst
            commonName                = ica-test.blacknon.local
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                F8:F8:13:E1:EC:D5:40:0E:C0:18:B6:B7:6C:9E:42:A2:CA:59:16:C9
            X509v3 Authority Key Identifier:
                keyid:B5:7E:AA:4C:4A:30:B6:69:AA:98:11:C4:F6:CA:EF:73:07:27:44:6F

            X509v3 Basic Constraints:
                CA:TRUE
Certificate is to be certified until Nov  2 06:29:43 2026 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
Signed CA certificate is in newcert.pem

中間CA証明書の作成をする。

/etc/pki/tls/misc/ICA -newca # /etc/pki/ICA/newcert.pemを指定する
mv /etc/pki/ICA/newkey.pem /etc/pki/ICA/private/cakey.pem
openssl x509 -in newcert.pem -out icacert.crt

配布用のderファイルを作成する。

openssl x509 -inform pem -in newcert.pem -outform der -out icacert.der

この時点で、後で必要になる以下のファイルが作成された。

  • /etc/pki/CA/cacert.crt ... ルートCA証明書(クライアントなどに信頼されたルート証明書としてインストールする)
  • /etc/pki/CA/cacert.der ... ルートCA証明書(クライアントなどに信頼されたルート証明書としてインストールする)
  • /etc/pki/ICA/icacert.crt ... 中間CA証明書(クライアントなどにインストールする)
  • /etc/pki/ICA/icacert.der ... 中間CA証明書(クライアントなどにインストールする)

3.サーバ証明書の作成・ルート認証局の署名を実施

次に、サーバ証明書を作成する。
以下のコマンドを実行し、秘密鍵の作成を実施する。

cd /etc/pki/tls/private
openssl genrsa -aes256 2048 > server.key
cp server.key{,.org}
openssl rsa -in server.key.org -out server.key
[root@BS-PUB-CENT7-01 private]# openssl genrsa -aes256 2048 > server.key
Generating RSA private key, 2048 bit long modulus
..................+++
.........................+++
e is 65537 (0x10001)
Enter pass phrase:
Verifying - Enter pass phrase:
[root@BS-PUB-CENT7-01 private]# cp server.key{,.org}
[root@BS-PUB-CENT7-01 private]# openssl rsa -in server.key.org -out server.key
Enter pass phrase for server.key.org:
writing RSA key

作成完了後、署名要求(CSR)を作成する。

openssl req -new -key server.key -out newreq.pem
[root@BS-PUB-CENT7-01 private]# openssl req -new -key server.key -out newreq.pem
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]:Tachikawa
Organization Name (eg, company) [Default Company Ltd]:Server Company
Organizational Unit Name (eg, section) []:None
Common Name (eg, your name or your server's hostname) []:BS-PUB-STACKSTORM.BLACKNON.LOCAL #SSLで利用するホスト名を入れる 
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

CSRの作成後、中間CAから署名を実施して証明書を作成する。

/etc/pki/tls/misc/ICA -sign
[root@BS-PUB-CENT7-01 private]# openssl req -new -key server.key -out newreq.pem
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]:Tachikawa
Organization Name (eg, company) [Default Company Ltd]:Server Company
Organizational Unit Name (eg, section) []:None
Common Name (eg, your name or your server's hostname) []:BS-PUB-STACKSTORM.BLACKNON.LOCAL
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@BS-PUB-CENT7-01 private]# /etc/pki/tls/misc/ICA -sign
Using configuration from /etc/pki/tls/openssl_ica.cnf
Enter pass phrase for /etc/pki/ICA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 17850187192760832372 (0xf7b89aad6ebc9174)
        Validity
            Not Before: Nov  4 06:41:15 2016 GMT
            Not After : Nov  2 06:41:15 2026 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Tokyo
            localityName              = Tachikawa
            organizationName          = Server Company
            organizationalUnitName    = None
            commonName                = BS-PUB-STACKSTORM.BLACKNON.LOCAL
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Cert Type:
                SSL Client, S/MIME
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                EE:03:EA:66:E8:E4:7E:E1:FB:83:F6:65:9B:8E:9F:55:0E:6A:9A:D8
            X509v3 Authority Key Identifier:
                keyid:F8:F8:13:E1:EC:D5:40:0E:C0:18:B6:B7:6C:9E:42:A2:CA:59:16:C9

Certificate is to be certified until Nov  2 06:41:15 2026 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
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 17850187192760832372 (0xf7b89aad6ebc9174)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=JP, ST=Tokyo, L=Default City, O=ICA TEst, CN=ica-test.blacknon.local
        Validity
            Not Before: Nov  4 06:41:15 2016 GMT
            Not After : Nov  2 06:41:15 2026 GMT
        Subject: C=JP, ST=Tokyo, L=Tachikawa, O=Server Company, OU=None, CN=BS-PUB-STACKSTORM.BLACKNON.LOCAL
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:bb:49:81:14:5d:06:2a:44:84:a4:04:35:67:09:
                    <略>
                    f1:28:26:fd:a8:32:dc:67:f5:f8:9a:54:4c:b8:3e:
                    e0:b9
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Cert Type:
                SSL Client, S/MIME
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                EE:03:EA:66:E8:E4:7E:E1:FB:83:F6:65:9B:8E:9F:55:0E:6A:9A:D8
            X509v3 Authority Key Identifier:
                keyid:F8:F8:13:E1:EC:D5:40:0E:C0:18:B6:B7:6C:9E:42:A2:CA:59:16:C9

    Signature Algorithm: sha256WithRSAEncryption
         62:4e:d3:7a:26:d5:62:de:30:fb:6d:53:64:50:32:d1:07:7a:
           <略>
         c4:4e:17:2a:06:50:80:be:70:66:2d:99:03:d6:22:59:7a:11:
         a2:d5:4b:50
-----BEGIN CERTIFICATE-----
MIIEATCCAumgAwIBAgIJAPe4mq1uvJF0MA0GCSqGSIb3DQEBCwUAMGkxCzAJBgNV
<略>
+bS0HHwWJ53Uar7oW78SpjpN23aP/Z9rPJKOoJ0CHJb4qP2CpouRv7uX0/oh3IDE
ThcqBlCAvnBmLZkD1iJZehGi1UtQ
-----END CERTIFICATE-----
Signed certificate is in newcert.pem

これで、新規の証明書「newcert.pem」が作成できた。
このままだとわかりにくいので、名称を変更しておく。

mv /etc/pki/tls/private/newcert.pem /etc/pki/tls/certs/
cd /etc/pki/tls/certs/
openssl x509 -in newcert.pem -out server.crt

この処理でできたファイルは以下。

  • /etc/pki/tls/certs/server.crt ... サーバ証明書(サーバ側で使用する)
  • /etc/pki/tls/private/server.key … サーバ秘密鍵(サーバ側で使用する)

これで、必要になる証明書は作成できた。

4.Webサーバで証明書の設定

作成された証明書をWebサーバで利用するため、以下の設定を行う。

4-1.Apacheの場合

Apacheの場合は、基本的には「/etc/httpd/conf.d/ssl.conf」に以下のように設定をしてやればよい。

SSLCertificateFile /PATH/server.crt
SSLCertificateKeyFile /PATH/server.key
SSLCertificateChainFile /PAHT/icacert.crt

設定変更後はApacheの再起動を行う。

4-2.Nginxの場合

Nginxの場合も、Apacheと同様となる。
以下のように設定ファイル「/etc/nginx/conf.d/xxxx.conf」を編集する。
なお、証明書はサーバ証明書+中間CA証明書の結合をしたファイルが必要になるため、事前に以下のコマンドでファイルを結合しておく。

cat /etc/pki/tls/certs/server.crt /etc/pki/ICA/icacert.crt > /etc/pki/tls/certs/server.nginx.crt
ssl_certificate /PATH/server.nginx.crt;
ssl_certificate_key /PATH/server.key;

設定変更後はNginxの再起動を行う。

5.クライアント側へルート証明書のインストール

各種OSでの配布したルート証明書のインストール方法は、以下のようになっている。

5-1.Windowsの場合

作成した「cacert.der」をダブルクリックし、「証明書のインストール」でインストールする。
なお、インストール時には「現在のユーザ」を使い、かつ証明書ストアは「信頼されたルート証明機関」を選択する。

5-2.Mac OS Xの場合

「アプリケーション」>「ユーティリティ」>「キーチェーンアクセス.app」からキーチェーンアクセスを開き、「cacert.der」を読み込む。
読み込んだ後は、「常に信頼する」をしておけばよい。

5-3.CentOS 7の場合

CentOS 7の場合は、以下のようにする。

cp /PATH/cacert.crt /usr/share/pki/ca-trust-source/anchors
cp /PATH/icacert.crt /usr/share/pki/ca-trust-source/anchors
update-ca-trust extract

5-4.Ubuntu Server 16.04の場合

Ubuntu Server 16.04 の場合、以下のようにする。

sudo cp /PATH/cacert.crt /usr/local/share/ca-certificates/
sudo cp /PATH/icacert.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates

これで、プライベート認証局の証明書がクライアントで利用できるようになった。


参考