ACMで外部の証明書を使用する場合の更新手順について

2019.02.19

大栗です。

AWS環境でhttpsを使う場合は、基本的にACMで証明書を発行してALBで使用すると思います。しかしACMはドメイン検証(DV)証明書であるため、組織認証(OV)や拡張認証(EV)の証明書を使用するには外部の証明書を使用する必要があります。ACM発行の証明書と異なり、証明書のインポート確認などをすべきで少々手順が面倒であるため、まとめてみます。

OV証明書とEV証明書

OV証明書は認証局が発行主体の組織の存在を確認してから発行されるものです。EV証明書はOV証明書より厳格な審査を行って発行する証明書です。

EV証明書はブラウザの種類によってアドレスバーに緑色の文字で組織名が表示されます。

やってみる

本当にOV証明書やEV証明書を用意するには手間と費用がかかるので、今回はLet's EncryptのDV証明書を利用します。

前提

対象のドメインはssl-test.example.comとします。適宜読み替えて下さい。

証明書の更新を想定しているため、本来設定すべきALBがすでにある想定です。またサービス提供中を想定して、証明書の確認や切り戻しができる手順としています。(切り戻しを考えない場合はACMで再インポートが一番簡単)

  1. (Let's Encryptで)証明書を発行する
  2. ACMに証明書をインポートする
  3. 検証用ALB+EC2を用意する
  4. 2.の証明書にアクセスして、内容を確認する
  5. ACMを更新する
  6. アクセスして、内容を確認する

1. (Let's Encryptで)証明書を発行する

本来はOV証明書やEV証明書を発行しますが、検証するために替わりにLet's EncryptでDV証明書を発行します。本来はOV証明書やEV証明書を発行するので、証明書がある場合は飛ばして下さい。

ここではクライアントをAmazon Linux 2とします。

基本はこちらのブログの内容です。

Amazon Linux 2のEC2を起動して、ポジトリパッケージをインストールします。

$ cd /tmp
$ wget -O epel.rpm –nv \
$ https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
$ sudo yum install -y ./epel.rpm

python2-certbot-apacheパッケージをインストールします。

$ sudo yum install -y python2-certbot-apache.noarch

初期設定のままのhttpdだとssl.confがあるとapachectl configtestが通らないので、ファイル名を変更して読み込み対象から外します。

$ sudo mv /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf.temp

起動したEC2にElastic IPを付与して、証明書を取得したいドメインでAレコードを設定します。しばらくしてAレコードが反映されていることをdigコマンドで確認します。

$ dig ssl-test.example.com +short
203.0.113.1

Let's Encryptの証明書を発行します。ssl-test.example.comは環境によって読み替えて下さい。

sudo certbot -i apache -a manual \
--preferred-challenges dns -d ssl-test.example.com

管理者用メールアドレスを入力します。

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer apache
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel):

利用規約に同意してAを入力します。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A

メールアドレスをElectronic Frontier Foundationmと共有するかを確認されます。本記事では共有しないで、Nを入力します。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o:

証明書を発行するにはIPアドレスのログに同意する必要があるのでYを入力します。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NOTE: The IP of this machine will be publicly logged as having requested this
certificate. If you're running certbot in manual mode on a machine that is not
your server, please ensure you're okay with that.

Are you OK with your IP being logged?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o:

DNSで_acme-challenge.ssl-test.example.comのドメインにTXTレコードとして表示された内容を設定します。TXTレコードが反映されたら次に進めます。TXTレコードの反映確認はdig -t txt _acme-challenge.ssl-test.example.com +shortというコマンドを実行してください。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.ssl-test.example.com with the following value:

GFyuogyiGuipGhiupgr5680yogHKhojhokfew20io0p

Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue

以下のように証明書がインストールされていない旨のメッセージが表示されますが、証明書自体は発行されます。

Waiting for verification...
Cleaning up challenges
Resetting dropped connection: acme-v02.api.letsencrypt.org
No vhost exists with servername or alias of ssl-test.example.com. No vhost was selected. Please specify ServerName or ServerAlias in the Apache config.
No vhost selected

IMPORTANT NOTES:
 - Unable to install the certificate
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/ssl-test.example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/ssl-test.example.com/privkey.pem
   Your cert will expire on 2019-05-19. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"

以下のように証明書が発行されます。/etc/letsencrypt/live/<ドメイン名>/以下に出力されます。

$ sudo ls -al /etc/letsencrypt/live/ssl-test.example.com/
合計 4
drwxr-xr-x 2 root root  93  2月 18 07:34 .
drwx------ 3 root root  59  2月 18 07:34 ..
-rw-r--r-- 1 root root 692  2月 18 07:34 README
lrwxrwxrwx 1 root root  55  2月 18 07:34 cert.pem -> ../../archive/ssl-test.example.com/cert1.pem
lrwxrwxrwx 1 root root  56  2月 18 07:34 chain.pem -> ../../archive/ssl-test.example.com/chain1.pem
lrwxrwxrwx 1 root root  60  2月 18 07:34 fullchain.pem -> ../../archive/ssl-test.example.com/fullchain1.pem
lrwxrwxrwx 1 root root  58  2月 18 07:34 privkey.pem -> ../../archive/ssl-test.example.com/privkey1.pem

ファイルの内容は以下の通りです。

ファイル名 内容
cert1.pem 証明書本文
chain1.pem 証明書チェーン
fullchain1.pem 証明書本文と証明書チェーンが一体になったもの
privkey1.pem 証明書のプライベートキー

2. ACMに証明書をインポートする

ACMに証明書をインポートします。

ACMのコンソールで証明書のインポートをクリックします。

証明書の内容を貼り付けて、レビューとインポートをクリックします。

インポートをクリックします。

このように証明書をインポートします。

3. 検証用ALB+EC2を用意する

証明書をアクセス確認するための環境を用意します。

まずEC2(Amazon Linux 2)を起動してhttpdをインストールします。

$ sudo yum install -y httpd

アクセス用ページを作成します。

$ curl -s http://169.254.169.254/latest/meta-data/instance-id | sudo tee /var/www/html/index.html
i-1a2b3c4d5e6f7g8h9

httpdを起動します。

$ sudo systemctl start httpd

アクセス確認します。

$ curl http://127.0.0.1/
i-1a2b3c4d5e6f7g8h9

次にALBを作成します。

EC2のコンソールのロードバランサーでロードバランサーの作成をクリックします。

Application Load Balancer作成をクリックします。

スキームをインターネット向け、リスナーのロードバランサーのプロトコルをHTTPS(セキュアHTTP)にします。

適切なVPC、適切なサブネットを選択します。

証明書について、以下のように設定します。

項目 内容 備考
証明書タイプ ACM から証明書を選択する (推奨)
証明書の名前 ssl-test.example.com 先ほど作成した証明書
セキュリティポリシー ELBSecurityPolicy-TLS-1-2-2017-01 適切なものを選択

適切なセキュリティグループを設定します。

ルーティングの設定を以下のように設定して次の手順: ターゲットの登録をクリックします。

項目 内容 備考
ターゲットグループ: ターゲットグループ 新しいターゲットグループ
ターゲットグループ: 名前 <任意>
ターゲットグループ: ターゲットの種類 インスタンス
ターゲットグループ: プロトコル HTTP
ターゲットグループ: ポート 80
ヘルスチェック: プロトコル HTTP
ヘルスチェック: パス /

作成したEC2インスタンスを登録します。

設定内容を確認して、作成をクリックします。

4. 2.の証明書にアクセスして、内容を確認する

そのままでは既存環境へアクセスしてしまうため、ローカル環境の名前解決をごまかして検証を行います。

まず検証用ALBのIPアドレスを確認します。

$ dig blog2-123456789.ap-northeast-1.elb.amazonaws.com +short
198.51.100.1
198.51.100.2

検証用ALBのIPアドレスをhostsファイルに設定します。以下の様な内容を追加します。macOSでは/etc/hosts、Windowsでは%WinDir%\System32\drivers\etc\hostsを編集して下さい。

198.51.100.1 ssl-test.example.com
198.51.100.2 ssl-test.example.com

キャッシュをクリアします。

macOSではsudo killall -HUP mDNSResponder、Windowsではipconfig /flushdnsを実行します。

ブラウザでアクセス

注意:chromeの場合はchrome://net-internals/#dnsにアクセスして、Clear host cacheをクリックしてからアクセスして下さい。

ブラウザでhttps://ssl-test.example.comにアクセスします。以下のようにエラー無くアクセスできることを確認します。

####

/etc/hostsまたは%WinDir%\System32\drivers\etc\hostsに追加したssl-test.example.comドメインの内容を削除します。

macOSではsudo killall -HUP mDNSResponder、Windowsではipconfig /flushdnsを実行してキャッシュを削除します。

5. ACMを更新する

証明書を更新します。

更新対象のロードバランサーを選択してリスナータブを選択します。HTTPSの行を選択して編集をクリックします。

一番下のデフォルトのSSL証明書をACM から (推奨)にしてインポートした証明書を選択します。選択後に右上の更新をクリックします。セキュリティポリシー は適切なものを選択して下さい。

証明書が更新されます。

6. アクセスして、内容を確認する

普通にブラウザでhttps://ssl-test.example.comにアクセスします。

証明書を確認するとインポートしたものになっていることが確認できます。

もし正常にアクセスできない場合には、5. 証明書を更新するの手順で更新前の証明書を選択して切り戻しします。

ALBで外部の証明書を利用している場合の切り替え手順は以上となります。

さいごに

EV証明書はブラウザのアドレスバーに組織名が表示されるなどブランディングを行いやすい証明書です。しかし証明書の自動更新などは行なえません。ACMで証明書を発行して自動更新したり、Let's EncryptとCertbotで自動更新したりしたほうが運用が楽になります。証明書の使い分けを意識してブランディングを運用性のバランスを取っていきましょう。