CentOS Stream 9でのAIDE導入と設定:ファイル整合性監視による改ざん検知

CentOS tutorial - IT technology blog
CentOS tutorial - IT technology blog

Linuxにおけるファイル整合性監視:RHEL/CentOS環境に適したツール選定

PCI-DSS(要件11.5)やISO 27001の監査対応において、ファイル整合性監視(FIM: File Integrity Monitoring)の導入は必須項目となります。攻撃者がRCE(リモートコード実行)脆弱性の攻略に成功した場合、次に狙われるのはほぼ間違いなくシステムファイルです。彼らは通常、/usr/bin/loginバイナリを改ざんしたり、/etc/crontabに悪意のあるコードを仕込んだり、/etc/ssh/sshd_configにバックドアを開けたりします。

手遅れになる前にこうした変更を検知するため、システム管理者は主に以下の3つのアプローチを検討します。

  • 自作Bashスクリプト + sha256sum:定期的にハッシュを生成し、diffで比較する手法。手軽ですが機能面では不十分です。
  • 統合型SIEM/FIMクラスター(Wazuh、OSSEC)の導入:リアルタイム監視には非常に優れています。ただし構成が大規模で、管理サーバー用だけでも最低2〜4 GBのRAMを消費します。
  • AIDE(Advanced Intrusion Detection Environment)の採用:軽量かつ堅牢で、RHEL/CentOSのAppStreamリポジトリから標準で利用可能です。

実環境における3つのアプローチの比較

実運用の経験に基づく比較一覧:

評価基準 自作スクリプト(Bash + Hash) 統合型エージェント(Wazuh/OSSEC) AIDE
導入の複雑さ 初期作成は容易、拡張時は管理が破綻しやすい 複雑(マネージャー、DB、ダッシュボードの構築が必要) dnfコマンド1行で即座に完了
CPU/RAMリソース ファイル数が少なければ低負荷、詳細スキャン時はハングの恐れあり バックグラウンドでデーモンが常駐し、RAMを常時消費 常駐時のRAM消費ゼロ。スキャン実行時のみCPUとI/Oを使用
検査スコープ 基本的にファイル内容のハッシュのみ リアルタイムイベント、ログ相関分析、監査ルール ハッシュ(SHA256/SHA512)、パーミッション、inode、SELinux、mtimeを網羅
適用シーン 一時的な応急処置 50〜100台以上の大規模インフラ 単体サーバー、ゲートウェイ、VPS、またはAnsibleによる集中管理

自作スクリプトでは、重要な指標の多くを見落としがちです。ファイル権限の変更、不正なシンボリックリンク、SELinuxコンテキストの改ざんなどは検知できません。一方で、2〜3台のWeb/DB用VPSを監視するためだけにWazuhクラスター全体を立ち上げるのは過剰投資と言えます。

CentOS Stream 9でAIDEを選ぶべきケース

CentOS Stream 9で運用するパブリックゲートウェイやスタンドアロンのデータベースサーバーにおいて、筆者はその実用性の高さからAIDEを推奨します。常駐プロセスによるメモリ逼迫の心配がなく、所有権(UID/GID)、タイムスタンプ、ファイルサイズから暗号化ハッシュに至るまで、すべてのパラメータを徹底的に検証できます。

さらに、専用の管理サーバーを維持する追加コストをかけることなく、セキュリティ監査の要件を確実に満たすことが可能です。

CentOS Stream 9におけるAIDE導入手順

ステップ1:AppStreamからのAIDEインストール

インストールパッケージはシステムのデフォルトリポジトリに用意されています。以下のコマンドを実行するだけで完了します。

sudo dnf install -y aide aide-selinux

aide-selinuxパッケージを省略しないでください。これが不足していると、EnforcingモードのSELinuxによってAIDEがシステム内の機密ファイルにアクセスできなくなります。

ステップ2:設定ファイルによるルール調整

ツールのメイン設定ファイルを開きます。

sudo nano /etc/aide.conf

デフォルトでは、検査対象となる属性マクロがあらかじめ定義されています。

# 標準マクロ: SHA256ハッシュ、パーミッション、inode、ユーザー、グループ、SELinux、ACLを検証
CONTENT_EX = sha256+ftype+p+u+g+n+acl+selinux+xattrs
DATAONLY   = p+u+g+sha256

実運用のアドバイス:最も起こりがちな失敗は、/var/logディレクトリ全体をコンテンツ監視の対象に含めてしまうことです。その結果、ログが更新されるたびに不要なアラートが大量発生してしまいます。頻繁に変更されるパスは、!プレフィックスを使って除外設定を行いましょう。

# 1. 厳格に監視すべき中核ディレクトリ
/etc          CONTENT_EX
/usr/bin      CONTENT_EX
/usr/sbin     CONTENT_EX
/boot         CONTENT_EX

# 2. ログ、一時ファイル、コンテナデータの除外
!/var/log/.*
!/var/tmp/.*
!/tmp/.*
!/var/lib/docker/.*
!/var/lib/containers/.*

ステップ3:ベースラインデータベースの初期化

AIDEは、ファイルシステムの現在の状態をスナップショットとしてデータベースファイルに記録することで動作します。初期スナップショットを生成します。

sudo aide --init

約50,000の標準ファイルが存在するNVMe SSD環境では、処理時間は20〜40秒程度です。完了すると、/var/lib/aide/aide.db.new.gzファイル(サイズは約3〜8 MB)が生成されます。

このデータベースを正式な比較基準として有効化します。

sudo mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz

セキュリティ強化策:root権限を奪取した攻撃者は、痕跡を消すためにこのデータベースを上書きしようとする可能性があります。改ざんを防止するため、データベースファイルに変更不可属性(immutable)を設定しておきましょう。

sudo chattr +i /var/lib/aide/aide.db.gz

ステップ4:変更検知のテスト

システムの名前解決ファイルを意図的に改ざんしてみます。

echo "192.168.1.50 rogue-c2.internal" | sudo tee -a /etc/hosts

整合性チェックのスキャンを実行します。

sudo aide --check

AIDEは即座に差分を検知し、詳細なレポートを出力します。

AIDE 0.16 found differences between database and filesystem!!
Start timestamp: 2026-10-25 10:30:00

Summary:
  Total number of entries:      54210
  Added entries:                0
  Removed entries:              0
  Changed entries:              1

---------------------------------------------------
Changed entries:
---------------------------------------------------
changed: /etc/hosts

---------------------------------------------------
Detailed information about changes:
---------------------------------------------------
File: /etc/hosts
  Size     : 158                              , 192
  Mtime    : 2026-10-25 09:12:00              , 2026-10-25 10:29:45
  SHA256   : e3b0c44298fc1c149afbf4c8996fb924 , b94d27b9934d3e08a52e52d7da7dabfa

ステップ5:OSアップデート後のベースライン更新

dnf upgradeを実行するたびに、多数のバイナリやライブラリのチェックサムが変化します。その直後にチェックを実行すると、誤検知のアラートで埋もれてしまいます。OS更新後はベースラインを再構築してください。

# ステップ3で設定したimmutable属性を一時解除
sudo chattr -i /var/lib/aide/aide.db.gz

# データベースの更新と置き換え
sudo aide --update
sudo mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz

# 再度ファイルをロック
sudo chattr +i /var/lib/aide/aide.db.gz

ステップ6:cronによる自動化とTelegramへのアラート通知

毎日手動でコマンドを実行するのは現実的ではありません。結果を自動処理するスクリプトを/usr/local/bin/aide-monitor.shに作成します。

#!/usr/bin/env bash

BOT_TOKEN="123456789:ABCdefGHIjklMNOpqrSTUvwxYZ"
CHAT_ID="-987654321"

# サーバーの負荷スパイクを防ぐため、最低のI/O優先度でスキャンを実行
OUTPUT=$(ionice -c 3 /usr/sbin/aide --check 2>&1)
EXIT_CODE=$?

# AIDEの終了コード: 0 = 変更なし、0以外 = 変更検知またはエラー発生
if [ $EXIT_CODE -ne 0 ]; then
    REPORT_SNIP=$(echo "$OUTPUT" | head -n 25)
    TEXT="⚠️ <b>FIMアラート発生: $(hostname)</b>%0A%0A<code>${REPORT_SNIP}"
    curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
        -d "chat_id=${CHAT_ID}" \
        -d "parse_mode=HTML" \
        -d "text=${TEXT}" > /dev/null
fi

スクリプトのパーミッションを厳格に設定します。

sudo chmod 700 /usr/local/bin/aide-monitor.sh
sudo chown root:root /usr/local/bin/aide-monitor.sh

rootのcrontabに毎日午前3:00の定期実行スケジュールを登録します。

echo "0 3 * * * /usr/local/bin/aide-monitor.sh" | sudo tee -a /var/spool/cron/root

AIDE運用における極めて重要な3つの注意点

  1. ディスクI/Oリソースの制御:50,000以上のファイルを一斉にスキャンすると、特にMySQL/PostgreSQLなどのデータベースサーバーでディスクI/Oが逼迫する原因になります。AIDEがアイドル時のI/Oのみを利用するよう、スキャンコマンドには必ずionice -c 3を適用してください。
  2. データベースのバックアップをサーバー外に退避:万が一root権限を完全に奪われた場合、攻撃者によってchattr +iが解除される恐れがあります。aide.db.gzファイルを独立したストレージサーバー(読み取り専用のNFSマウントやObject Lockを有効にしたS3バケットなど)に定期同期してください。
  3. AIDEバイナリ自体の厳重管理:監視ツール自体の完全性をいつでも検証できるよう、/usr/sbin/aideのSHA256ハッシュ値を外部ドキュメント等に控えておくことを強く推奨します。
Share: