「サーバーの設定ファイルが書き換えられていないか、いつ確認できるの?」「毎時間cronでAIDEを回しているけど、リアルタイムで気づく方法はないのか?」
こういう悩みを持つインフラエンジニアは多いはずです。AIDE(ファイル整合性監視)は強力なツールですが、スキャンは定期実行のため、攻撃者がファイルを改ざんしてから数十分、最悪1時間以上気づけないことがあります。
この記事では、Linuxカーネルが標準で持つ inotify(アイノティファイ)というファイル監視APIを使い、ファイルの変更を書いた瞬間に検知する仕組みを現場で使えるレベルで解説します。設定ファイルの改ざん検知・Webディレクトリへの不審な書き込みアラートなど、情シス1人体制でも今日から導入できる実装方法まで網羅します。

inotifywaitとは?リアルタイムファイル監視の要
inotifyはLinuxカーネル2.6.13から標準搭載されたファイル変更通知機構です。カーネルがファイルシステムのイベント(書き込み・作成・削除・属性変更など)をユーザー空間のプログラムにリアルタイムで通知します。
inotify-toolsパッケージに含まれる inotifywait と inotifywatch は、このinotify APIをシェルスクリプトから手軽に扱えるようにしたコマンドラインツールです。
・inotifywait: 指定したファイル・ディレクトリにイベントが発生するまで待機し、イベントを標準出力に出力する
・inotifywatch: 指定時間内のイベント発生回数を集計して出力する(統計・負荷分析向け)
なぜ今この仕組みが重要なのか
インシデント対応の現場では、攻撃者がWebシェルを設置するのに要する時間は数秒です。定期スキャン方式では「改ざんから検知まで」のギャップが必ず存在します。inotifywaitを使えば、そのギャップを数秒レベルまで縮めることができます。
inotify APIの仕組み(カーネルが監視を担う理由)
従来のポーリング方式(一定間隔でファイルの更新時刻を比較する方法)と異なり、inotifyはカーネルがファイルシステムのI/Oを直接フックしてイベントを生成します。
・ポーリング方式のデメリット: CPU使用率が高くなりやすい・検知に遅延が生じる・スキャン対象が多いと負荷が増大する
・inotifyのメリット: イベント駆動のためCPUコストが低い・変化が発生した瞬間に通知・カーネルレベルの処理で信頼性が高い
inotifyが検知できる主要イベント
| イベント名 | 発生タイミング | セキュリティ上の意義 |
|---|---|---|
| IN_MODIFY | ファイルの内容が変更された | 設定ファイル・スクリプトの改ざん検知 |
| IN_CREATE | ファイル・ディレクトリが作成された | Webシェル設置・マルウェアドロップの検知 |
| IN_DELETE | ファイル・ディレクトリが削除された | ログ削除・証跡消去の検知 |
| IN_ATTRIB | パーミッション・所有者などの属性変更 | SUIDビット付与など権限昇格の前兆を検知 |
| IN_MOVED_FROM / IN_MOVED_TO | ファイルの移動・リネーム | バイナリ置き換え攻撃の検知 |
| IN_CLOSE_WRITE | 書き込み後にファイルがクローズされた | IN_MODIFYより確実に「書き込み完了」を検知 |
inotify-toolsのインストールと基本操作
1. インストール
inotify-toolsは多くのディストリビューションの標準リポジトリに収録されています。
# RHEL / Rocky Linux / AlmaLinux / CentOS Stream sudo dnf install inotify-tools # Ubuntu / Debian sudo apt install inotify-tools # インストール確認 inotifywait --version inotifywatch --version
2. 基本的な使い方
# /etc/passwdへのイベントを1回だけ待機(テスト用) inotifywait /etc/passwd # 別のターミナルで touch /etc/passwd を実行すると # OUTPUT: /etc/passwd ATTRIB # -eオプションで監視イベントを絞り込む # IN_CLOSE_WRITEのみ検知(書き込み完了後) inotifywait -e close_write /etc/passwd # -rオプションでサブディレクトリも再帰的に監視 # -mオプションで継続的に監視(1回で終了しない) inotifywait -r -m /var/www/html
3. 主要オプション一覧
・-m / –monitor: 継続監視モード(1イベント検知後も終了しない)
・-r / –recursive: サブディレクトリを含めて再帰的に監視
・-e / –event: 監視するイベントを指定(複数指定可)
・–format: 出力フォーマットを指定(例: --format '%w%f %e %T')
・–timefmt: タイムスタンプのフォーマット(例: --timefmt '%Y-%m-%d %H:%M:%S')
・–exclude / –excludei: 除外パターンの指定(正規表現・大文字小文字無視)
・-q / –quiet: inotifywait起動時のメッセージを抑制(スクリプト組み込み時に有用)
改ざん検知スクリプトの実践実装
1. 単一ディレクトリ監視スクリプト
Webサーバーのドキュメントルート(/var/www/html)を監視し、PHPファイルの作成・変更を検知する基本スクリプトです。
#!/bin/bash # /usr/local/bin/watch-webroot.sh # Webルートへのファイル変更をリアルタイム検知して syslog に記録する TARGET_DIR="/var/www/html" LOG_TAG="webroot-monitor" inotifywait \ -m -r \ -e create,close_write,modify,moved_to,delete,attrib \ --format '%T %w%f %e' \ --timefmt '%Y-%m-%d %H:%M:%S' \ --exclude '\.(jpg|jpeg|png|gif|ico|css|js|map)$' \ "$TARGET_DIR" \ | while read -r DATETIME FILEPATH EVENT; do logger -t "$LOG_TAG" "EVENT=$EVENT FILE=$FILEPATH TIME=$DATETIME" echo "[$DATETIME] $EVENT: $FILEPATH" done
ポイントは --exclude で画像・CSS・JSなど頻繁に更新される静的ファイルを除外することです。これにより、PHPやHTMLなど実行ファイルの変更だけを絞り込めます。
2. アラートメール通知の設定
変更検知時にメールで即時通知するスクリプトに拡張します。
#!/bin/bash # /usr/local/bin/watch-webroot-alert.sh # 変更検知時にメールアラートを送信する TARGET_DIR="/var/www/html" ALERT_MAIL="security@example.com" HOSTNAME_STR=$(hostname -f) LOG_TAG="webroot-monitor" inotifywait \ -m -r \ -e create,close_write,moved_to,delete,attrib \ --format '%T %w%f %e' \ --timefmt '%Y-%m-%d %H:%M:%S' \ --exclude '\.(jpg|jpeg|png|gif|ico|css|js|map)$' \ "$TARGET_DIR" \ | while read -r DATETIME FILEPATH EVENT; do logger -t "$LOG_TAG" "EVENT=$EVENT FILE=$FILEPATH TIME=$DATETIME" # PHPファイルの新規作成は特に危険なため即時アラート if [[ "$EVENT" == *"CREATE"* ]] && [[ "$FILEPATH" == *.php ]]; then echo "【緊急】WebシェルかもしれないPHPファイルが設置されました。 サーバー: $HOSTNAME_STR ファイル: $FILEPATH イベント: $EVENT 検知時刻: $DATETIME 速やかに内容を確認してください。" \ | mail -s "[ALERT] PHP file created: $FILEPATH" "$ALERT_MAIL" fi done
3. systemdサービスとして常駐化
スクリプトをサービスとして登録し、サーバー再起動後も自動起動させます。
# /etc/systemd/system/webroot-monitor.service [Unit] Description=Webroot File Change Monitor After=network.target [Service] Type=simple ExecStart=/usr/local/bin/watch-webroot-alert.sh Restart=on-failure RestartSec=5 # 専用ユーザーで実行(rootは避ける) User=nobody Group=nobody [Install] WantedBy=multi-user.target
# スクリプトに実行権限を付与 sudo chmod +x /usr/local/bin/watch-webroot-alert.sh # サービスを有効化・起動 sudo systemctl daemon-reload sudo systemctl enable webroot-monitor sudo systemctl start webroot-monitor # 動作確認 sudo systemctl status webroot-monitor
inotifyのシステム上限と調整
大量のディレクトリを再帰監視する場合、カーネルのinotifyウォッチ上限に引っかかることがあります。
# 現在の上限確認(デフォルトは8192) cat /proc/sys/fs/inotify/max_user_watches # 一時的に増やす(再起動で元に戻る) sudo sysctl fs.inotify.max_user_watches=524288 # 永続化する場合(/etc/sysctl.d/に設定ファイルを置く) echo "fs.inotify.max_user_watches=524288" | sudo tee /etc/sysctl.d/99-inotify.conf sudo sysctl --system
/var/www/html配下のファイル数が数万を超えるような場合は524288(約50万)程度に設定するのが一般的です。
中小企業でも今日からできること
inotifywaitは設定が複雑に見えますが、最小構成から段階的に導入できます。
・ステップ1(即日): inotifywait -m -r /etc /usr/local/bin 2>&1 | logger -t inotify & をrc.localに追加するだけで設定ファイルへの変更をsyslogに記録できる
・ステップ2(1日~): 本記事のスクリプトをサービス化し、Webディレクトリの監視を常駐化する
・ステップ3(1週間~): アラートメールの受信先をチームのSlackやメーリングリストに接続し、インシデント対応フローと連携させる
・ステップ4(継続): 誤検知(除外すべきファイルの多さ)を確認しながら --exclude パターンを最適化する
なお、Linuxのログ監視全体についてはLinuxログ監視入門(syslog・journald・auditd)もあわせてご参照ください。inotifywaitと組み合わせることで、ファイル変更の検知から証跡保管までの仕組みが整います。
よくある誤解と注意点
【誤解1】inotifywaitがあればAIDEは不要
inotifywaitはプロセスが動いている間しか監視できません。サーバー再起動前後や、監視スクリプトが強制終了された隙間に行われた変更は検知できないため、AIDE(定期スキャン)との二段構えが推奨です。inotifywaitはリアルタイム性、AIDEは確実な差分記録という役割分担で運用してください。
【誤解2】auditdで代替できる
auditdはシステムコール単位の監査ログを記録する強力なツールですが、設定が複雑でリアルタイムなスクリプト処理との連携はやや難易度が高くなります。inotifywaitはシェルスクリプトとシームレスに統合でき、軽量な用途に向いています。
【注意】ネットワークファイルシステムには注意
inotifyはローカルファイルシステム(ext4、xfsなど)上の変更を検知しますが、NFSなどのネットワークファイルシステムではリモート側の変更は通知されないことがあります。NFS共有ディレクトリを監視する場合は制限を理解した上で設計してください。
【注意】重要ファイルを変更不能にする別の手段も検討
設定ファイルへの改ざんを「検知する」だけでなく「そもそも変更させない」という観点も重要です。chattr(不変フラグ)を使うと、root権限でも変更できないファイルを設定でき、inotifywaitと組み合わせることでより堅牢な多層防御になります。
AIDEとinotifywaitの使い分けまとめ
| 特性 | inotifywait | AIDE |
|---|---|---|
| 検知方式 | イベント駆動(リアルタイム) | 定期スキャン(差分比較) |
| 検知速度 | 秒単位 | スキャン間隔依存(分~時間単位) |
| CPU負荷 | 低(イベント待機中はほぼゼロ) | スキャン時に一時的な負荷あり |
| 導入難易度 | 低(シェルスクリプト1本で動く) | 中(初期データベース構築が必要) |
| 監視の確実性 | プロセスが動いている間のみ | 過去の変更も遡って検知可能 |
| チェックサム記録 | なし(ファイルパスとイベントのみ) | あり(SHA256等でハッシュ記録) |
| 推奨用途 | Webディレクトリ監視・即時アラート | 重要バイナリ・設定ファイルの整合性管理 |

本記事のまとめ
・inotifywaitはLinuxカーネル標準のinotify APIを使い、ファイル変更をイベント駆動でリアルタイムに検知できるツール
・インストールはdnf install inotify-toolsまたはapt install inotify-toolsの1コマンドで完了
・-m -r -e close_write,create,deleteの組み合わせでWebディレクトリの常駐監視が実現できる
・PHPファイルの新規作成などの危険イベントはmailコマンドとの組み合わせで即時アラートを送信できる
・systemdサービスとして登録すれば再起動後も自動起動し、Restart=on-failureでプロセス異常終了からも自動復旧する
・fs.inotify.max_user_watchesのカーネルパラメータを調整することで大規模ディレクトリにも対応可能
・AIDEの定期スキャンと組み合わせて「リアルタイム検知+確実な差分記録」の二段構えが理想的な運用
inotifywaitは「攻撃者が設置したWebシェルを、次の定期スキャンまで気づかない」というタイムラグをなくす、実践的なツールです。設定ファイルの書き換えやWebシェルの設置を秒単位で検知できる環境を、今日から整えていきましょう。
PR
inotify・auditd・SELinuxなどLinuxサーバーのセキュリティ強化を網羅した実践書。本記事で触れたファイル監視の仕組みをさらに深く学びたい方に最適な一冊です。
