Scribble at 2022-03-07 22:46:45 Last modified: 2022-03-08 08:20:46
Mar 1 04:00:01 CROND[14984]: (root) CMD (certbot renew 2>&1 | mail -s "Let's Encrypt update information" system.info@%%%%%.co.jp && systemctl restart httpd)
上記は、/var/log/cron.log で取得した cron のログである。僕がメンテナンスしてるウェブ・サーバでは、この5年くらいのあいだに専有のサーバだと常時 SSL にするのが当たり前になってきたのだが、その SSL サーバ証明書は無料で取得・運用するのも当たり前になってしまっている。これは、もともと金がない自治体だけに限らず、企業だろうと同じことだ。要は、ウェブ・コンテンツの制作や運用に割く予算なんて大手だろうと零細だろうと企業の企画部や広報部にはないのである。よって、受ける側も有償の EV SSL 認証なんて取得する道理はないわけで、当然だが Let's Encrypt しか選択肢がなくなる。それでも、インストールしたり更新管理する僕の工数すら無料の案件が多いのだから、受託側の持ち出しが何年も続いている。これでは損益分岐点を超える実績など簡単に維持できないのは当たり前で、そもそもウェブ制作という業務そのものに事業としての継続性がないのである。
これは、印刷屋とかデザイン事務所よりも酷い。なぜなら、彼らは目に見える機材や工数よりも必要となる工数がないからだ。紙へ印刷するために印刷屋がインクの製法を学び続ける必要などない(ウェブなら JavaScript の仕様を追いかけるのに等しい)し、版下を DTP デザインするために Adobe InDesign の開発に必要な C++ の知識をデザイナーがもつ必要はない。でも、ウェブではサイトを実装するためにウェブ・サーバの知識は(レンタルで借りるとしても)一定のレベルで必要だし、ウェブ・ページを制作するためにコーディングの仕様は学び続ける必要がある。しかし、こうしたリテラシーやスキルの習得・維持に要するコストは全て請求書や見積書に埋没する。もちろん僕の工数やノウハウも15年くらい埋没しているわけである(もちろん、見積もりに加算しろと何度も言ってるし、僕自身が見積もりを提出できる場合は必ず算定に入れている)。
そんなわけで、上記のようなログを引っ張り上げてウェブ・サーバのメンテナンスに必要な知識とか情報とか、あるいは問題が起きている場合の調査とかに、必要以上の工数とか僕自身の能力を使うのは、端的に言えば浪費に他ならない。これは、僕が会社の部長として言っているだけではなく、もちろん(哲学者として)生きている一人の人間としても、残された時間の無駄な使い方だと言っている。しかしそうは言え、今回のようなトラブル、つまり上記のログではわからないと思うが、certbot という Let's Encrypt のスクリプトが cron から実行されるタイミングで SSL サーバ証明書の更新に失敗しているという問題への対処方法を見つけて改善するという経緯から、今後の仕事でも役に立つ対策は立てられると期待しているわけである。期待できる根拠がなければ、こんなもの必要に応じて僕が ssh ターミナルを使って手動で証明書を更新すればいいだけだ。そして、実際にさきほど僕は手動で証明書を更新したわけである。しかし、cron というタスクの自動実行プログラムを使っておきながら自動で任せられないというのは、コンピュータを使うソフトウェアの設計・実装者としてだけでなく、そのソフトウェアを使う人間として恥ずべきことであろう。
00 04 01 * * certbot renew 2>&1 | mail -s "Let's Encrypt update information" system.info@%%%%%.co.jp && systemctl restart httpd
上記が crontab に root ユーザとして登録しているタスクである。先頭の「00 04 01 * *」は、毎月の1日の早朝4:00に、それ以下のコマンドを実行するという意味だ。コマンドの記述個所は、簡単なことだが、certbot という Let's Encrypt のスクリプトを実行して、"renew" という証明書の更新を指示している。その結果を mail コマンドで指定されたアドレスへ送信するとともに、ウェブ・サーバの Apache を再起動させる。しかし、メールは来ていない。そこで、Let's Encrypt の実行ログを見てみると、
2022-03-01 04:00:03,647:ERROR:certbot._internal.log:An unexpected error occurred:
2022-03-01 04:00:03,647:ERROR:certbot._internal.log:IOError: [Errno 32] Broken pipe
となって、途中で処理が停止している。手動で "# certbot renew" とやれば全く問題なく証明書が更新できるのに、どうして cron から自動のタスクとして実行するとエラーで停止してしまうのか。
一つの問題は certbot が 1.11.0 と古いことにある。現在、certbot は CentOS 7(いや CentOS という OS すらメンテナンスが終わってしまう予定なのだが)の古いバージョンだと yum でしか更新できないのだが、yum で更新できる certbot は限界があり、CentOS を 7.6 以上のバージョンにしたうえで snap というパッケージ管理ツールへ移行し、それから certbot を最新版(少なくとも 1.16.0 以上)へアップデートしないと、stdout へのログを出力できないというわけである。そこで I/O のエラーが起きるらしい。
既に動いているサーバで簡単に OS のバージョンを上げるわけにはいかないので、これについてはしばらく証明書を手動で更新し続けないといけないらしい。よって、エラーが出ても意味がないから、ひとまず cron のタスク(本来は「ジョブ」と呼んでいる)は削除しておこう。というか、いま作業したのだが、実際には "crontab -e" で上記の行の先頭に "#" を挿入して「コメント・アウト」しただけだ。
[追記:2022-03-08] ・・・と思ったが、自動でジョブを実行させるのが趣旨だったのだから、これでは本末転倒だ。さきほど起きてすぐに "00 04 01 * * certbot renew | systemctl restart httpd" として再びタスクを登録した。つまり、stdout への出力に問題があるなら、そこだけ省略してやればいい。