let’s encryptで自動更新に失敗したときの原因と対策

サーバー
スポンサーリンク

こんばんは、ぼっちです。

当サイトはlet’s encryptによるHTTPS化をしています。

let’s encryptの証明書は3ヶ月で有効期限が切れてしまうので、cronによって自動更新コマンドを実行しております。

先日証明書の更新日が過ぎたのでサイトを確認したところ、

あれ……?

証明書の期限が切れて、いわゆるオレオレ証明書(自己署名)状態になっています。

これはまずいということで原因を探りました。

cronの設定確認

#!/bin/bash
systemctl stop httpd
cd /root/letsencrypt/
./letsencrypt-auto renew > /var/log/certbot.renew.log 2>&1;
systemctl start httpd

cron.dailyで回しているスクリプトです。3ヶ月前は正常に動いていました。

コマンドによる更新

let’s encryptの証明書更新コマンド、./letsencrypt-auto renewを手動で試してみます。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/XXX.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Attempting to parse the version 1.1.0 renewal configuration file found at
/etc/letsencrypt/renewal/XXX.com.conf with version 1.0.0 of Certbot. 
This might not work.

Plugins selected: Authenticator standalone, Installer None
Starting new HTTPS connection (1): acme-staging-v02.api.letsencrypt.org
Renewing an existing certificate

Performing the following challenges:
http-01 challenge for XXX.com
Cleaning up challenges

Attempting to renew cert (XXX.com) from /etc/letsencrypt/renewal/XXX.com.conf 
produced an unexpected error:

Problem binding to port 80: Could not bind to IPv4 or IPv6.. Skipping.

「produced an unexpected error:」というところで、何やらエラーが出ています。

実は当サイトは3つのドメインを管理していて、本サイトのドメイン、ゲームサイトのドメイン、そして旧ドメインです。

旧ドメインは元々当サイトを完全なるTech Blogとして使っていた時代に取得していたもので、上記の「XXX.com」がそれにあたります。

ドメインも証明書もとっくに失効済みにも関わらず、let’s encryptが存在しないドメインを更新対象と認識してエラー、それにつられて他のドメインもまとめて失敗扱いしていたのが原因のようです。

放っておけば勝手に失効するからと放置していたのがよくなかったようです。

旧ドメインを完全に消しましょう。

証明書の削除

証明書の削除コマンドは「certbot-auto delete -d ドメイン名」です。

# certbot-auto delete -d XXX.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log

Which certificate(s) would you like to delete?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: XXX.com
2: このサイト
3: ゲームサイト
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 1

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Deleted all files relating to certificate XXX.com.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

めでたく証明書も消え去り、当サイトとゲームサイトが残りました。やったー。

と、これで終わってはいけません。もう一度renewコマンドを試してみると……

# certbot renew --force-renew --dry-run 
(中略)
Running post-hook command: systemctl reload httpd
post-hook command "systemctl reload httpd" returned error code 1
Error output from post-hook command systemctl:
Job for httpd.service failed because the control process exited with error code. 
See "systemctl status httpd.service" and "journalctl -xe" for details.

今度はrelaod httpdでエラーが出ています。

httpdで読み込む設定に問題があるようです。

httpdの設定確認

ひとまず「systemctl status httpd」で状態を確認します。

# systemctl restart httpd.servicestatus httpd
* httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Fri 2020-01-24 22:47:14 JST; 3s ago
     Docs: man:httpd(8)
           man:apachectl(8)
  Process: 2784 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited, status=1/FAILURE)
  Process: 2714 ExecReload=/usr/sbin/httpd $OPTIONS -k graceful (code=exited, status=1/FAILURE)
  Process: 2783 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
 Main PID: 2783 (code=exited, status=1/FAILURE)

Jan 24 22:47:14 dream-tale.com systemd[1]: Starting The Apache HTTP Server...
Jan 24 22:47:14 dream-tale.com httpd[2783]: AH00548: NameVirtualHost has no effect and will be removed in the next release /etc/httpd/conf.d/ssl.conf:56
Jan 24 22:47:14 dream-tale.com httpd[2783]: AH00526: Syntax error on line 27 of /etc/httpd/conf.d/vhost_old.conf:
Jan 24 22:47:14 dream-tale.com httpd[2783]: SSLCertificateFile: file '/etc/letsencrypt/live/XXX.com/cert.pem' does not exist or is empty
Jan 24 22:47:14 dream-tale.com systemd[1]: httpd.service: main process exited, code=exited, status=1/FAILURE
Jan 24 22:47:14 dream-tale.com kill[2784]: kill: cannot find process ""
Jan 24 22:47:14 dream-tale.com systemd[1]: httpd.service: control process exited, code=exited status=1
Jan 24 22:47:14 dream-tale.com systemd[1]: Failed to start The Apache HTTP Server.
Jan 24 22:47:14 dream-tale.com systemd[1]: Unit httpd.service entered failed state.
Jan 24 22:47:14 dream-tale.com systemd[1]: httpd.service failed.

下の方で、消したはずのXXX.comの証明書を探してしまっています。

怪しいのは1行上の「/etc/httpd/conf.d/vhost_old.conf」のところです。

実は旧ドメインから現在のドメインに引っ越すとき、XXX.comのvhostの設定を「vhost_old.conf」とリネームしたのですが、これが原因でした。

おそらくですがvhostの仕様か、対象フォルダにあるすべてのconfファイルの設定を読み込んでしまうようです。

リネームするならvhost.conf.oldにすべきでした……。

とりあえず「vhost_old.conf」をローカルに退避して、リロード。

問題なくhttpdが再起動しました。

念のためcertbot renewの挙動確認

# certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

(中略)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** 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/本サイト/fullchain.pem (success)
  /etc/letsencrypt/live/ゲームサイト/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

上手くいきました!

教訓

①古いドメイン設定は綺麗に消す

②古い設定ファイルは拡張子をoldにする

3ヶ月後は上手くいくといいなぁ……。

コメント

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