つい先日新しいWebサーバーを設定したのですが、logrotate で /var/log/ 配下のログは問題なくローテーションされるのに /usr/local/apache2/logs/ 配下のログのみローテーションされないという現象がありました。そこで今回は、/usr/ 配下のログがローテーションできない場合の原因と対処方法をまとめてみました。
原因
原因は、Linuxシステムや各種サービスを管理している systemd にあります。
具体的には logrotate サービスの設定値 ProtectSystem が「full」になっていることが /usr/ 配下のログがローテーションできない原因です。
$ systemctl show logrotate.service -p ProtectSystem ProtectSystem=full
どういうことかと言うと、ProtectSystem の値が「full」に設定されている場合は、/usr/ と /etc/ およびブートローダーディレクトリ配下が logrotateサービスに対して読取り専用でマウントされるため、ログローテーション時に新たにファイルを作成することができず結果としてログローテーションに失敗します。少し厄介な設定でありますが、これはセキュリティ確保のためで、長時間実行されるすべてのサービスに対してこの設定を有効にすることが推奨されています。
参考資料:ProtectSystem | systemd.exec
RHEL系のサーバーOSでは、バージョン8までは ProtectSystem はデフォルトで「no」が設定されていたため、意図して設定を変更しない限りこのような問題は発生しなかったのですが、バージョン9からはデフォルトで「full」に設定されているため、サーバーOSに RHEL9、AlmaLinux9、RockyLinux9などを利用している場合は注意が必要です。
対処方法
ログの出力先を変更する
そのままですがLinuxの作法(FHS)に従って素直に /var/log/ 配下にログを出力するようにサービスの設定を変更しましょう。
設定には手をつけずにシンボリックリンクを使ってログの出力先を変更することもできます。例えばログの出力先を /usr/local/apache2/logs/ から /var/log/httpd/ に変更するには次のようにシンボリックリンクを作成します。
sudo systemctl stop httpd sudo mv -i /usr/local/apache2/logs /var/log/httpd sudo ln -s /var/log/httpd /usr/local/apache2/logs sudo systemctl start httpd
書込みを許可する
セキュリティの観点からはオススメできませんが、やむを得ない事情がある場合は ReadWritePaths の設定で特定のディレクトリへの書込みを許可する方法もあります。
$ sudo systemctl edit logrotate.service ### Editing /etc/systemd/system/logrotate.service.d/override.conf ### Anything between here and the comment below will become the new contents of the file (以下の2行を追記します) [Service] ReadWritePaths=/usr/local/apache2/logs ### Lines below this comment will be discarded (略)
設定が反映されていることを確認します。
$ systemctl show logrotate.service -p ReadWritePaths ReadWritePaths=/usr/local/apache2/logs
logrotate を再起動します。
sudo systemctl restart logrotate.service
おわりに
logrotate -f /etc/logrotate.d/httpd とかでローテーションを実行すると /usr/ 配下であってもローテーションできるので、原因が分かるまでかなりの時間がかかりました、、、systemd は知れば知るほど奥が深く、ハマりポイントでもありますのでしっかり理解しておきたいものですね。
コメント