letsencryptで証明書を取得するときにはまったこと


letsencryptの成長が目覚ましいですね。

そもそもLet's Encryptだったり、LetsEncryptだったり検索キーワードが複数あるため情報が散らばっているせいで、最新情報を追いにくくはありますが、そんな影響をものともしないくらいの成長具合が見られます。

かつては、letsencryptだった実行コマンドが、letsencrypt-autoになったり、certbotに変わったりして、現在は、certbot-autoで落ち着いたようです。

シェルに書いたり、Dockerで記述したりする記事を見かけますが、実行コマンドが変わっても修正箇所を最小限にしたりと、みんないろんな工夫をしているようです。

実際にはまったこと

以下のようなシェルスクリプトを用意して、その下の手順通り進めたところ、letencrypt側のエンドポイントにステージング環境が採用されて、ルート証明書が「Fake LE Intermediate X1」というフェイク証明書になってしまいました。

letsencrypt.sh
#!/bin/sh

#証明書のドメイン(,区切りで複数のドメインも指定可能)
DOMAIN=<YOUR DOMAIN>

#ドキュメントルート(上のドメインで接続可能である必要がある)
WEBROOT=<YOUR DOCUMENTROOT>

#メールアドレス(トラブル時にメールが届く)
EMAIL=<YOUR MAIL>

/usr/local/certbot/certbot-auto certonly -m $EMAIL /
--agree-tos --non-interactive $* /
--webroot -w $WEBROOT -d $DOMAIN

手順

※前提として、DNSの設定、Webサーバのセットアップ、certbotのインストールは完了していること。

1. 上記のletsencrypt.shを任意の場所に配置する。
2. 下記コマンドでテストサーバに接続して証明書を取得する。(※これが誤り)
sudo ./letsencrypt.sh --test-cert
3. 下記コマンドで、本番用の証明書を取得する。
sudo ./letsencrypt.sh --force-renewal

--force-renewを実行しすぎて、証明書取得の利用制限の閾値を超える

1日で5回、1週間で20回のどちらかの制限にかかって、証明書取得ができなくなりました。(どちらにかかったのか確認するすべがない)

日本語公式ページにも以下のように書いてあり、無効な証明書を取得していました。

--test-cert もしくは --staging
SSL/TLS サーバ証明書の取得時に、ステージングサーバを使用して、無効な証明書を取得します。
オプション --server https://acme-staging.api.letsencrypt.org/directory を指定するのと同じ動作です。
(デフォルト: False)

どうやって解決したか

メインのドメインはEV証明書も必要なため有償の証明書を割り当てていたため、letsencryptのドメインに含めることができず、泣く泣くサブドメインの変更を余儀なくされました。

ところが、変更後のサブドメインの証明書を取得する際には、2.の手順のところで、--dry-runを指定した後で、--force-renewalを指定して再度実行したところ正しいルート証明書を取得することができました。