tabimoba.net

とあるエンジニアの雑記帳

certbot-dns-sakuracloudを利用したLet's Encrypt証明書更新に失敗する場合の原因と対応方法

はじめに

DNSサーバとしてさくらのクラウドDNSを利用している場合、certbot-dns-sakuracloudを利用することで、DNS認証によるLet's Encryptの証明書追加および更新を自動化することができますが、更新時に以下のようなメッセージが表示され、証明書の更新に失敗する場合があります。

※以下はhoge.localという架空のドメインを例にしていますが、このようなドメインは当然さくらのクラウドDNSやLet's Encryptでは扱えません。

# certbot renew --force-renewal --server https://acme-v02.api.letsencrypt.org/directory
(略)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/hoge.local.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Plugins selected: Authenticator dns-sakuracloud, Installer None
Renewing an existing certificate
Performing the following challenges:
dns-01 challenge for hoge.local
dns-01 challenge for hoge.local
Unsafe permissions on credentials configuration file: /root/.sakura
不適切な要求です。パラメータの指定誤り、入力規則違反です。入力内容をご確認ください。
_acme-challenge のTTLは全て同じである必要があります
Cleaning up challenges
Attempting to renew cert (hoge.local) from /etc/letsencrypt/renewal/hoge.local.conf produced an unexpected error: Error adding TXT record: 400 Client Error: Bad Request for url: https://secure.sakura.ad.jp/cloud/zone/is1a/api/cloud/1.1/commonserviceitem/xxxxxxxx. Skipping.
All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/hoge.local/fullchain.pem (failure)

原因

以下のファイルより、 ttl = 60 という記述が確認できます。これによって、更新時にこれから追加される _acme-challenge TXTレコードに設定される(あるいは既存の _acme-challenge TXTレコードに設定されていることが期待されている)TTLが60秒であることがわかります。

https://github.com/certbot/certbot/blob/master/certbot-dns-sakuracloud/certbot_dns_sakuracloud/dns_sakuracloud.py

class Authenticator(dns_common.DNSAuthenticator):
    """DNS Authenticator for Sakura Cloud DNS
    This Authenticator uses the Sakura Cloud API to fulfill a dns-01 challenge.
    """

    description = 'Obtain certificates using a DNS TXT record ' + \
                  '(if you are using Sakura Cloud for DNS).'
    ttl = 60

    def __init__(self, *args, **kwargs):
        super(Authenticator, self).__init__(*args, **kwargs)
        self.credentials = None

対応

既存の _acme-challenge TXTレコードのTTLを全て60秒に揃えたうえで、

# certbot renew --force-renewal --server https://acme-v02.api.letsencrypt.org/directory

を実行することで、正常に(前述の問題が発生すること無く)証明書更新が行なえるようになります。