8. (参考)プライベートCAの構築・運用手順

本章では OpenSSL を使用したプライベートCAの構築・運用手順について参考までに説明します。 なお、実運用を行う際は CA 用の商用製品を使用されることを推奨します。

8.1. 必要環境

RHEL7 または CentOS7 が必要です。また、OpenSSL がインストールされている必要があります。

8.2. Root CA の構築

8.2.1. CAディレクトリの作成

CA関連のファイルを格納するためのディレクトリを作成してください。 このディレクトリを $CATOP とします。

以下手順で必要なディレクトリ・ファイルを作成します。

$ cd $CATOP
$ mkdir certs newcerts private
$ echo "01" > serial
$ touch index.txt

8.2.2. openssl.cnf の作成

$CATOPディレクトリに openssl.cnf ファイルを作成し、編集します。

$ cd $CATOP
$ cp /etc/pki/tls/openssl.cnf .
$ vi openssl.cnf

以下の通り、openssl.cnf を修正してください。

なお、以下設定をすべて行った状態(ただし basicConstraints は CA:TRUE)の openssl.cnf のサンプルが openssl.cnf にありますので、 こちらをお使いいただいても構いません。

ただしサーバ証明書作成時は、次項の説明に従ってopenssl.cnfを修正を行ってください。

注意

ここでは簡単のため CA, サーバ, クライアントの各証明書発行に同じ openssl.cnf を使用していますが、 本来であればそれぞれ毎に basicConstrains, keyUsage を変更した openssl.cnf を使用するべきです。

基本設定

  • CA_default セクションにデフォルト設定を行います。
    • dir の値を $CATOP ディレクトリのフルパスに変更(または単に "." でも OK)
  • usr_cert セクションに CA 用の設定を行います。
    • basicConstraints の値を "CA:FALSE" から "CA:TRUE" に変更。
    • nsCertType に "sslCA, emailCA" を設定。
    • keyUsage に "cRLSign, keyCertSign" を追加。

サーバ証明書発行用の設定

サーバ証明書の発行を行う場合は、追加で以下の設定を行います。

  • req セクションに署名用の設定を行います。
    • req_extensions の値を"v3_req" に指定。(サーバ証明書作成時に有効化してください)
  • usr_cert セクションに サーバ署名用の設定を行います。
    • basicConstraints の値を "CA:FALSE" に設定。
    • nsCertType に "server" を設定。(複数指定する場合はカンマ区切り)
    • keyUsage に "nonRepudiation, digitalSignature, keyEncipherment" を追加。
    • subjectAltNameに "@alt_names"を追加します。(サーバ証明書作成時に有効化してください)
  • v3_req セクションに署名用の設定を行います。
    • subjectAltNameに"@alt_names"を追加します。(サーバ証明書作成時に有効化してください)
  • alt_names セクションを追加します。
    • ドメイン名を使用する場合は DNS.<連番> にドメインを追加します。
    • IP アドレスを使用する場合は、IP.<連番> にIPアドレスを追加します。

クライアント証明書発行用の設定

クライアント証明書の発行を行う場合は、追加で以下の設定を行います。

  • usr_cert セクションに クライアント証明書用の設定を行います。
    • basicConstraints の値を "CA:FALSE" に設定。
    • nsCertType に "client" を設定 (複数指定する場合はカンマ区切り)
    • keyUsage に "nonRepudiation, digitalSignature, keyEncipherment" を追加。
  • クライアントの識別子としてUIDを使用する場合、以下の修正を行います。
    • CA_defaultセクションのpolicyで指定する値(policy_match、またはpolicy_anything)のサブセクションに UID = optional を追加。
    • req_distinguished_name セクションに UID = UID および UID_max = 64 を追加。

8.2.3. CA の作成

以下手順で CA を作成します。

まず、CAの秘密鍵(private/cakey.pem)と証明書要求(careq.pem)を作成します。

$ cd $CATOP
$ openssl genrsa -aes256 -out private/cakey.pem 2048
$ openssl req -new -config ./openssl.cnf -key private/cakey.pem -keyout private/cakey.pem -out careq.pem

作成中にいくつか質問されますので、以下のように入力します。

  • Enter PEM pass phrase: PEMパスフレースを入力します。
  • Country Name: 国コードを入力します (日本の場合は 'JP')
  • State or Province Name: 県名を入力します (例: 'Tokyo')
  • Locality Name: 都市名を入力します (例: 'Minato')
  • Organization Name: 組織名を入力します (例: 'NEC')
  • Organizational Unit Name: 下位組織名を入力します
  • Common Name: CAの名前を入力します (例: 'BaasRootCA')
  • Email Address: 管理者のメールアドレスを入力します。
  • Enter pass phrase for ...cakey.pem: 上記のPEMパスフレーズを入力します。

ついで、証明書要求に署名を行いCAのX.509証明書(cacert.pem)を作成します。 有効期間は -days で指定してください。

$ cd $CATOP
$ openssl x509 -req -in careq.pem -signkey private/cakey.pem -out cacert.pem -days 3650

本ファイル(cacert.pem)はクライアント側に設定する必要があります。

8.3. サーバ証明書の発行

HAProxy で使用するサーバ証明書の発行手順を説明します。

8.3.1. RSA秘密鍵の生成

RSA秘密鍵を生成します。

$ openssl genrsa -aes256 -out server_key.pem 2048

鍵を暗号化するためのパスフレーズの入力が必要です。

8.3.2. RSA秘密鍵のパスフレーズ解除

パスフレーズで保護されたままだと、サーバの起動時に毎回パスフレーズの入力が必要になります。 これを不要にするには、以下のようにパスフレーズを解除してください。

$ mv server_key.pem server_key_encrypted.pem
$ openssl rsa -in server_key_encrypted.pem -out server_key.pem

8.3.3. CSR(証明書発行要求)の生成

CSR を生成します。

$ openssl req -new -key server_key.pem -out server_req.pem

作成中にいくつか質問されますので、適宜回答してください。 この際 "Common Name" の値には、必ず証明書を設定するサーバの FQDN を 指定するようにしてください。

8.3.4. 証明書の発行

CA で CSR を署名して証明書を発行します。 証明書の有効期間は -days で指定してください。

$ cd $CATOP
$ openssl ca -config ./openssl.cnf -in server_req.pem -out server_cert.pem -days 3650

以上でサーバ証明書が作成できました。

注釈

サーバ証明書のX509v3 extensionsに、X509v3 Subject Alternative Nameが設定されていない場合、 ブラウザや通信ライブラリによって証明書が不正と判断される場合があります。

HAProxy に投入するためには、秘密鍵(server_key.pem) と証明書(server_cert.pem)を cat で連結して1ファイルにして投入してください。

$ cat server_cert.pem server_key.pem > server_cert_with_key.pem

8.4. クライアント証明書の発行

8.4.1. RSA秘密鍵の生成

RSA秘密鍵を生成します。

$ openssl genrsa -aes256 -out client_key.pem 2048

鍵を暗号化するためのパスフレーズの入力が必要です。

8.4.2. RSA秘密鍵のパスフレーズ解除

秘密鍵のパスフレーズを解除を行うには以下のようにします。 (ブラウザに取り込む場合は、インポート時にパスフレーズを入力できるため不要です)

$ mv client_key.pem client_key_encrypted.pem
$ openssl rsa -in client_key_encrypted.pem -out client_key.pem

8.4.3. CSR(証明書発行要求)の生成

CSR を生成します。

$ openssl req -config ./openssl.cnf -new -key client_key.pem -out client_req.pem

サーバ証明書と同様にSubjectの値を指示に従って入力します。

8.4.4. 証明書の発行

CA で CSR を署名して証明書を発行します。 証明書の有効期間は -days で指定してください。

$ cd $CATOP
$ openssl ca -config ./openssl.cnf -in client_req.pem -out client_cert.pem -days 1095

以上で証明書が作成できました。

注釈

CAはCSRに設定されているOrganization Name等の検証を行い、ポリシーに一致しない場合は署名に失敗します。 CAのopenssl.cnf "CA_default -> policy"を参照し、matchとなっている要素はCAの証明書の値と一致する必要があります。 suppliedとなっている要素は任意の値をCSRに指定する必要があります。

クライアントではPKCS#12形式の証明書を使用することがあります。 PKCS#12 形式の証明書は、以下のようにPEMの秘密鍵、証明書から生成します。

$ openssl pkcs12 -export -in client_cert.pem -inkey client_key.pem -out client_cert.p12

8.5. 証明書の失効と、CRL(証明書失効リスト)の作成

以下の手順で、クライアント証明書を失効させることができます。

  • CAでクライアント証明書を失効させる
  • サーバへのCRL反映

8.5.1. 証明書の失効

以下コマンドで、クライアント証明書を失効させます。 失効の手続きは、証明書発行元のCAで行って下さい。

$ cd $CATOP
$ openssl ca -config ./openssl.cnf -gencrl -revoke client_cert.pem -out crl.pem

証明書(client_cert.pem) を失効させ、CRL(crl.pem)が生成されます。

注釈

CRLにも有効期間があります。これを超えた場合、サーバでの認証が正常に動作しません。定期的にCRLの更新を行うか、openssl.cnfにあるCRLの有効期限 default_crl_days を伸ばしてからCRLを生成してください。

CRLの更新のみを行う場合は、以下コマンドを使用します。

$ openssl ca -config ./openssl.cnf -gencrl -out crl.pem

8.5.2. サーバへのCRL反映

作成したCRLをHAProxy等のサーバに反映します。 失効した証明書を使用した場合、サーバでの認証に失敗します。 手順は リバースプロキシで認証する場合の設定 を参照下さい。