らくがきちょう

なんとなく

lego で Let's Encrypt の証明書を Route53 DNS 認証で取得する

Let's Encrypt を利用すると無料で SSL/TLS サーバ証明書を取得することが出来ます。 certbot を使って証明書を取得する例をよく見かけますが、certbot は意外とフットプリントが大きく作られています。 その点、Go 言語で実装された lego はフットプリントが小さい割に必要十分な機能が実装されており、扱いやすいです。 今回は lego を使って Amazon Route53 を使った DNS 認証により SSL/TLS サーバ証明書を取得する手順をメモしておきます。

インストール

Linux 系 OS であればインストールは簡単です。 具体的には以下のコマンドを実行するだけです。 現時点で lego はバージョン 0.4.1 までリリースされているのですが、0.4.1 で Route53 による DNS 認証を行うとエラーになってしまいます。 この問題を回避する為に、意図的にひとつ前のバージョンである 0.4.0 をインストールします。

mkdir tmp
cd tmp
wget https://github.com/xenolf/lego/releases/download/v0.4.0/lego_linux_amd64.tar.xz
xz -dc lego_linux_amd64.tar.xz | tar xfv -
mv lego_linux_amd64 /usr/local/bin/lego
chmod 755 /usr/local/bin/lego
chown root:root /usr/local/bin/lego

証明書を取得する

証明書の更新処理を実施する為には Route53 のレコードを編集する権限が付与されている必要があります。 従って、lego を実行する EC2 インスタンスへ適用する IAM ロールには以下のような Policy を付与し、該当の DNS Zone を変更出来るようにしておきます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "route53:GetChange",
                "route53:ListHostedZonesByName"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "route53:ChangeResourceRecordSets"
            ],
            "Resource": [
                "arn:aws:route53:::hostedzone/<INSERT_YOUR_HOSTED_ZONE_ID_HERE>"
            ]
        }
    ]
}

用意が出来たら以下のように lego を実行します。 完了までしばらく時間がかかりますが、--path オプションで指定したディレクトリに証明書や鍵が保存されます。

lego --accept-tos \
     --path=/etc/letsencrypt \
     --email="email@example.com" \
     --dns="route53" \
     --domains="www.example.com" \
     run

証明書を更新する

DNS 認証で証明書を更新するには以下のように実行します。 更新時は run では無く、renew を指定します。 Let's Encrypt は一定期間の間に証明書取得を試行出来る回数が決まっています。 この制限に抵触しないよう、「証明書の有効期限が xx 日を下回る場合のみ、更新処理を行う」には --day オプションを指定します。 例えば --days 30 と指定した場合は「証明書の有効期限が 30 日未満の場合のみ、更新処理を行う」という振る舞いをします。

lego --accept-tos \
     --path=/etc/letsencrypt \
     --email="email@example.com" \
     --dns="route53" \
     --domains="www.example.com" \
     --days 30 \
     renew