certbot renewでApacheがCPU 100%に張り付くでござるの巻き
SSL証明書の期限が切れた状態でcertbot renewを行うと、ApacheプロセスのCPU利用率が100%となりハング状態になるっぽい。apachectlで止めようとしても(弊鯖はご存じのとおりFreeBSDなのでservice apache24 stopだが)、応答が返ってこずkillせざるを得ないという状況。環境は以下のとおり。
- FreeBSD 13.0-RELEASE-p4
- Apache 2.4.51
- certbot 1.21.0
- certbot-apache 1.21.0
- Python 3.8.12
- webrootモードで運用
weekly_certbot_enableでもって週次で証明書の確認&更新が行われるはずなのに、なんで切れてるの?そもそも期限切れになったからと言って、なんでhttpdがハング状態になるの?と疑問は尽きないのだが、ひとまず脇に置いといて、この状況に陥ったらcertbot certonlyを使って手動で証明書を更新してやる。
# certbot certonly --webroot -w /path/to/document_root -d example.com
証明書更新後、certbot renewでhttpdが暴走しないことを確認する(renewが正常に終われば暴走はしてない。)
それにしても原因は何なんだろうなー。以前、同様の状況が発生した時は、apacheやモジュールの更新を行っていたのでバイナリ間の何らかの不整合くらいで流したが、たぶん今回と同じ原因だったんだろう。さらにその以前は正しく動いていたような気がしなくもない(結構期限切れをやらかしていたので確証が持てない)ので、よくわかりません。
詳しい方教えてください。
(2021-12-24 追記)
確証はないけど、証明書更新後にapache reloadをしておらず、新しい証明書がapacheに認識されてないのが原因な気がする。
FreeBSDフォーラムの投稿のように、証明書更新後のフックスクリプトでリロードしてやれば解決しそうな気がする。
- /usr/local/etc/letsencrypt/renewal-hooks/deploy/reload_apache24.sh
#!/bin/sh service `echo $0|sed -e 's/.*\/\(.*\)_\(.*\).sh/\2 \1/'`
パッと見「なんじゃこりゃ?」ってシェルスクだが、自身のファイル名をsedで切り出しservice apache24 reloadを実行するという、実に巧妙な仕組みだ。引用元のフォーラムでは、同様にdovecotやpostfixの証明書更新も行っていた。中身同じでファイル名を変えればいいだけとは、よく思いつくものだ。
参考サイト
FreeBSD 12のApache 2.4.39がunion semun ickふんだららでビルドエラー
FreeBSD 12.0-RELEASEへの更新中、www/apache24のports更新で以下のようなビルドエラーが起きた。
unixd.c:245:25: error: variable has incomplete type 'union semun'
union semun ick;
^
unixd.c:245:19: note: forward declaration of 'union semun'
union semun ick;
^
1 error generated.
*** [unixd.lo] Error code 1
union semunが定義されとらんとな…。
ググってみたら既にバグチケが上がっていた。メンテナ曰く、当該箇所を削除するか全部のトップレベルのportsをリビルドせよとの事だが、後者は面倒でござる。というか、“全てのトップレベル”の範囲がわからんかったので、ソース修正でどうにかする。
/usr/ports/www/apache24/work/httpd-2.4.39/os/unix/unixd.cの240行目付近、#if !APR_HAVE_UNION_SEMUNによってunion semunの定義がなくなっているようなので、#ifと#endifをコメントしてやる。
apr_os_proc_mutex_t ospmutex; //#if !APR_HAVE_UNION_SEMUN ///★コメントアウト! union semun { long val; struct semid_ds *buf; unsigned short *array; }; //#endif ///★コメントアウト! union semun ick; struct semid_ds buf = { { 0 } };
あとは/usr/ports/www/apache24の下でmake installすればビルドは通る。……が、起動しようとするとSegmentation faultで落ちるぅorz。
見た感じdevel/apr1関係のコードのような気がするので、portmaster apr –force-configでaprをリビルド。その後、改めてportmaster apache24 –force-configしたら無事ビルドも通って問題なく起動した。
FreeBSD 10に入れたTomcat 7のタイムゾーン設定方法
何かの拍子に、Tomcat 7.0で動かしているサービスのタイムゾーンがUTCとして認識されるようになってしまった。マシンのRTCは昔からUTCで、OSのロケール≒タイムゾーンも以前からJSTで特に変更はしてないのだが…。
変わっちゃったもんは仕方ないんで、Tomcatのタイムゾーンを変更する方法を調べたところ、setenv.shでCATALINA_OPTS環境変数を弄ればいいらしい。setenv.shってどこにあんのよっていうと、/usr/local/apache-tomacat-7.0/bin/である。もっとも自分の環境(FreeBSD 10.3-RELEASE-p26/Tomcat 7.0.59)ではsetenv.shは無かったんだけど、startup.shを見るにsetenv.shがあれば読み込むように見えたので、新規で作ったら上手く行った。
setenv.shの中味は以下の通り。
export CATALINA_OPTS='-Duser.timezone=Asia/Tokyo'
あとはApacheとTomcatを再起動してやればおk。
lang/php71とwww/mod_php71のZTSオプションは合わせないとハマる
FreeBSDでportsからPHP 7.1とmod_php71をインストールする際、それぞれのZTSのオプション設定を合わせておかないとハマる。というのも、ZTSの有無によってPHPエクステンションの読み込みパスが変わるからだ。
- ZTS無効時:/usr/local/lib/php/20160303/
- ZTS有効時:/usr/local/lib/php/20160303-zts/
エクステンションはlang/php71のZTSオプションに沿った場所にインストールされる。一方、mod_phpは自身のZTSオプション設定に沿った場所からエクステンションを読み込もうとするため、設定を合わせておかないとApache起動時に
Failed loading /usr/local/lib/php/20160303-zts/opcache.so: Cannot open "/usr/local/lib/php/20160303-zts/opcache.so"
てな感じで怒られる事になる。
ApacheがCannot load mod_authn_file.soと言って起動しない
社内wikiを立ち上げようと、FreeBSD 10.2-RELEASEにpkgでApache 2.4を入れてservice spache24 startしたら、以下のようなエラーで起動しなかった。
Performing sanity check on apache24 configuration: httpd: Syntax error on line 66 of /usr/local/etc/apache24/httpd.conf: Cannot load libexec/apache24/mod_authn_file.so into server: Cannot open "/usr/home/www/libexec/apache24/mod_authn_file.so" Starting apache24. httpd: Syntax error on line 66 of /usr/local/etc/apache24/httpd.conf: Cannot load libexec/apache24/mod_authn_file.so into server: Cannot open "/usr/home/www/libexec/apache24/mod_authn_file.so" /usr/local/etc/rc.d/apache24: WARNING: failed to start apache24
mod_authn_file.soってLoadModuleの最初の行じゃないですかー、何でこんな所でコケてるんですかー、やだー!
/usr/local/libexec/apache24/mod_authn_file.soは間違いなくあるし、マジ意味わかんないですケド…。今までずっとports版を使ってきたところに、今回はpkgで導入したからそのせい?なんて思ったりしたが、いくら何でも基本中の基本のモジュール読み込みに失敗するようなバイナリが落ちてくるとは考えられない。
で、まぁ上記のログをよく見てみるとCannot open “/usr/home/www/libexec/apache24/mod_authn_file.so”となってるんですな。うん、これは明らかにオカシイですな。
結局原因はというと、DocumentRootを書き換えたつもりでServerRootを書き換えてたという…。みんなも気をつけようね!
DokuWikiにはSessionとXML Parserが必要
前項の社内WikiというのはDokuWikiな訳だが、無事Apacheが起動したので次はDokuWikiのインストーラを起動したみたところ、start_session(), utf8_encode(), utf8_decode()関数がないと言われて進めなかった。これらもpkgでサクッとインスコ。これらだけならphp56-session, php56-xmlを入れれば事足りるが、php56-extensionsを使って標準っぽいモジュール群を入れておく。
pkg install php56-extensions php56-openssl php56-gd php56-mbstring
DokuWikiの動作にはGDとOpenSSLもあった方がいいのでついでに。mbstringは他のPHPスクリプトで使われてそうだから、これも一緒に。
最終的に導入されたモジュールはこんな感じ。
$ php -m [PHP Modules] Core ctype date dom ereg filter gd hash iconv json libxml mbstring mhash mysqlnd openssl pcre PDO pdo_sqlite Phar posix Reflection session SimpleXML SPL sqlite3 standard tokenizer xml xmlreader xmlwriter Zend OPcache zlib [Zend Modules] Zend OPcache
これでようやくDokuWikiが使えるようになった。