Route53+DNS-01のLet'sEncryptを自動更新する
ググると日本語の記事も結構出てくるんですが、どれも私の環境ではうまく動かなかったので自分なりにやりました。
前提
certbot-external-authは下記でインストール
https://github.com/EnigmaBridge/certbot-external-auth
上のURLを参考に
pip install certbot pip install certbot-external-auth
でインストールできる。
コード
renew.sh
#!/bin/sh certbot certonly \ -d sub1.example.com \ -d sub2.example.com \ --email test@example.com \ --agree-tos \ --preferred-challenges dns \ --keep-until-expiring \ --text \ --configurator certbot-external-auth:out \ --certbot-external-auth:out-public-ip-logging-ok \ --certbot-external-auth:out-handler /path/to/hook.sh # apacheなら systemctl restart httpd # nginxなら # systemctl restart nginx
hook.sh
#!/bin/sh set -e cmd="$1" shift case "$cmd" in perform) HOSTED_ZONE_ID="/hostedzone/YOUR_HOSTED_ZONE_ID" FILENAME=`date "+%Y%m%d%H%M%S"`.json DIR=/path/to/json_dir/ # 環境変数チェック if [ -z "$domain" ] || [ -z "$validation" ]; then echo "Undefined environment variable" exit 1 fi # 設定用jsonファイルを書き出し cat <<EOT > $DIR$FILENAME { "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": "_acme-challenge.$domain", "Type": "TXT", "TTL": 60, "ResourceRecords": [ { "Value": "\"$validation\"" } ] } } ] } EOT # jsonファイルをアップロードしてTXTレコードを追加 aws route53 change-resource-record-sets --hosted-zone-id "$HOSTED_ZONE_ID" --change-batch file://$DIR$FILENAME # DNS反映待ち sleep 60 ;; *) ;; esac
使い方
renew.shをcronに登録して毎月1回実行すれば更新されるはず。
説明
certbot-external-authってやつがDNS-01のチャレンジを行うときに色々なタイミングでフックしてくれます。
そのフックを利用してチャレンジ前にTXTレコードを書き換えて認証してもらうって流れです。
どのタイミングでフックされるかや、どういう環境変数を渡してくれるかは下記を参考にしてください。
github.com
hook.shの方はどのフックタイミングかを見極めてperformのときにTXTレコードを書き換えます。
hosted_zone_idはRoute53にアクセスしてHosted zonesを見ればわかります。
awsコマンドでRoute53の変更を行うにはjsonを使うので、設定用jsonを書き出します。
書き出したjsonをawsコマンドでアップロードします。
チェレンジ前にDNSの設定が反映されてる必要があるのでTTLの60秒待ちます。
その後はcertbotが勝手にやってくれます。
最後にWebサーバーを再起動すれば新しい証明書になります。
注意点
本番でやる想定なので「--keep-until-expiring」というオプションをつけてます。
これは証明書の更新が必要ない場合は発行しないというオプションです。
証明書の有効期限にかかわらず発行させる場合は「--force-renewal」というオプションをつけます。
このオプションをつけて実行する場合Let's Encryptのレート制限に引っかからないように注意しましょう。
Rate Limits - Let's Encrypt - Free SSL/TLS Certificates