Skip to Content

EC2とRoute53でLet's Encryptのワイルドカード証明書取得

概要

特定のアクセスのみに制限されたEC2と、Route53を使いLet’s Encryptからワイルドカード証明書を取得する

結論

Route53のDNS-01チャレンジは少し難しそうな感じがするが、
全部LEGOがよしなにやってくれたので手軽にワイルドカード証明書が取得できる

図解

EC2インスタンス上でLEGOコマンドを利用してLet’s Encryptからワイルドカード取得までの流れ
DNS-01チャレンジを使い、EC2にはWEBサーバの起動も80番ポートの解放も不要で行う

Welcome :: Let’s Encrypt client and ACME library written in Go.

DNS-01チャレンジ

ドメイン名が登録されているDNSサーバ(今回はRoute53)にLet’s Encryptが指定したレコードを登録します
そのレコードをLet’s Encryptから見て確認できれば、あなたはドメインの所有者に間違いないですね、ヨシ!証明書発行します!!

どうやってヨシ!するの?

Let’s Encryptが発行したトークンをドメイン名が登録されているDNSサーバに
_acme-challenge.<YOUR_DOMAIN>の名前で値に発行されたトークンを入れてTXTレコードを登録する
Let’s Encryptは_acme-challenge.<YOUR_DOMAIN>の名前をDNSで引いて、TXTレコードが発行されたトークンと同じか確認する

なるほど、おもしろいヨシの仕組みだ

チャレンジのタイプ - Let’s Encrypt - フリーな SSL/TLS 証明書

なにがうれしいの?

よく使われるHTTP-01チャレンジのデメリットが解決される

HTTP-01チャレンジのデメリット

  • 証明書を取得したいサーバでWEBサーバ(apache, Nginxなど)が起動していないといけない
    • 証明書使いたいサーバであればだいたいこの条件は満たせている
  • 80番ポートを全世界に向けてオープンにしていないといけない
    • 社内アクセス限定や、特定のグローバルIP・ポートに制限したWEBサーバでは証明書が取得できない
      • ここが個人的に大きなポイント(仕事で使いたかったときに)
  • ワイルドカード証明証が発行できない
    • ここも個人的に大きなポイント(仕事で証明書を都度発行するの面倒くさかったから)

DNS-01チャレンジのデメリットとしては小難しそうなだと思われることが大きい
今回はLEGOとRoute53の組み合わせで簡単に実現する

チャレンジのタイプ - Let’s Encrypt - フリーな SSL/TLS 証明書

構築手順

必要なもの

  • EC2インスタンス1台
  • Route53操作用のIAMロール1個
  • Route53で管理しているドメイン(ホストゾーン)1個
  • LEGO(Let’s Encrypt Client)

EC2

EC2インスタンスからLEGOを利用して、Let’s Encryptへ証明書取得を行います
Go製のシングルバイナリなのでt3a.nanoでも動きます

環境

項目 バージョン 備考
OS Amazon Linux2 -
LEGO v3.7.0 Releases · go-acme/lego

EC2構築

SSH接続可能なEC2インスタンスを新規作成します

  • EC2インスタンスからインターネット接続が可能なこと
  • セキュリティグループは最低限SSH接続のみ許可されていればよい

LEGO実行環境構築

EC2インスタンスにSSH接続後、下記コマンドを実行してlegoコマンドを実行可能な状態を作成

1
2
3
4
5
6
cd /tmp
wget https://github.com/go-acme/lego/releases/download/v3.7.0/lego_v3.7.0_linux_amd64.tar.gz
tar zxvf lego_v3.7.0_linux_amd64.tar.gz
sudo mv lego /usr/local/bin/
sudo chmod 755 /usr/local/bin/lego
chown ec2-user. /usr/local/bin/lego
動作確認

legoコマンドが実行できるかバージョン表示で確認

1
2
$ lego --version
lego version 3.7.0 linux/amd64

Route53

証明書を取得したいドメインがRoute53に登録されていること
Route 53 でドメインを取得・購入する(2019版) | Developers.IO

この手順ではabashiri.cityドメインを利用して説明します

IAMロール・ポリシー

EC2インスタンスからRoute53を操作できるようにEC2用のIAMロールを作成
EC2インスタンスにロールをアタッチ

LEGOで必要なRoute53ポリシー例

arn:aws:route53:::hostedzone/ZZZZZZZZZZZZZZZZZZZ...はRoute53のホストゾーンIDを入力
よくわからなかったら制限が緩くなるけどarn:aws:route53:::hostedzone/*に置き換えても可

必要なポリシーは公式ドキュメントを参考にした
Amazon Route 53 :: Let’s Encrypt client and ACME library written in Go.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "route53:GetChange",
                "route53:ChangeResourceRecordSets",
                "route53:ListResourceRecordSets"
            ],
            "Resource": [
                "arn:aws:route53:::hostedzone/ZZZZZZZZZZZZZZZZ",
                "arn:aws:route53:::change/*"
            ]
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": "route53:ListHostedZonesByName",
            "Resource": "*"
        }
    ]
}

IAMロール名をLegoRoute53EditRole
ポリシー名をLegoRoute53EditPolicyと名付け作成
※ 名前は任意です

EC2インスタンスにロールをアタッチ

さきほど作成したIAMロールをアタッチ

証明書取得作業

EC2インスタンスにSSH接続
legoコマンドを実行し、所定のディレクトリに証明書を保管する

証明書取得コマンド

--path=: 証明書が保存されるパス
--email=: 登録メールアドレス
--domains=: Route53に登録されているドメイン名
※ワイルドカード証明書を取得するため、*.をドメイン名頭につける

1
2
3
4
5
6
lego --accept-tos \
    --path=/home/ec2-user \
    --email="your_mailaddress" \
    --dns="route53" \
    --domains="*.your.domain" \
    run
実行例
1
2
3
4
5
6
lego --accept-tos \
    --path=/home/ec2-user \
    --email="xxx@gmail.com" \
    --dns="route53" \
    --domains="*.abashiri.city" \
    run

正常終了時の実行ログ

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2020/05/27 16:47:03 No key found for account xxx@gmail.com. Generating a P384 key.
2020/05/27 16:47:03 Saved key to /home/ec2-user/accounts/acme-v02.api.letsencrypt.org/xxx@gmail.com/keys/xxx@gmail.com.key
2020/05/27 16:47:04 [INFO] acme: Registering account for xxx@gmail.com
!!!! HEADS UP !!!!

Your account credentials have been saved in your Let's Encrypt
configuration directory at "/home/ec2-user/accounts".

You should make a secure backup of this folder now. This
configuration directory will also contain certificates and
private keys obtained from Let's Encrypt so making regular
backups of this folder is ideal.
2020/05/27 16:47:06 [INFO] [*.abashiri.city] acme: Obtaining bundled SAN certificate
2020/05/27 16:47:08 [INFO] [*.abashiri.city] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz-v3/4840202104
2020/05/27 16:47:08 [INFO] [*.abashiri.city] acme: use dns-01 solver
2020/05/27 16:47:08 [INFO] [*.abashiri.city] acme: Preparing to solve DNS-01
2020/05/27 16:47:09 [INFO] Wait for route53 [timeout: 2m0s, interval: 4s]
2020/05/27 16:47:45 [INFO] [*.abashiri.city] acme: Trying to solve DNS-01
2020/05/27 16:47:45 [INFO] [*.abashiri.city] acme: Checking DNS record propagation using [10.1.0.2:53]
2020/05/27 16:47:45 [INFO] Wait for propagation [timeout: 2m0s, interval: 4s]
2020/05/27 16:47:46 [INFO] [*.abashiri.city] The server validated our request
2020/05/27 16:47:46 [INFO] [*.abashiri.city] acme: Cleaning DNS-01 challenge
2020/05/27 16:47:47 [INFO] Wait for route53 [timeout: 2m0s, interval: 4s]
2020/05/27 16:48:18 [INFO] [*.abashiri.city] acme: Validations succeeded; requesting certificates
2020/05/27 16:48:20 [INFO] [*.abashiri.city] Server responded with a certificate.
補足

コマンド実行中にRoute53から対象のドメイン(ホストゾーン)を確認
DNS-01チャレンジのTXTレコードが追加されていることが確認できる
コマンド終了後、自動的にこのレコードは削除されていた

また、挙動確認のためコマンド実行中にCtrl+Cで処理を打ち切ってみた
TXTレコードが自動削除されないため残り続けるので手動で削除が必要

証明書確認

--path=で指定したディレクトリ配下にcertificatesディレクトリが新規作成され保存されている

1
2
3
4
5
6
7
8
9
$ pwd
/home/ec2-user/certificates

$ ll
合計 16
-rw------- 1 ec2-user ec2-user 3323  5月 27 16:48 _.abashiri.city.crt
-rw------- 1 ec2-user ec2-user 1648  5月 27 16:48 _.abashiri.city.issuer.crt
-rw------- 1 ec2-user ec2-user  236  5月 27 16:48 _.abashiri.city.json
-rw------- 1 ec2-user ec2-user  288  5月 27 16:48 _.abashiri.city.key

次回、今回取得した証明書をNginxに配置し動作確認を行う

感想

IAMポリシーでホストゾーンの制限に悩んだ以外は、とくに詰まる要素はありませんでした
CloudFormationで作成していたため、実際はCloudFormationの書き方に不慣れな部分もあり結構手こずりました

IAMロールの知識不足で詰まったところは別記事にまとめています
CloudFormationでIAMロール作成と、インスタンスプロファイルを学ぶ | infraya.work

参考

AmazonLinux2 で lego を使い Route53 認証でサーバ証明書を取得する - らくがきちょう
Let’s Encrypt のチャレンジ方式 | knooto
DNS-01方式によるLet’s Encrypt自動更新 - ぱろっくの日記