ACMでプライベートCAを作成して証明書を発行してみた

記事タイトルとURLをコピーする

こんにちは。ポインコと暮らしているエンジニアの高橋です。 今回はACMでプライベートCAを作成し、証明書を発行してみます。

プライベートCA(認証局)とは

SSL/TLSサーバー証明書を発行するのが認証局(CA)ですが、CAには大きく分けてパブリックとプライベートとがあります。パブリックCAは監査法人によって認められた信頼された機関で、一般的なWebサイトにはこのパブリックCAの証明書が使用されます。一方、プラべートCAは誰でも構築することができる独自のCAです。社内システムに適用することなどが考えられます。

ACMとは

ACMは「AWS Certificate Manager」の略で、SSL/TLS 証明書を作成/管理したり、CAを作成してプライベート証明書を発行することができるサービスです。 https://docs.aws.amazon.com/ja_jp/acm/latest/userguide/acm-overview.html

ACMの料金

ACMでプロビジョニングしたSSL/TLS 証明書は無料なのですが、プライベートCAについては料金が発生します。結構高額なので注意しましょう!(Amazonプライムと同じで初回は30日間無料です)

プライベートCAの料金:毎月400 USD(日割計算) プライベート証明書の発行:

月/リージョンで作成されたプライベート証明書の数 料金 (証明書当たり)
1~1,000 0.75 USD
1,001~10,000 0.35 USD
10,001~ 0.001 USD

プライベートCA作成

それでは早速プライベートCAを作成していきましょう。ACMの画面からプライベートCAを選択して作成を開始します。

認証機関のタイプ

ルートCAなのか下位CAなのかを選択します。以前は下位CAのみの対応だったようですが、ルートCAも選択できるようになりました。今回は社内運用を想定し、ルートCAとして作成します。

認証機関(CA)名の設定

組織や組織単位、住所、証明機関名を入力します。日本語もOKですが、英語が無難です。

証明機関(CA)のキーアルゴリズムの設定

暗号化方式を選びます。

証明書の失効の設定

証明書失効リスト(CRL)を自動的に作成するかどうかを選択します。CRLはS3に作成されるようです。今回は有効にしませんでした。

タグの追加

好きなタグを付けましょう。

CA許可を設定

突然ステップ番号が表示されて(?)ですが、ACMからCAへのアクセスを許可することで、証明書の自動更新ができます。あとからでも設定変更可能です。

確認画面

最後に設定を確認して、課金されるけどほんとにいい? って問いに同意して作成します。

できました。

ルートCA証明書

続いてルートCA証明書を作成、インストールしましょう。

有効期限と署名アルゴリズムを選択し、さくっとインストールします。

完了です。

プライベート証明書の発行

プライベートCAの準備がととのったので、プライベート証明書を発行してみましょう。 Certificate Managerから証明書のリクエストをおこないます。プライベート証明書のリクエストを選択します。

先ほど作成したルートCAを選び...

証明書を使って保護したいドメインを入力します。

あとは確認して...

正常にリクエストされましたね。

証明書をエクスポートする

証明書が発行できたので、Certificate Managerから該当の証明書を選び、エクスポートしましょう。(プライベート証明書のみエクスポートできます)

この際、証明書のプライベートキーを暗号化するためのパスフレーズが必要です。

このパスフレーズにはハマりポイントがあり、以下の条件を満たす必要があります。 ・4 ~ 128文字 ・「%#&+」の4つの記号が使用不可

この4つの記号についての情報は記載されていません。当社社員がAWSサポートに問い合わせて得た情報です。いくつか試してみましたが、これらの記号が含まれていてもエクスポートが可能な場合があるため、注意が必要です。当該記号が何文字か含まれているとエクスポートには失敗しましたが、1文字だけだと成功するケースもあり、、あるいはエクスポートできても正常に復号化できないのかもしれません。「%#&+」は含まないことをお薦めします。

エクスポートした証明書の形式

エクスポートした証明書は、pemファイルになっています。 マネジメントコンソールでエクスポートした場合は「証明書本文」「証明書チェーン」「証明書のプライベートキー」ごとにファイルが異なります。 後述するCLIでエクスポートした場合は1ファイルになっていて、先頭から「証明書本文」「証明書チェーン」「証明書のプライベートキー」が連続して書かれています。

※CLIでエクスポートした場合のpemファイル例

-----BEGIN CERTIFICATE-----
HOGEhogeHAgeHeGEHEgeHOGEhogeHAgeHeGEHEgeHOGEhogeHAgeHeGEHEge
HOGEhogeHAgeHeGEHEgeHOGEhogeHAgeHeGEHEgeHOGEhogeHAgeHeGEHEge
.....
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
PoyoPOYOPPPOpoyoPoyoPOYOPPPOpoyoPoyoPOYOPPPOpoyoPoyoPOYOPPPO
PoyoPOYOPPPOpoyoPoyoPOYOPPPOpoyoPoyoPOYOPPPOpoyoPoyoPOYOPPPO
.....
-----END CERTIFICATE-----
-----BEGIN ENCRYPTED PRIVATE KEY-----
DekoBOKOEDkobokODekoBOKOEDkobokODekoBOKOEDkobokODekoBOKOEDko
DekoBOKOEDkobokODekoBOKOEDkobokODekoBOKOEDkobokODekoBOKOEDko
.....
-----END ENCRYPTED PRIVATE KEY-----

証明書をインストールするOSがLinux系であれば、大抵の場合この形式で問題ないですが、Windowsの場合だとcer形式やpfx形式などに変換する必要があります。 詳細は割愛しますが、今回はpfx形式にしたかったため、OpenSSLを使って以下のコマンドで変換しました。(CLIでエクスポートしている場合は、自分でファイルを分割しましょう)

openssl pkcs12 -export -out certificate.pfx -inkey private_key.txt -in Certificate.txt -certfile Certificate_chain.txt
Enter pass phrase for private_key.txt:
Enter Export Password:
Verifying - Enter Export Password:

エクスポート際のプライベートキー用パスフレーズを訊かれ、更にエクスポートのパスワードを入力しろと言われます。エクスポートのパスワードはインポート時に必要になります。

数が多くてエクスポートがめんどくさいのでPowerShellでバッチ処理にする

証明書は無事使えるようになりましたが、この証明書をクライアント証明書として複数のPCにインストールする場合、マネジメントコンソールからでは結構しんどいのでCLIを使って自動化してみました。パスフレーズはランダムで生成していますが、便宜上コンソール上で表示してしまってたり、CSVに保存しているので、あくまで参考としていただければ幸いです。

# AWS CLIで使いたいAWSアカウントに設定しておく

Param(
    [Int]$CertNum    = 1,  # 発行する証明書の数
    [String]$CertArn = ""  # プライベートCAのARN
)

# パスフレーズ出力用CSVつくる
Set-Content -Encoding Default -Value "パスフレーズ" -Path "passphrase.csv"

# エクスポート繰り返し
for($i = 1; $i -le $CertNum; $i++){

    # エクスポートするファイル名称用
    $num = $i.ToString("000")

    # パスフレーズ生成
    #  以下の情報から、使用文字を絞る
    #    ・AWS ACM から証明書をエクスポートする際のパスフレーズに「%#&+」の 4 つの記号が使用不可
    #    ・PowerShellでは、ハイフン(「-」)で始まり途中にピリオド(「.」)を含む文字列があると、ピリオドの前で分割してしまう
    $pass = @(Add-type -AssemblyName System.Web;[System.Web.Security.Membership]::GeneratePassword(16,0)) `
            | %{$_ -replace "[^a-z0-9!""$'()*,./:;<=>?@[\]^_`{|}~]","0"}

    # パスフレーズまとめ用CSVにめも
    Add-Content -Encoding Default -Value $pass -Path "passphrase.csv"

    # プライベート証明書のエクスポート
    # https://docs.aws.amazon.com/ja_jp/acm/latest/userguide/gs-acm-export-private.html
    If(Test-Path "Certificate$num.pem"){
        Remove-Item "Certificate$num.pem"
    }
    aws acm export-certificate --certificate-arn $CertArn `
    --passphrase $pass | jq -r -j "(.Certificate,.CertificateChain,.PrivateKey)"  `
    | Set-Content -Encoding Default -Path "Certificate$num.pem"

    # エクスポートできたかチェック
    If(!(Test-Path "Certificate$num.pem")){
        Write-Host "あかーん エクスポートできなかったんや!"
        exit
    }

    Write-Host "パスフレーズ $pass でエクスポートしたで! ($i / $CertNum)"
}

プライベート証明書のエクスポート https://docs.aws.amazon.com/ja_jp/acm/latest/userguide/gs-acm-export-private.html

あとがき

プライベートCAを作成して、証明書を発行、エクスポート等等をおこなってみました。 プライベートCAの感想ではないですが、今回はじめてPowerShellを使ってみて、色々なことができることにちょっと感動でした!

なお、プライベートCAを削除しても証明書は無効化されませんので、配布した証明書は削除するか、あるいはCAを再構築して証明書を再発行するなどの処置が必要です。

さいごに、お試し中の方は無料トライアル期間中に削除することをお忘れなく、と兄が言っていました。それではまた、ごきげんよう。

高橋悠佑 (ポインコ兄) (執筆記事一覧)

健康志向です