【RHEL 9】ユーザーの操作ログを別ファイルに分離して自動ローテーションする最適設定(rsyslog + logrotate)

EC2アイキャッチ画像

Linux(RHEL 9)の運用保守において、「誰が・いつ・どのディレクトリで・何のコマンドを実行したか」という操作ログ(コマンド履歴)の取得は、セキュリティ監査やトラブルシューティングの観点から非常に重要です。

しかし、標準設定のまま操作ログを /var/log/messages に流してしまうと、他のシステムログと混ざって視認性が落ちるだけでなく、ログ容量の肥大化や管理(ローテーション)の手間が発生します。

本記事では、RHEL 9で操作ログを専用の独立したログファイルに出力し、さらに自動で30日間ローテーション(圧縮保存)させるスマートな設定手順を解説します。

全体像:今回構築する仕組み

  1. シェルの設定 (/etc/profile.d/): ユーザーがコマンドを実行するたび、日時・PID・カレントディレクトリ付きで情報を syslog (local6) へ送信。
  2. rsyslogの設定 (/etc/rsyslog.d/)local6 のログを /var/log/user_history.log に隔離し、messages には混ぜない。
  3. logrotateの設定 (/etc/logrotate.d/): 毎日自動でログを区切り、過去30日分をGzip圧縮して世代管理。古いものは自動削除。

ステップ1:シェルの設定(送信先ファシリティの変更)

すべてのユーザーが実行したコマンドをリアルタイムに検知し、システムログへ送るための共通設定を行います。

まず、設定ファイルを新規作成します。

sudo vi /etc/profile.d/operation_log.sh
export HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S "

function log_to_syslog {
    declare command
    command=$(fc -ln -1)
    if [ -n "$command" ]; then
        # 「local6.notice」としてシステムに送る
        logger -p local6.notice -t "USER_OP_${USER}[$PPID]" "PWD=${PWD}: $command"
    fi
}
trap log_to_syslog DEBUG

ステップ2:rsyslogの設定(messagesから除外し、専用ファイルへ)

次に、RHEL 9のログ振り分けルールを設定します。 既存の rsyslog.conf を直接編集するとアップデート時に競合する可能性があるため、/etc/rsyslog.d/ ディレクトリ配下に独立した設定ファイルを作成するのがベストプラクティスです。

sudo vi /etc/rsyslog.d/user_history.conf

以下の2行を記述して保存します。

# local6のログ(操作ログ)を専用ファイルに保存
local6.* /var/log/user_history.log

# messagesなど、他のログに混ざらないようにここで処理を終了させる
& stop

設定の反映

設定を反映させるため、rsyslogサービスを再起動し、先ほど作成したシェルの設定を現在のセッションに読み込ませます。

sudo systemctl restart rsyslog
source /etc/profile.d/operation_log.sh

ステップ3:動作確認

正しくログが専用ファイルに書き込まれているかテストします。

適当なディレクトリ移動やコマンドを実行してみます。

cd /tmp
pwd
ls -la

別のターミナル、または同じ画面から管理者権限でログファイルの末尾を確認(または監視)します。

sudo tail -f /var/log/user_history.log

上記のように、実行ユーザー名、親プロセスID、実行時のカレントディレクトリ、コマンドの中身が1行で綺麗に記録されていれば成功です。

ステップ4:ログローテーションの設定

このまま運用するとログファイルが無限に肥大化し、ディスクを圧迫してしまいます。Linux標準の logrotate を使って、「毎日自動分割」「30日分キープ」「古いものは圧縮して自動削除」という運用フリーな設定を追加します。

sudo vi /etc/logrotate.d/user_history

以下の内容を記述します

/var/log/user_history.log {
    daily
    # 30日分(30世代)だけ保管して、古いのは自動削除
    rotate 30
    # 古いログは自動でGzip圧縮して容量を節約
    compress
    # 1世代前(昨日の分)は圧縮せず、一昨日以前の分を圧縮
    delaycompress
    missingok
    notifempty
    sharedscripts
    postrotate
        /usr/bin/systemctl kill -s HUP rsyslog.service >/dev/null 2>&1 || true
    endscript
}

⚠️ 注意(ハマりポイント) logrotateの設定ファイルでは、rotate 30 などの設定値と同じ行(後ろ)に # コメントを記述すると構文エラー(bad rotation count)になります。上記のようにコメントは必ず独立した行に記述してください。

ローテーション設定のデバッグ(テスト)

設定ファイルが正しく書けているか、ドライラン(シミュレーション)コマンドで確認します。

sudo logrotate -d /etc/logrotate.d/user_history

画面に error: という文字列が出ず、後半に considering log /var/log/user_history.log や log does not need rotating といった検証ログが流れていれば設定は完璧です(サーバーを再起動してもこの設定は維持されます)。

まとめ

RHEL 9において、rsyslog と logrotate を適切に組み合わせることで、システムに負荷をかけず、管理の手間もかからない強固な操作ログ保存環境が使い始められます。

「いつ・誰が何をしたか」の証跡をクリアにしておくことは、トラブル時の迅速な原因究明や、内部不正の抑止力にもつながります。インフラ構築時の標準構成として、ぜひ取り入れてみてください。