101010

プログラミング備忘録とともに、ポエムってます。

Let's Encrypt自動更新ができなかったときの解決法 | CentOS 6.x SSL

以前に こちらの記事 で設定したLet's Encryptの自動更新がうまくできず、またもや次のようなメールが届いてしまった。

Hello,

Your certificate (or certificates) for the names listed below will expire in 19 days (on 31 Mar 19 18:05 +0000). Please make sure to renew your certificate before then, or visitors to your website 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.

律儀に同じメールを定期的に送ってくるボットだね、まったく!まあなんとかLet's Encryptの自動更新が無事に解決できたのでメモを残しておくことにした。

エラーログの確認をする

まずはLet's Encryptのログを確認してみる。

cat /var/log/letsencrypt/letsencrypt.log

すると次のような更新失敗のエラーがログに残っていた。

2019-03-01 14:00:09,322:DEBUG:certbot.plugins.selection:Requested authenticator standalone and installer None
2019-03-01 14:00:09,323:DEBUG:certbot.renewal:no renewal failures

cronの問題なのかなんなのか。まずは手動で実行して更新できるか確認してみる。

/usr/bin/certbot-auto renew

やっぱりSSL証明期限の更新が出来ない。次のようなエラーが吐かれた。

Upgrading certbot-auto 0.31.0 to 0.32.0...
Replacing certbot-auto...
Creating virtual environment...
Error: Command '['/opt/eff.org/certbot/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1

よくわからないけれど、Python関係でエラーになっている感じだ。

解決への糸口

先程のエラーを元にいろいろと調べてみた。すると次の記事にたどり着くことができた。

CentOS6でletsencript更新に失敗した時の解決策

こちらの記事によれば scl enable python27 './certbot-auto renew' というコマンドで実行すれば良いとのことである。しかし scl ってなに? python27 って python2.7 の間違いじゃないの?などと最初は思ったが、この方法で最終的に解決することができたのだ。これら謎のコマンドはこれから順を追って説明していく。

SCLをインストールする

まずはSCLってなんぞや?調べてみたら次の記事が参考になった。

Software Collections (SCL) を CentOS に入れてみた

ようするにSCLとは、本来ふるいCentOSでは使えないはずの最新アプリケーションを実行可能なようにしてくれるものらしい。例えばyumでインストールできないパッケージとか。

つぎのコマンドで有無を言わさずsclをインストールしてみる。

$ yum install centos-release-scl-rh

Python27のなぞ

ここまで来ると勘が働くようになる。最初に紹介されていたコマンド scl enable python27 './certbot-auto renew'certbot-autoPython2.7.x で実行すると言うことではなかろうか。調べてみるとやはり Python27 というのはSCLで提供されている Python2.7.x のパッケージ名のことのようだ。

なるほどですね! CentOS 6.x のyumでは Python2.6.x までしかインストールできないが、SCLを使えば Python2.7.x を使えるようにしてくれるということだ!

さっそくSCLで使用するための Python27 パッケージをインストールする。

$ yum -y install python27

インストールできたところで、現在のpythonのバージョンを確認してみよう。

$ python --version
Python 2.6.6

あれれ? Python 2.6.6 のままである。

しかしあわてることはない。✋ 先程インストールした Python27 パッケージをSCLで実行すればPython2.7.x を使うことができるのだ!

$ scl enable python27 bash
$ python --version
Python 2.7.13

みごと Python 2.7.13 へ切り替わった!

しかしシェルをログアウトすると Python 2.6.6 に戻ってしまうね。つまりSCLは一時的にパッケージを指定してプログラムを実行するものということでさぁーね。

SSL証明書の更新

ここまで来てようやく本題のSSL証明書の更新を行ってみることにしよう。次のように SCLPython27 を使って certbot-auto を実行してみる。

$ scl enable python27 '/usr/bin/certbot-auto renew'

するとSSL証明書の更新が無事に開始された。ほっ♨、としたところで確認する。あれれ?サイトにアクセスできない。非常に焦る💦。よく見ると次のようなエラーが出ていた。

httpd を起動中: [Tue Mar 12 11:51:51 2019] [warn] module ssl_module is already loaded, skipping
(98)Address already in use: make_sock: could not bind to address [::]:443
                                                           [  OK  ]

Apache起動でエラー

先程のApache起動時のエラーは「ssl_moduleが既に読み込まれてるからスキップしますよ」という内容のようだった。さらに調べてみると、SSLの設定が重複していることが原因でエラーが発生していることがわかった。

このことでピンときた!思い当たるフシがあるのだ。

すぐに cd /etc/httpd/conf.d/ で移動して ll コマンドを実行する。

思ったとおりだ。ディレクトリ内にSSL設定のファイルが2つ存在している。 末尾が ssl.conf で終わるファイルが2つある。

この原因は大昔のことだ。もともと私がApache設定のときに、デフォルトの ssl.conf をコピペして本番用の設定を書き込んだからである。

それによって未設定の ssl.conf ファイルをApacheが読み込んでしまい、本番用の設定ファイルが読み込まれないという自体になっていたのだった。しかし今までは問題にならなかったぞ?なんか怖くて不思議だ。

その問題は横においておき👀、使っていない ssl.conf をどうにかした後、Apacheを再起動させてみた。

無事にエラー無くApacheを起動することができた。ここでようやくサイトへ接続でき、SSL証明書の期限の更新も確認することができた。

以上ですべての修正を終えることができた。今までで、Let's Encryptの自動更新がスムーズにできたためしがない。今後またこのようなトラブルが起こるかもしれないと思うと、若干の不安は残っている。まぁ無料SSLという選択をしてしまったのだからそこはDo it yorselfってなことですね、分かります。それでもたくさんの失敗のおかげで、Linuxやサーバー管理の勉強になっているので良しとしましょうか。

cronの設定

おっと!最後にcronの設定も忘れずに書き換えておかなければならない。

今度こそ「自動更新がうまくいきますように!」と、強い思いを込めて!

00 14 01 * * /etc/rc.d/init.d/httpd stop && scl enable python27 '/usr/bin/certbot-auto renew' && /etc/rc.d/init.d/httpd start

記述方法 分 時 日 月 曜日 <実行コマンド>

参考