Let's Encrypt でワイルドカード証明書を取得する

(2018/07/23 追記しました)

こんにちは、masm11 です。

弊社では社内でいくつものサブドメインを使っています。abc.example.com, def.example.com, ghi.example.com, ... そしていずれも HTTPS でアクセスできるようにするため、Let's Encrypt で証明書を取得しています。 しかし、サブドメインは時々増え、そのたびに証明書を新たに作っていました。 わりと手間です。

その手間を軽減するため、Let's Encrypt でワイルドカード証明書を取得することにしました。 ワイルドカード証明書があれば、*.example.com 全てに使えるため、 サブドメインが増えても証明書を新たに作らなくてすみます。

そこで今回は、Let's Encrypt を使ったワイルドカード証明書の取得方法について書きたいと思います。 ただ、今回の作業が、certbot-auto が既に動いていて、それを使ってワイルドカード証明書を取得する、 というものだったため、 この記事は「今まで certbot-auto で取得・更新していて、それをワイルドカード証明書に移行したい」 という人向けとなります。

さて、Let's Encrypt でワイルドカード証明書を取得するには、DNS を使った認証をする必要があります。 そして、せっかく Let's Encrypt を使うのですから、更新を自動化したいものです。 そこで、DNS による認証を自動化します。

DNS サービスは世の中にいくつもあり、certbot(-auto) はそれらの中のいくつかの方式に対応しています。 弊社では Route53 を使っていますので、Route53 用のプラグインを使いました。

1. certbot-auto について

certbot-auto や、それが使っている Python のライブラリは、自動更新されているはずです。 従って、改めて更新する必要はありません。

2. certbot-dns-route53 プラグインのインストール

/opt/eff.org/certbot/venv/ に certbot-auto が使っている python の virtualenv がありますので、 ここに certbot-dns-route53 をインストールします。

sudo /opt/eff.org/certbot/venv/bin/pip install certbot-dns-route53

./certbot-auto plugins と実行すると、使えるプラグインのリストが表示され、 その中に dns-route53 が存在するのが確認できます。

* dns-route53
Description: Obtain certificates using a DNS TXT record (if you are using AWS
Route53 for DNS).
Interfaces: IAuthenticator, IPlugin
Entry point: dns-route53 = certbot_dns_route53.dns_route53:Authenticator

3. AWS 的な準備

AWS に新たなユーザ(IAM)を作ります。このユーザの権限で DNS を操作することになります。

このユこのユーザに与える権限は、JSON で与えるのが簡単です。 JSON は以下のようになります (/opt/eff.org/certbot/venv/lib/python2.7/site-packages/certbot_dns_route53/__init__.py そのままです)。

{
    "Version": "2012-10-17",
    "Id": "certbot-dns-route53 sample policy",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "route53:ListHostedZones",
                "route53:GetChange"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect" : "Allow",
            "Action" : [
                "route53:ChangeResourceRecordSets"
            ],
            "Resource" : [
                "arn:aws:route53:::hostedzone/YOURHOSTEDZONEID"
            ]
        }
    ]
}

これの YOURHOSTEDZONEID の部分を書き換えてアップロードすると、 権限を設定できます。 hostedzone ID は aws console に表示されていますので、それに書き換えて下さい。

このユーザの credentials を /root/.aws/credentials に保存します。 ファイルの中身は以下のようになります。

[default]
aws_access_key_id = ...
aws_secret_access_key = ...

4. 証明書を取得

いよいよ証明書の取得です。

sudo ./certbot-auto certonly \
  --server https://acme-v02.api.letsencrypt.org/directory \
  --email メールアドレス \
  --agree-tos \
  --dns-route53 \
  -d \*.ドメイン

ワイルドカード証明書を取得するには、letsencrypt のサーバを default とは異なる acme-v02 にする必要があるので、 それを指定しています。

また、サーバを変更するとメールアドレスも再度登録する必要があるので、--email を指定しています。 再登録となるので、同意確認もあります。同意確認のために --agree-tos を付けています。

--dns-route53 は Route53 を使った認証をする指定です。

実行すると、少し時間がかかります。DNS を使うため、TXT レコードを設定した後に、前の TXT レコードの TTL が切れるのを 期待して少し待っているようです。

5. nginx の設定を修正

sudo vi /etc/nginx/nginx.conf

証明書と秘密鍵は /etc/letsencrypt/live/ドメイン/ にあるので、設定を修正します。 ドメインは、*. を除いたものになります。

設定を修正したら nginx を restart します。

ブラウザからアクセスして、ワイルドカード証明書に切り替わっていることを確認しましょう。 問題なければ取得はこれで完了です。

6. 証明書を更新

これはまだ試せていないのですが、 証明書を取得した際のオプションは /etc/letsencrypt/renewal/ に保存されているので、 更新時にはオプションは必要ないはずで、

sudo ./certbot-auto renew --post-hook '/etc/init.d/nginx restart'

だけでできるはずです。

7. 旧証明書を revoke

これもまだ試していないのですが、 証明書の自動更新まで確認できたら、旧証明書は revoke しておくのが良いでしょう。

sudo ./certbot-auto revoke --cert-path /etc/letsencrypt/live/ホスト名/fullchain.pem

revoke すると、証明書ファイルは削除され、それ以降は renew による更新の対象にならなくなります。

まとめ

弊社ではこの手順で取得しました。今のところ問題ありませんが、更新が問題なくできるか、ちょっとドキドキです。


2018/07/23 追記。

これだけでうまくいくと思っていたのですが、予想外の事態が発生しました。 certbot-dns-route53 が削除されてしまいます。

certbot-auto は、実行された時に certbot-auto 自身や必要としている python ライブラリを更新しています。 おそらくこの時に削除されているものと思われます。

いくつか対策を実施して、現在動作確認中です。 今回の証明書更新は手動で実行したので、2ヶ月後に確認できると良いな、と思っています。


ではまた。