IPv6専用サイトでLet's Encryptの証明書更新がトラブった

所有しているウェブサイトの1つでIPv6専用のものがある。
Let's EncryptのTLS証明書を使用していて、certbotで管理していた。
で、同じホストで稼働している他の通常のホストと一緒にcertbotで証明書が自動更新される筈が、このIPv6専用サイトだけが証明書の更新に失敗していた。

何で失敗するのか解らなかったので手動で更新してみた。

# certbot renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /usr/local/etc/letsencrypt/renewal/hoge.example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert is due for renewal, auto-renewing...
Plugins selected: Authenticator standalone, Installer None
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for hoge.example.com
Cleaning up challenges
Attempting to renew cert (hoge.example.com) from 
/usr/local/etc/letsencrypt/renewal/hoge.example.com.conf produced an unexpected error: 
Problem binding to port 80: Could not bind to IPv4 or IPv6.. Skipping.                      
All renewal attempts failed. The following certs could not be renewed:
  /usr/local/etc/letsencrypt/live/hoge.example.com/fullchain.pem (failure)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
All renewal attempts failed. The following certs could not be renewed:
  /usr/local/etc/letsencrypt/live/hoge.example.com/fullchain.pem (failure)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1 renew failure(s), 0 parse failure(s)

Problem binding to port 80: Could not bind to IPv4 or IPv6と表示されている。「IPv4とIPv6のポート80のどちらかが繋がらないよ」ということか。そりゃそうだIPv6専用サイトなんだから。どうも証明書の対象ウェブサイトが稼働している限りはIPv4への接続は必須っぽい。(IPv6は必須じゃない?)
certbotで特定のホストだけIPv4無しで更新させるという指定は無いっぽい。
と、思ったら、ウェブサーバが停まってたら(インターネットから繋がらなければ)上手くいくとの情報が。

以下のservice nginx hogeというのはFreeBSDでNginxのサービスをhogeしろというコマンド

/usr/local/bin/certbot renew --quiet && service nginx reload

上はこれまでcrontabに書いていたコマンド部分。
certbotで証明書の更新をして、成功したら、Nginxの設定を再読込みするという内容。
これだとウェブサーバのダウンタイムは限りなくゼロに近いけど、Nginxが動いたままなので証明書の更新NGになった。(IPv6専用サイト以外の証明書は更新される。)


service nginx stop; /usr/local/bin/certbot renew --quiet; service nginx start

Nginxを停止して、certbotで証明書を更新して、Nginxを起動、という内容に書き換えた。
こちらは数秒から1分程度とはいえウェブサーバのダウンタイムがしっかり発生する。crontabで頻繁に起動させないように、さらに実行する時間も注意。月1,2回深夜に実行する程度が無難?

手動でやってみた。

# service nginx stop
Stopping nginx.
Waiting for PIDS: 63339.
# certbot renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log

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

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
new certificate deployed without reload, fullchain is
/usr/local/etc/letsencrypt/live/hoge.example.com/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
中略

# service nginx start
Performing sanity check on nginx configuration:
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
Starting nginx.

うん、上手くいく。(黄字部分)
でも、謎仕様だなぁ。