CloudFlareのせいで何をやっても証明書が更新できなかったお話

この記事は約15分で読めます。

プロローグ

本サイトはLet’s EncryptのSSL証明書を利用し、かつCloudFlareのCDNを利用してエッジ証明書を利用しています。
今年の4月以降、cronで回している証明書更新が失敗しており、色々調査した結果ハマったので備忘録がてら記事にします。

certbot renewが失敗する

このサイトを立ち上げて早1年が経ちます。
4月にAWS Lightsailで構築した後、5月〜6月にかけて別のパブリッククラウド基盤上にWPのWEBサーバを立てています。

Lightsail時代からLet’s Encryptにはお世話になっていて、ずっとcronで証明書の更新は済ませていました。
2021年6月に入ってから、Let’s Encryptからこんなメールが入りました。

Hello,

Your certificate (or certificates) for the names listed below will expire in 19 days (on 01 Jul 21 10:19 +0000). Please make sure to renew your certificate before then, or visitors to your web site will encounter errors.

We recommend renewing certificates automatically when they have a third of their total lifetime left. For Let’s Encrypt’s current 90-day certificates, that means renewing 30 days before expiration. See https://letsencrypt.org/docs/integration-guide/ for details.

www.bambiman.com

For any questions or support, please visit: https://community.letsencrypt.org/ Unfortunately, we can’t provide support by email.

For details about when we send these emails, please visit: https://letsencrypt.org/docs/expiration-emails/ In particular, note that this reminder email is still sent if you’ve obtained a slightly different certificate by adding or removing names. If you’ve replaced this certificate with a newer one that covers more or fewer names than the list above, you may be able to ignore this message.

If you are receiving this email in error, unsubscribe at:
http://delivery.letsencrypt.org/track/unsub.php?u=XXXXXXXX
Please note that this would also unsubscribe you from other Let’s Encrypt service notices, including expiration reminders for any other certificates.

Regards,
The Let’s Encrypt Team

Let’s Encrypt certificate expiration notice for domain “www.bambiman.com”

およよとインスタンスにログインして手動で更新してみるも、失敗。

bambiman.com:~$ sudo certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/www.bambiman.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert is due for renewal, auto-renewing...
Plugins selected: Authenticator nginx, Installer nginx
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for www.bambiman.com
Waiting for verification...
Cleaning up challenges
Attempting to renew cert (www.bambiman.com) from /etc/letsencrypt/renewal/www.bambiman.com.conf produced an unexpected error: Failed authorization procedure. www.bambiman.com (http-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from https://www.bambiman.com/.well-known/acme-challenge/XXXXX [xxx.xxx.xxx.xxx]: "<html>\n<head><title>404 Not Found</title><script async src='/cdn-cgi/bm/cv/XXXXX/api.js'></script></head>\n<body bgcolor=\"whi"". Skipping.
All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/www.bambiman.com/fullchain.pem (failure)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/www.bambiman.com/fullchain.pem (failure)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1 renew failure(s), 0 parse failure(s)

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: www.bambiman.com
   Type:   unauthorized
   Detail: Invalid response from
   https://www.bambiman.com/.well-known/acme-challenge/XXXXX
   [xxx.xxx.xxx.xxx]: "<html>\n<head><title>404 Not Found</title><script
   async src='/cdn-cgi/bm/cv/XXXX/api.js'></script></head>\n<body
   bgcolor=\"whi"

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address.
bambiman.com:~$

特にWEBサーバ側では構成など大きく変えていないので、Let’s Encrypt側の仕様変更によるものかと色々調べてみてもそれっぽいものは出てこず。

nginxでhttpアクセスのリダイレクトなどをしていたので、configを色々弄るも全く変わらず。
(むしろ悪化することが多かった)

そんなこんなで放置していたら、見事に有効期限が切れてしまいました。
しかしながらCloudFlareのエッジ証明書はCDNのフロント側で証明書を自動で管理してくれるため、今回CDNを使っている恩恵を受けることができました。

Origin(Web)サーバの証明書が切れた状態だと、Originサーバとキャッシュサーバ間のSSL通信が出来なくなるんですかね。(小並感)

そんな恩恵をのんきに有り難く思っている所に、ふと疑問がよぎりました。

あれ、これCloudFlareが原因?

あまりよく理解していないですが、Let’s Encryptの動作としては80と445の通信が両方出ている認識で、nginxのConfigを弄ってもエラー内容が変わらないってことはCloudFlareのCDNが悪さをしているんじゃないかと仮説を立てました。

解決した後によくよくエラーを見返してみると、それらしきキーワードがありました。(関係あるかは知らん)

Attempting to renew cert (www.bambiman.com) from /etc/letsencrypt/renewal/www.bambiman.com.conf produced an unexpected error: Failed authorization procedure. www.bambiman.com (http-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from https://www.bambiman.com/.well-known/acme-challenge/XXXXX [xxx.xxx.xxx.xxx]: "<html>\n<head><title>404 Not Found</title><script async src='/cdn-cgi/bm/cv/XXXXX/api.js'></script></head>\n<body bgcolor=\"whi"". Skipping.

よくよくみると、”cdn-cgi”というキーワードがありました。

早速CloudFlareの管理コンソールに入って設定を眺めていると、早速怪しい設定を発見しました。

「常に HTTPS を使用」

スキーム「http」を持つすべてのリクエストを「https」にリダイレクトします。これは、ゾーンへのすべての http リクエストに適用されます。

って書いてあるので、めちゃくちゃ怪しいですよね。
しかも今回は80番でのACMEチャレンジに失敗しているので、余計怪しさアップです。

サクッと無効化して、再チャレンジです。

bambiman.com:~$ sudo certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/www.bambiman.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert is due for renewal, auto-renewing...
Plugins selected: Authenticator nginx, Installer nginx
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for www.bambiman.com
Waiting for verification...
Cleaning up challenges

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
new certificate deployed with reload of nginx server; fullchain is
/etc/letsencrypt/live/www.bambiman.com/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/www.bambiman.com/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bambiman.com:~$

拍子抜けするほど、上手くいってしまいました。
このままdry-runオプションを抜いて更新します。

bambiman.com:~$ sudo certbot renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/www.bambiman.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert is due for renewal, auto-renewing...
Plugins selected: Authenticator nginx, Installer nginx
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for www.bambiman.com
Waiting for verification...
Cleaning up challenges

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
new certificate deployed with reload of nginx server; fullchain is
/etc/letsencrypt/live/www.bambiman.com/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/www.bambiman.com/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bambiman.com:~$

無事Successになりました。

エピローグ

おそらく”常に HTTPS を使用”の状態で証明書を更新する方法はあると思いますが、nginxのリダイレクトで事足りているため今はこのままで運用したいと考えています。
今後時間がある時にちょっと調べてみて解決策があれば追記していこうかと思います。

記事は以上

タイトルとURLをコピーしました