AuditdによるLinuxセキュリティ監査の実践:ルール設定、ファイル監視、ログ分析

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

実際の課題:本番環境ファイル改ざんの謎

本番Webサーバーが突然不安定な挙動を示し始めました。/root/.ssh/authorized_keysに見覚えのない公開鍵が追加されていたり、データベースの認証情報が含まれる本番用.envファイルを不明なプロセスが読み取っていたりします。しかし、/var/log/syslogや.bash_historyを確認しても有用な情報は残っていません。攻撃者はunset HISTFILEでシェルの履歴を消去しており、syslogには定期的なcronジョブやサービスの再起動ログしか記録されていないためです。

標準的なLinuxのシステムログは、サービスが再起動したことやセッションが開かれた時刻などの「結果」を記録するにすぎません。そのため、フォレンジック調査で極めて重要となる以下のような問いには答えられません。

  • 誰が(Who)そのコマンドを実行したのか? syslogでは、実際のログインアカウントと昇格したsudoセッションを正確に区別できません。
  • 何が(What)、どのファイルパスやシステムコールが正確に操作されたのか?
  • どの(Which)プロセスIDや実行ファイルが変更を開始したのか?
  • いつ(When)不正なプロセスが機密ファイルを(内容を変更せずに)読み取ったのか?

カーネルレベルのテレメトリがなければ、セキュリティインシデントの調査は難航します。権限昇格や内部不正の兆候を見逃すことになってしまいます。

根本原因の分析:なぜ標準ログ機能だけでは不十分なのか

アプリケーションレベルのログ記録は、ソフトウェアがrsyslogや<a href="https://itnotes.dev/ja/systemd-journal-remote%e3%81%ab%e3%82%88%e3%82%8b%e3%83%ad%e3%82%b0%e3%81%ae%e4%b8%80%e5%85%83%e7%ae%a1%e7%90%86%ef%bc%9a%e8%bb%bd%e9%87%8f%e3%81%aaelk%e4%bb%a3%e6%9b%bf%e6%a1%88/">systemd-journald</a>などのデーモンへ自発的にメッセージを送信することに依存しています。侵入者がvimで<a href="https://itnotes.dev/ja/etc%e3%81%ae%e3%83%90%e3%83%bc%e3%82%b8%e3%83%a7%e3%83%b3%e7%ae%a1%e7%90%86%ef%bc%9aetckeeper%e3%81%a7linux%e3%82%b5%e3%83%bc%e3%83%90%e3%83%bc%e3%82%92%e8%a8%ad%e5%ae%9a%e3%83%88%e3%83%a9%e3%83%96/">/etc/passwd</a>を編集したり、/dev/shmに配置したバイナリを実行したりしても、ユーザーランドのロガーは沈黙したままです。直接的なファイル操作がsyslogに通知されることはありません。

攻撃者は痕跡を隠すためにtouch -rでファイルのタイムスタンプを偽装したり、環境変数をクリアしたりするのが常套手段です。確実な監視を行うには、ユーザーランドよりも下層のLinuxカーネル内部で動作させる必要があります。あらゆるファイルの読み取り、プロセスの実行、ネットワークのバインドは、openat()、execve()、unlinkat()などのシステムコールを経由します。Linux監査フレームワーク(auditd)はこれらのシステムコールに直接フックし、ユーザースペースから改ざんされる前に変更不可なイベントレコードを記録します。

ソリューションの比較:適切な監査メカニズムの選択

Linux管理者がシステムアクティビティを追跡する際、主に次の3つのアプローチが検討されます。

1. プロセスアカウンティング(psacct / acct)

  • メリット: 設定が極めてシンプルで、メモリ使用量が非常に軽量(10MB未満)。基本的なコマンドの終了を追跡可能。
  • デメリット: rootユーザーであれば容易に無効化できる。実行されたコマンド名は記録されるが、ファイルパス、ファイルの読み取り、ネットワークコール、変更されたファイル属性などは無視される。

2. eBPFセキュリティエンジン(Falco / Tetragon)

  • メリット: プログラマブルでシステムコールのオーバーヘッドがほぼゼロ。リアルタイムアラートに対応し、Kubernetesやコンテナワークロード向けに設計されている。
  • デメリット: 全機能を利用するにはLinuxカーネル5.8以降が必要。メモリ消費量が比較的大きく(ノードあたり200〜500MB程度)、カスタムポリシーの開発には学習コストがかかる。

3. Linux監査デーモン(auditd)

  • メリット: カーネルに直接組み込まれており、主要なエンタープライズディストリビューション(RHEL、Debian、Ubuntu、Rocky Linux)に標準搭載。厳格なコンプライアンス要件(PCI-DSS 10.2、CISベンチマーク、SOC 2、HIPAA)を満たし、専用のフォレンジック検索ユーティリティ(ausearch、aureport)を備える。
  • デメリット: ルール設定が広範すぎたり適切に調整されていなかったりすると、I/O負荷が高くなりディスク容量を急速に消費する。

最適なアプローチ:Auditdの導入と設定手順

秒間500リクエスト以上を処理する高負荷な本番環境ノードでは、ルールのスコープが不適切だと1時間に数ギガバイトものログが生成される恐れがあります。ストレージを圧迫することなく安全にauditdを導入、設定、検証するために、以下の体系的な手順に従ってください。

ステップ1:監査デーモンのインストールと有効化

UbuntuまたはDebianに必要なパッケージをインストールします。

sudo apt update
sudo apt install auditd audispd-plugins -y

RHEL、Rocky Linux、AlmaLinuxの場合:

sudo dnf install audit -y

サービスを起動し、OS起動時の自動起動を有効化します。

sudo systemctl enable --now auditd
sudo systemctl status auditd

ステップ2:永続的な監査ルールの定義

auditctlコマンドで直接追加したルールは即座に適用されますが、再起動すると消えてしまいます。永続化させるには、/etc/audit/rules.d/にモジュール単位でルールを記述します。augenrulesスクリプトがこれらをコンパイルし、/etc/audit/audit.rulesを生成します。

ルールは主に以下の2つのカテゴリに分類されます。

  1. ファイルウォッチ(File Watches): ファイルやディレクトリへのアクセスを、読み取り(r)、書き込み(w)、実行(x)、属性変更(a)の観点で監視します。
  2. システムコールルール(Syscall Rules): execve、settimeofday、ptraceなどのカーネルレベルの関数をインターセプトします。

/etc/audit/rules.d/security.rulesに専用の設定ファイルを作成します。

sudo nano /etc/audit/rules.d/security.rules

以下の本番運用向けルールを追加します。

## 既存のルールを削除し、カーネルバッファを割り当て(8,192メッセージ)
-D
-b 8192
-f 1

## 1. ユーザーおよびグループデータベースの変更を監視
-w /etc/passwd -p wa -k identity_changes
-w /etc/shadow -p wa -k identity_changes
-w /etc/group -p wa -k identity_changes
-w /etc/gshadow -p wa -k identity_changes

## 2. SSHキーの追加およびデーモン設定の変更を追跡
-w /root/.ssh/ -p wa -k ssh_key_tamper
-w /etc/ssh/sshd_config -p wa -k sshd_config_change

## 3. スケジュールジョブおよび権限昇格ルールの監視
-w /etc/crontab -p wa -k cron_tamper
-w /etc/cron.d/ -p wa -k cron_tamper
-w /etc/sudoers -p wa -k sudo_privilege_escalation
-w /etc/sudoers.d/ -p wa -k sudo_privilege_escalation

## 4. システム時刻の改ざんを検知(ログの順序偽装によく利用される)
-a always,exit -F arch=b64 -S adjtimex,settimeofday,clock_settime -k system_time_change

## 5. 権限昇格を捕捉:一般ユーザーがrootのEUIDで実行したコマンド
-a always,exit -F arch=b64 -S execve -C uid!=euid -F euid=0 -k elevated_priv_exec

ルールパラメータの内訳:

  • -b 8192:カーネルの監査バッファを8,192メッセージに設定します。これにより、書き込みスパイク発生時のイベント破棄を防ぎます。
  • -w <path>:監視対象のファイルまたはディレクトリパスを指定します。
  • -p wa:プロセスがファイルに対して書き込み(w)を行うか、パーミッションや所有権などの属性変更(a)を行ったときにトリガーされます。
  • -k <key_name>:高速な検索・フィルタリング用にカスタムキーを設定してレコードをタグ付けします。
  • -a always,exit:指定したシステムコールが完了した直後に監査イベントを記録します。
  • -F arch=b64:フィルタリングを64ビットアーキテクチャのシステムコールに限定します。

ステップ3:ルールの読み込みと確認

デーモンを再起動することなく、新しいルールをコンパイルして読み込みます。

sudo augenrules --load

カーネルで有効になっているルールを一覧表示し、正しく読み込まれたことを確認します。

sudo auditctl -l

ステップ4:ausearchとaureportを用いたログの検索とフィルタリング

生のログエントリは/var/log/audit/audit.logに保存されます。これらのレコードには16進数エンコードされたパスや数値IDが含まれています。ausearchを使用することで、人間が読み取れる形式に変換・抽出できます。

1. ルールキーでフィルタリングし、IDを名前に変換して表示:

sudo average ausearch -k identity_changes -i

-i(interpret)フラグを使用すると、数値のUIDやGID、16進数エンコードされた文字列が自動的にubuntu、root、/etc/passwdなどの名前に変換されます。

2. 特定の時間範囲でイベントを検索:

sudo ausearch -k ssh_key_tamper -ts today -te now -i

3. 特定のユーザー(UID 1000)によって実行された操作を抽出:

sudo ausearch -ua 1000 -i

4. aureportで監査サマリーを素早く生成:

# システム全体のすべてのファイル変更をサマリー表示
sudo aureport -f -i --summary

# 認証失敗およびsudo実行失敗の一覧を表示
sudo aureport -au -i --failed

# 実行ファイルごとにグループ化した実行コマンド数を集計
sudo aureport -x -i --summary

ステップ5:監査ログレコードの構造解析

監視対象のファイルが変更されると、auditdは複数行のエントリを出力します。ausearch -k identity_changes -iを実行すると、以下のような出力が得られます。

type=SYSCALL msg=audit(10/03/2026 10:15:22.412:128) : arch=x86_64 syscall=openat success=yes exit=3 a0=0xffffff9c a1=0x55dc87a21390 a2=0x241 a3=0x1b6 items=2 ppid=1420 pid=2105 auid=ubuntu uid=root euid=root exe=/usr/bin/nano key="identity_changes"
type=PATH msg=audit(10/03/2026 10:15:22.412:128) : item=0 name="/etc/passwd" inode=264104 dev=fc:01 mode=file,644 ouid=root ogid=root rdev=00:00 nametype=NORMAL

調査で注目すべき重要なフィールド:

  • auid=ubuntu:監査ユーザーID(Audit User ID)。初回ログイン時のアイデンティティを保持します。ユーザーがsudo suでrootに昇格した場合でも、auidには元の実ユーザー(ubuntu)が保持されます。
  • uid=root / euid=root:実行時にバイナリを実行していた実効ユーザー。
  • exe=/usr/bin/nano:呼び出された実行バイナリの正確なパス。
  • name="/etc/passwd":アクセスまたは変更された対象ファイルのパス。
  • key="identity_changes":設定ファイル内でマッチしたルールラベル。

まとめと本番環境でのセキュリティ強化のヒント

カーネル監査は、システム上で何が起きたのかについて疑う余地の生じない決定的な証拠を提供します。本番運用にあたっては、以下の安全対策を講じておきましょう。

  • ディスク枯渇の防止: /etc/audit/auditd.confを編集し、max_log_file = 50(MB)、num_logs = 5、max_log_file_action = ROTATEを設定します。これにより、監査ログの総容量を250MBに制限できます。
  • ノイズの排除: /tmp、/var/log、頻繁に更新されるデータベースのデータディレクトリなど、書き込みが極めて頻繁なパスに対して無制限の書き込み監視を設定しないでください。
  • ルールセットのロック: 検証完了後、/etc/audit/rules.d/security.rulesの最終行に-e 2を追加します。これによりルールが不変(イミュータブル)となり、rootユーザーであってもサーバーを完全に再起動しない限りルールの変更や監査の停止ができなくなります。
Share: