Let's Encryptの証明書の有効期限が切れそうになったので、
マニュアル通り以下のコマンドを実行しました。
sudo certbot renew
問題発生
しかし以下のエラーが発生して更新できませんでした。
Saving debug log to /var/log/letsencrypt/letsencrypt.log
-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/mygitlab.example.com.conf
-------------------------------------------------------------------------------
Cert is due for renewal, auto-renewing...
Renewing an existing certificate
Performing the following challenges:
tls-sni-01 challenge for mygitlab.example.com
nginx: [error] invalid PID number "" in "/run/nginx.pid"
Cleaning up challenges
nginx: [error] invalid PID number "" in "/run/nginx.pid"
Encountered exception during recovery
nginx restart failed:
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/certbot/error_handler.py", line 99, in _call_registered
self.funcs[-1]()
File "/usr/lib/python2.7/dist-packages/certbot/auth_handler.py", line 284, in _cleanup_challenges
self.auth.cleanup(achalls)
File "/usr/lib/python2.7/dist-packages/certbot_nginx/configurator.py", line 824, in cleanup
self.restart()
File "/usr/lib/python2.7/dist-packages/certbot_nginx/configurator.py", line 590, in restart
nginx_restart(self.conf('ctl'), self.nginx_conf)
File "/usr/lib/python2.7/dist-packages/certbot_nginx/configurator.py", line 853, in nginx_restart
"nginx restart failed:\n%s\n%s" % (out.read(), err.read()))
MisconfigurationError: nginx restart failed:
Attempting to renew cert (mygitlab.example.com) from /etc/letsencrypt/renewal/mygitlab.example.com.conf produced an unexpected error: nginx restart failed:
. Skipping.
All renewal attempts failed. The following certs could not be renewed:
/etc/letsencrypt/live/mygitlab.example.com/fullchain.pem (failure)
1 renew failure(s), 0 parse failure(s)
このエラー内容のうち、よく見かける記述があります。
nginx: [error] invalid PID number "" in "/run/nginx.pid"
そうです!
GitLab Omnibus packageに入っているnginxは、上記のファイルにPIDを書き込まないので、
nginx -s stop
で終了できないのです。
調べてみると、nginxを停止していないと証明書の更新が失敗するので、
certbot renew
コマンド内で停止しようとして失敗してしまう事が原因でした。
対処法
GitLabを一旦停止します。
sudo gitlab-ctl stop
その後、テスト実行してみます。
(証明書の更新頻度に制限があるため何度も実行すると拒否されてしまいますが、
このテスト実行モードは何度でも試して大丈夫です)
sudo certbot renew --standalone --dry-run
今度はうまくいくはずです。
それでは、本番実行します。
sudo certbot renew --standalone
しかし、またしてもエラー発生・・・
Saving debug log to /var/log/letsencrypt/letsencrypt.log
-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/mygitlab.example.com.conf
-------------------------------------------------------------------------------
Cert is due for renewal, auto-renewing...
Renewing an existing certificate
Performing the following challenges:
tls-sni-01 challenge for mygitlab.example.com
Cleaning up challenges
Attempting to renew cert (mygitlab.example.com) from /etc/letsencrypt/renewal/mygitlab.example.com.conf produced an unexpected error: Problem binding to port 443: Could not bind to IPv4 or IPv6.. Skipping.
All renewal attempts failed. The following certs could not be renewed:
/etc/letsencrypt/live/mygitlab.example.com/fullchain.pem (failure)
1 renew failure(s), 0 parse failure(s)
原因は、テスト実行した後にnginxを勝手に起動しているために、それが邪魔をして失敗していました。
という訳でもう一度nginxを停止します。
因みに起動しているのはOmnibus packageの方ではないので通常通り、
sudo nginx -s stop
で停止します。
これでうまくいくはずです。
最後に、またもや勝手に起動したnginxを停止して、
sudo nginx -s stop
GitLabを起動します。
sudo gitlab-ctl start
あとがき
対処法でrenewコマンドを実行する時に、
そういえば証明書を取得した時に「--standalone」を付けていたので、
こっちにも付けた方が良いかなと思って付けていました。
調べてみると、このオプションはwebサーバが稼働していない時に、
仮のwebサーバを起動するためのもので、
それで勝手にnginxが起動していたみたいです・・・