はじめに
株式会社ピーアールオー(あったらいいな!を作ります) Advent Calendar 2023 の11日目です。
先日、anacronで実行されるmysqlのlogrotateにて、
新しく作られたファイルに出力が行われない事象が発生しました。
cronでの実行や手動の場合は問題なかったですが、anacronでlogrotate実行後のmysql関連のlogが出力されなくなったのでそれについて書いていきます。
原因だけ先に書いておくとSELINUXを適用しているためでした。
mysqlがlogrotateされない場合
設定は以下のようなよくある設定とします。
/var/log/mysqld.log {
create 640 mysql mysql
notifempty
daily
rotate 5
missingok
compress
postrotate
# just if mysqld is really running
if test -x /usr/bin/mysqladmin && \
/usr/bin/mysqladmin ping &>/dev/null
then
/usr/bin/mysqladmin flush-logs
fi
endscript
}
mysqlのlogrotateが上手くいかない多くの原因は権限のエラーだと思います。
その場合は以下の記載に修正すると上手くいくかと思います。
/usr/bin/mysqladmin --defaults-extra-file=/root/.my.cnf flush-logs
logrotateされるがlogに出力されない
logrotateは上手くいっているのにファイルの書き込みが上手くいっていない。
この場合はファイルディスクリプタについて疑うかと思います。
現にmysqlの再起動など行う場合はmysqlのlogの出力は正常な状態となりました。
また、手動でlogrotate内で実行するコマンドを試した場合でもファイルへの出力は問題ありません。
anacronでlogrotate実行後のmysql関連のlogが出力されなくなった
つまりflush-logsの実行が出来ておらず書き込みファイルが切り替わっていない状態でした。
SELINUXがEnforcingだった場合は原因としてSELINUXが考えられますので、一時的にPermissiveにしてみるなどの対応を行ってください。
$ getenforce
$ setenforce 0
また、audit.logを確認してSELINUXのlogを確認してください。
selinuxが原因の場合、以下のようなlogが出ている可能性があります。
avc: denied { name_connect } for pid=xxxxxxxxxx comm="mysqladmin" dest=3306 scontext=system_u:system_r:logrotate_t:s0-s0:c0.c1023 tcontext=system_u:object_r:mysqld_port_t:s0 tclass=tcp_socket permissive=0
操作元 : scontext=system_u:system_r:logrotate_t:s0-s0:c0.c1023
操作先 : tcontext=system_u:object_r:mysqld_port_t:s0
上記の場合はlogrotate_tがmysqld_port_tに対して、{ name_connect }を拒否している状態です。
また、以下のコマンドで何が許可されているかなど確認することもできます。
$ sesearch -A -s logrotate_t -t mysqld_port_t
今回の事象ではこのルールに許可がなかったことが原因となります。
cron実行の際に上手くいっていたのはこの権限周りがanacronの時と違ったんでしょうね。
そのため上記で拒否されたルールを許可してあげる必要があります。
※不要な許可は足さないように十分検討してください。
原因は判明したので対応について記載します。
以下のように対応すれば、anacron+SELINUXの環境で上手く動くようになるかと思います。
※audit2allow -a
は拒否されたアクセスが全て表示されてしまうので許可する必要のないものは含まれていないことを確認しましょう。不要なものがある場合は手動でもカスタムモジュールは作成出来ます。
# 拒否されたアクセスを許可する Type Enforcement ルールを表示
$ audit2allow -a
# カスタムモジュール作成
$ audit2allow -a -M モジュール名
# コンパイルされたファイルが作成されるのでSELINUXに適用
$ semodule -i モジュール名.pp
# 今回のような拒否内容の場合は以下にモジュールが追加されていることを確認できます。
$ sesearch -A -s logrotate_t -t mysqld_port_t
終わりに
logrotateが何かしら上手くいってない場合は、基本的には設定ファイルやmysqlの権限に問題がある可能性が高いかと思います。
そのため調べてもSELINUXが原因という可能性はなかなかたどり着けないこともあるかと思いますのでこの記事を作成しました。
anacronでmysqlをlogrotateする際にSELINUXをEnforcingにしている状態、とピンポイントなところですが、SELINUXの許可の追加方法は他でも応用が効きますのでお試し下さい。
たまに見かけるSELINUXをPermissiveにして解決!みたいなことは好みません。。
以上