AWS Certificate Manager Private Certificate Authority 素振り

AWS のマネージドなプライベート CA の AWS Certificate Manager Private Certificate Authority を素振りしたメモ。

費用

https://aws.amazon.com/jp/certificate-manager/pricing/

プライベート CA ごとに 400 USD の月額と、プライベート証明書を発行する都度の費用が必要で、月/リージョンで発行した証明書の数によって次のディスカウントが効いた費用が必要です。

月/リージョンの証明書の数 料金/証明書
1~1,000 0.75 USD
1,001~10,000 0.35 USD
10,001 以上 0.001 USD

プライベート CA の月額は削除した月内は日割りで計算されます。ただし削除した CA を復旧可能期間中に復旧させると、削除から復旧までの期間についても課金されます。

アカウントで最初に作成したプライベート CA は30日間の無料期間があります。

証明書について、プライベートキーにアクセスの無いプライベート CA から発行する証明書は無料、とのこと。後述のローカルで秘密鍵&CSRを作成してプライベート CA で証明書を作成するケースは無料ということかな?

ACM と ACM PCA

ACM(AWS Certificate Manager)と ACM PCA(AWS Certificate Manager Private Certificate Authority)はマネジメントコンソールでは同じところにあるものの実質は別のサービスで連携ができると考えておくほうがわかりやすいかも。

ACM PCA はいわゆるフルマネージドなプライベート CA サービスで、ユーザーが作成した CSR を元に署名された証明書を作成できます。作成した証明書を失効することもできて、失効リストも ACM PCA で作成&S3 に保存されます。

ACM は証明書&秘密鍵を管理するサービスです。証明書&秘密鍵は以下のいずれかの方法で登録できます。

  • パブリック証明書をリクエスト
    • AWS で署名された証明書を作成
      • 一般的なブラウザで信頼される証明書チェイン
    • 秘密鍵も自動で作成される
      • 秘密鍵はエクスポートできない
    • CN のドメイン検証が必要
      • メール、または、DNS
  • プライベート証明書をリクエスト
    • 発行元として ACM PCA で作成されたプライベート CA を指定
      • 一般的なブラウザで信頼されるかどうかはプライベート CA の上位 CA 次第
    • 証明書の CN のドメイン検証は不要
      • 任意の CN で作成できる
    • 秘密鍵も自動で作成される
      • 秘密鍵もエクスポートできる
  • 証明書&秘密鍵をインポート
    • 別のベンダーから取得した証明書&秘密鍵を ACM にインポート

オレオレルート CA の作成と プライベート CA の証明書作成のメモ

ACM PCA でプライベート CA を作成するためには、プライベート CA の証明書に署名するためのルート CA が必要です。つまり ACM PCA のプライベート CA はルート CA にはならず、こちらで用意する CA の下位 CA になります。

なお、マネジメントコンソールでプライベート CA を作成するときに「下位 CA」という1つしか選択できない選択肢があるので、将来的にはルート CA も作成できるようになるのかもしれません。

オレオレルート CA はいわゆる CA.sh (/etc/pki/tls/misc/CA) で作るのが普通かもしれませんが、これが対話式で辛いのでなるべく対話不要に作ります。

# basicConstraints を critical,CA:true にしておかないと証明書のインポートでコケる
cp -an /etc/pki/tls/openssl.cnf /etc/pki/tls/openssl.cnf.orig
vim /etc/pki/tls/openssl.cnf
#=> [ v3_ca ]
#=> basicConstraints = critical,CA:true

# index.txt を作成
touch /etc/pki/CA/index.txt

# ルート CA の秘密鍵&CSRを作成
openssl req -batch -new -newkey rsa:2048 -nodes -sha256 \
    -subj /C=JP/ST=Tokyo/O=oreore/OU=oreore/CN=oreore-root-ca \
    -keyout /etc/pki/CA/private/cakey.pem \
    -out /etc/pki/CA/careq.pem

# ルート CA の自己署名証明書を作成
openssl ca -batch -create_serial -selfsign -days 3650 -extensions v3_ca \
    -keyfile /etc/pki/CA/private/cakey.pem \
    -in /etc/pki/CA/careq.pem \
    -out /etc/pki/CA/cacert.pem

# ACM PCA プライベート CA の CSR を貼り付けて保存
vim acm-pca.csr

# ACM PCA プライベート CA の証明書を作成
openssl ca -batch -policy policy_anything -days 3650 -extensions v3_ca -in acm-pca.csr -out acm-pca.crt

# オレオレルート CA 証明書と ACM PCA プライベート CA 証明書を PEM 形式で表示してマネジメントコンソールからインポート
openssl x509 -in /etc/pki/CA/cacert.pem
openssl x509 -in acm-pca.crt

ローカルで秘密鍵&CSRを作成してプライベート CA で証明書を作成

ローカルで秘密鍵&CSRを作成し、プライベート CA で CSR から証明書を作成して署名できます。

# 秘密鍵&CSRを作成
openssl req -batch -new -newkey rsa:2048 -nodes -sha256 -subj /CN=foo.test -keyout client.key -out client.csr

# プライベートCAで署名して証明書作成
aws acm-pca issue-certificate \
    --certificate-authority-arn \
    "arn:aws:acm-pca:ap-northeast-1:999999999999:certificate-authority/9191161e-d094-4217-9796-45612de76aad" \
    --csr file://client.csr \
    --signing-algorithm "SHA256WITHRSA" \
    --validity Value=365,Type="DAYS"

# 証明書をエクスポートしてファイルに保存
aws acm-pca get-certificate \
    --certificate-authority-arn \
    "arn:aws:acm-pca:ap-northeast-1:999999999999:certificate-authority/9191161e-d094-4217-9796-45612de76aad" \
    --certificate-arn \
    "arn:aws:acm-pca:ap-northeast-1:999999999999:certificate-authority/9191161e-d094-4217-9796-45612de76aad/certificate/f8e94e702ca3eef0bdd6d46e4ae00318" \
    --query "Certificate" --output text > client.crt

証明書のシリアルナンバーを指定して証明書を失効できます。

# シリアルナンバーを取得
openssl x509 -noout -serial -in client.crt
#=> serial=F8E94E702CA3EEF0BDD6D46E4AE00318

# 証明書を失効させる
aws acm-pca revoke-certificate \
    --certificate-authority-arn \
    "arn:aws:acm-pca:ap-northeast-1:999999999999:certificate-authority/9191161e-d094-4217-9796-45612de76aad" \
    --certificate-serial "F8E94E702CA3EEF0BDD6D46E4AE00318" \
    --revocation-reason "UNSPECIFIED"

しばらくすると失効リストに追加されます。失効リストはプライベート CA の作成時に指定した S3 に保存されます。

curl -s http://ore-no-ca.s3.ap-northeast-1.amazonaws.com/crl/9191161e-d094-4217-9796-45612de76aad.crl |
    openssl crl -inform DER -text -noout

作成された証明書をマネジメントコンソールや AWS CLI や AWS API で一覧を得ることはできなさそうです。なので aws acm-pca issue-certificate の応答の証明書の ARN を忘れてしまうと証明書が取得できなくなりそうです。

監査報告書を有効にすれば S3 に JSON や CSV で作成した証明書の一覧が保存されるので、それで確認できます。

ACM でプライベート証明書をリクエスト

ACM のマネジメントコンソールの「プライベート証明書のリクエスト」から証明書が作成できます。プライベート CA で自動で署名されるので証明書のドメイン名(CN)は何でも OK です。

証明書と秘密鍵が自動で作成されたうえでそれらが ACM で管理されます。また、ACM でパブリック証明書を作成すると秘密鍵はエクスポートできませんが、プライベート証明書なら秘密鍵もエクスポートが可能です。

作成される証明書の有効期限は365日で固定です。もしこの有効期限よりプライベートCAの有効期限が短いと、とてもわかりにくいエラーメッセージで失敗します。

マネジメントコンソールでプライベート証明書を作成するのと同じことが AWS CLI でもできます。

# 証明書の発行
aws acm request-certificate \
    --certificate-authority-arn \
    "arn:aws:acm-pca:ap-northeast-1:999999999999:certificate-authority/9191161e-d094-4217-9796-45612de76aad" \
    --domain-name "hoge.test"

# 証明書&秘密鍵のエクスポート
aws acm export-certificate \
    --certificate-arn \
    "arn:aws:acm:ap-northeast-1:999999999999:certificate/65039cd8-9b91-49be-8ea6-5de62244b152" \
    --passphrase "password"

ここで作成したプライベート証明書は AWS PCA のプライベート CA で署名されているので、プライベート CA の監査報告書にも追記されます。監査報告書には AWS PCA の証明書の ARN も記述されているので AWS PCA の AWS CLI で証明書を得ることもできます(つまり ACM と ACM PCA の両方の ARN がある)。

# ACM から証明書取得
aws acm get-certificate \
    --certificate-arn \
    "arn:aws:acm:ap-northeast-1:999999999999:certificate/65039cd8-9b91-49be-8ea6-5de62244b152" \
    --query 'Certificate' --outpu text | openssl x509 -noout -text

# ACM PCA から証明書取得(↑と同じ結果)
aws acm-pca get-certificate \
    --certificate-authority-arn \
    "arn:aws:acm-pca:ap-northeast-1:999999999999:certificate-authority/9191161e-d094-4217-9796-45612de76aad" \
    --certificate-arn \
    "arn:aws:acm-pca:ap-northeast-1:999999999999:certificate-authority/9191161e-d094-4217-9796-45612de76aad/certificate/7e03d1acb41aa7c2083b16c1adc055a6" \
    --query 'Certificate' --outpu text | openssl x509 -noout -text

ACM のプライベート証明書の失効

ACM のマネジメントコンソールや AWS CLI でプライベート証明書を ACM から削除しても、プライベート CA の失効リストには追加されません。あくまでも ACM の管理上から削除されるだけです。

ACM のプライベート証明書は ACM PCA でも管理されているので、ACM PCA で署名した証明書と同様にプライベート証明書のシリアルナンバーを指定して証明書を失効できます。

# シリアルナンバーを取得
aws acm get-certificate \
    --certificate-arn \
    "arn:aws:acm:ap-northeast-1:999999999999:certificate/65039cd8-9b91-49be-8ea6-5de62244b152" \
    --query 'Certificate' --outpu text | openssl x509 -noout -serial -in client.crt
#=> serial=7E03D1ACB41AA7C2083B16C1ADC055A6

# 証明書を失効させる
aws acm-pca revoke-certificate \
    --certificate-authority-arn \
    "arn:aws:acm-pca:ap-northeast-1:999999999999:certificate-authority/9191161e-d094-4217-9796-45612de76aad" \
    --certificate-serial "7E03D1ACB41AA7C2083B16C1ADC055A6" \
    --revocation-reason "UNSPECIFIED"

参考