サーバーで実行コマンドを監査する方法
シェル履歴は監査証跡になりません。sudo ログ、セッション記録、シェルフック、auditd の execve ルールを比較し、ログをサーバー外へ送る方法を解説します。
サーバー上でユーザーが実行したコマンドを実際に記録する方法
サーバー上でユーザーが実行したコマンドを監査するには、ユーザーが編集できない記録が必要です。シェル履歴はその記録ではありません。これは利便性のためのファイルであり、書き込んだアカウントが所有します。そのシェルに入力できるユーザーなら、履歴記録を無効にしたり削除したりできます。
実際の記録を保持できる層は4つありますが、それぞれにコストがあります。sudo はコマンドごとに1行を syslog へ書き込みます。sudo の I/O ロギングは、1つのアカウントについてセッション全体を記録します。PROMPT_COMMAND のようなシェルフックは、対話的な bash ユーザーが入力した内容を記録します。カーネルの監査サブシステムは execve syscall 自体を記録するため、すべてのプロセスを把握できる唯一の層です。このガイドでは、これらの層を順に説明し、それぞれの記録範囲を示します。最後に、記録を監査対象者が到達する前にマシンの外部へ送れるかどうかが、これらの記録に価値があるかを左右します。
開始する前に、1つ注意点があります。監査サブシステムはカーネル上で動作するため、ホストのカーネルを共有するコンテナ内ではテストできません。カーネルを自分で管理できる KVM VPS 上でコマンドを実行してください。
シェル履歴が監査証跡にならない理由
~/.bash_historyは、一般的な4つの理由により証拠として機能しません。どれも、攻撃者が巧妙である必要はありません。
ユーザーに属しています。 ファイルのモードは600で、そのアカウントが所有者です。そのため、rm ~/.bash_historyに特別な権限は一切必要ありません。エディターで開き、重要な20行を削除する場合も同様です。
シェルの終了時に書き込まれます。 kill -9 $$で終了したセッションや、接続が切断されたセッションでは、何も書き込まれません。exitの前にhistory -cを実行した場合も同じで、何も起きなかったように見えます。
1語で無効にできます。 unset HISTFILEは、そのセッションでのファイルへの書き込みを停止します。set +o historyは記録を直ちに停止します。HISTCONTROL=ignorespaceは、先頭にスペースを付けて入力したすべてのコマンドを隠します。これはすべて、ユーザーが制御できるようにman bashに定義されています。
入力された内容を記録するだけで、実行された内容は記録しません。 alias やシェル関数を使用すると、ファイル内のテキストはカーネルが実行したプログラムそのものではありません。
また、HISTTIMEFORMATがエントリの書き込み時に設定されていない限り、タイムスタンプもありません。bashは、この変数が設定されている場合にのみ#1755043200のマーカー行を書き込むためです。
共有ログインでは、誰が実行したのかも判別できません。3人が1つのdeployアカウントを使用すると、1つの uid 配下に、複数人の操作が混在した1つのファイルが生成されます。2人が同じ uid を共有している場合、どのロギング層でも操作を人間個人に帰属させることはできません。これが、共有ログインではなく、ユーザーごとに1つの非特権アカウントを用意するべき実務上の理由です。
シェル履歴は、本来の目的には適しています。昨日のコマンドを再入力する際に役立つためです。参考情報として使用してください。証拠として提示してはいけません。
sudo のログ内容と記録が止まる箇所
sudo は実行するすべてのコマンドについて、authpriv syslog ファシリティに 1 行を送信します。
sudo grep 'sudo:' /var/log/auth.log | tail -5
journalctl -t sudo -n 5各行には、ユーザー、端末、作業ディレクトリ、対象ユーザー、コマンドが記録されます。
sudo: alice : TTY=pts/0 ; PWD=/home/alice ; USER=root ; COMMAND=/usr/bin/apt update/var/log/auth.log が存在しない場合、そのイメージには rsyslog がインストールされていません。同じ記録は journal にのみ保存されています。journal を信頼する前に、揮発性ではないことを確認してください。
journalctl --list-boots現在のブートしか表示されない場合、/var/log/journal が存在しないため、journal は /run に保存されています。そのため、次回の再起動ですべての行が失われます。永続化します。
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald次に、記録の限界を確認します。sudo が記録するのは、実行を要求されたコマンドです。そのコマンドが後から実行する処理までは記録しません。したがって、記録は 1 行で途切れます。
sudo -iシェルについては 1 件の記録しか残りません。その root シェル内で入力したコマンドは、sudo が処理経路から外れているため、sudo には記録されません。sudo su -、sudo bash、sudo vim /etc/shadow に続けて :!bash を実行する場合も、すべて同じ構造です。vim や find のように shell escape が可能なプログラムを許可する sudoers ルールは、ログに記録されない root 権限を付与するルールです。ログの行を信頼する前に、アカウントが実際に到達できる範囲を確認してください。
sudo -l -U alice1 つのアカウントのセッション全体を記録する
まず、使用している sudo を確認します。この機能は Rust で書き直された実装には存在しないためです。
sudo --version | head -1出力に sudo-rs と表示された場合は、このセクションを飛ばして audit サブシステムを使用してください。Ubuntu の 25.10 および 26.04 リリース向け公式ドキュメントでは、I/O ロギングと sudoreplay はサポート対象外と記載されており、2026 年 8 月時点でも変更されていません。これが重要なのは、これらのリリースでは sudo-rs がデフォルトの sudo であり、アップグレードによって利用できると思っていた制御機能が失われる可能性があるためです。sudo ベースのロギングを計画する前に、sudo-rs の動作変更一覧を確認してください。
Ubuntu 24.04 LTS にも引き続き同梱されている従来の sudo では、1 つのアカウントに対して I/O ロギングを有効にします。
sudo visudo -f /etc/sudoers.d/iologDefaults:deploy log_output
Defaults!/usr/bin/sudoreplay !log_outputエディターではなく visudo を使用してください。構文解析できないファイルの保存を拒否するためです。壊れた sudoers ファイルは、すべてのユーザーを sudo から締め出します。続いて、セッションを再生します。
sudo sudoreplay -l user=deploy
sudo sudoreplay 000001sudoreplay -l はセッションを ID とともに一覧表示します。log_output がそのユーザーに適用されていない場合は、何も出力しません。必要な容量にも注意してください。端末を通過するすべてのバイトが /var/log/sudo-io に保存されるため、出力の多いセッションは大きくなります。2 行目の sudoers 設定は、再生処理自体が記録されることを防ぎます。実際に大きな問題となるのは Secret です。I/O ログには、入力および出力された内容がそのまま保存されます。セッション内のプロンプトに入力したパスワードも含まれるため、パスワード保管庫と同じ保護が必要です。記録範囲も限定されます。sudo 経由で実行されたコマンドだけが対象です。ログイン後に自分のアカウントとしてのみ作業したユーザーは、まったく記録されません。
シェルフックと、正確な回避方法
「すべてのコマンドを記録する」方法として広まっているのは、PROMPT_COMMAND フックを /etc/profile.d/ に配置する手順です。
# /etc/profile.d/00-cmdlog.sh
PROMPT_COMMAND='logger -p local6.info -t cmdlog "$(whoami) $$ $(history 1 | sed "s/^ *[0-9]* *//")"'bash は各プロンプトを表示する前に PROMPT_COMMAND を実行します。そのため、行がシェルの終了時ではなく、入力された時点で syslog に送られます。logger はシステムログデーモン経由で書き込むため、ユーザー自身のファイル権限は関係しません。新しい login shell を開き、sudo tail -f /var/log/syslog で確認してください。rsyslog がないイメージでは journalctl -t cmdlog -f を使用します。
ただし、次の 5 通りでは機能しなくなります。いずれも 1 分で再現できます。
- 非対話型シェルはプロンプトを表示しません。
ssh you@server 'id'はコマンドを実行して終了しますが、PROMPT_COMMANDが評価されないため、何も記録されません。 - これは変数です。
unset PROMPT_COMMANDを実行すると、そのセッションの残りの期間は無効になり、権限も必要ありません。 - このファイルは login shell によって読み込まれます。
bash --noprofile --norcは/etc/profile.d/をまったく source しません。 - bash 固有の機能です。
vim内のzsh、sh、python3 -c 'import os; os.system("id")'、:!idは、bash のプロンプトフックからは確認できないプログラムを実行します。 - 入力された行をそのまま記録するため、alias や関数を使うと、実際に実行されたコマンドは隠れます。
シェルフックは、利便性のために使用してください。協力的なユーザーに対して、「先週の火曜日に何を実行したか」を確認する用途には使えます。これを統制手段と呼ぶチェックリストに依存してはいけません。
カーネル監査サブシステムはすべての execve を認識します
auditd デーモンによって動作する Linux audit サブシステムは、ここでユーザーが回避できない唯一の層です。システムコールの実行時に、カーネル内部で記録が作成されるためです。プロセスがプログラムを実行すれば、イベントが発生します。シェル、使用言語、端末の有無は関係ありません。
sudo apt update && sudo apt install -y auditd audispd-plugins
sudo systemctl enable --now auditd
sudo auditctl -sauditctl -s はデーモンの状態を表示します。ゼロ以外の pid を伴う enabled 1 は実行中を示し、lost 0 はまだ記録が 1 件も破棄されていないことを示します。この lost カウンターは後で再び登場するため、覚えておいてください。
auid は、audit を導入する価値を生むフィールドです。 PAM はセッション開始時に login uid を設定し、カーネルはそれ以降、すべての子プロセスにその値を引き継がせます。自分の値を確認します。
cat /proc/self/loginuid対話型 SSH セッションでは pam_loginuid.so に /etc/pam.d/sshd が含まれるため、自分の uid が表示されます。4294967295 の値は loginuid が設定されていないことを示します。これは、起動時に system daemon が開始したプロセスでは通常の状態です。重要なのは、sudo -i がこの値を変更しないことです。alice が開いた root shell でも auid 1000 が維持されるため、その中で実行したすべてのコマンドを alice に帰属させられます。これは、sudo では残る抜け穴です。いったん設定した loginuid の変更には CAP_AUDIT_CONTROL が必要で、通常のユーザーにはその権限がありません。さらに sudo auditctl --loginuid-immutable により、次回の再起動まで root に対しても変更できなくなります。
/etc/pam.d/sshd、/etc/pam.d/login、/etc/pam.d/cron にそれぞれ pam_loginuid.so が含まれていることを確認してください。含まれていないと、イベントに対応するユーザーがない状態で記録されます。これは VPS 上の SSH アクセスを強化する際に編集するファイル一覧と同じです。2 つの作業をまとめて行ってください。
auditd の基本ルールセット
ルールは /etc/audit/rules.d/*.rules に配置します。augenrules はファイル名順にルールを連結して 1 つのリストにします。カーネルは最初に一致したルールで処理を停止するため、順序によって動作が決まります。追加する前に、すでに存在する内容を確認してください。後のファイルにある -D によって、それまでに読み込まれたすべてのルールが消去されるためです。
ls /etc/audit/rules.d/
cat /etc/audit/rules.d/audit.rules次に、/etc/audit/rules.d/50-exec.rules を記述します。
## Suppressions first: the kernel takes the first matching rule.
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg-deb
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg-query
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg-split
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg-trigger
## Every program started by a logged-in human.
-a always,exit -F arch=b64 -S execve,execveat -F auid>=1000 -F auid!=unset -k exec
-a always,exit -F arch=b32 -S execve,execveat -F auid>=1000 -F auid!=unset -k exec
## Changes to who may become root.
-w /etc/sudoers -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
## Changes to the audit configuration itself.
-w /etc/audit/ -p wa -k auditconfig読み込んで確認します。
sudo augenrules --load
sudo auditctl -lauditctl -l によってルールが再表示されれば、ルールは有効です。No rules は読み込みに失敗したことを示し、journalctl -u auditd -n 20 はパーサーが拒否したファイルと行を示します。古い audit userspace は unset キーワードを認識しません。ローダーがこのフィールドについてエラーを出す場合は、代わりに -F auid!=4294967295 と記述してください。これは同じ値を文字列で指定したものです。
次に、イベントを読み取ります。
sudo ausearch -k exec -ts recent -i | tail -40
sudo ausearch -ul 1000 -ts today -i
sudo aureport -k --summary -i-i は uid と syscall 番号を名前に変換します。実際の運用では省略できません。-ts recent は直近 10 分間を対象にします。各実行は複数のレコード群として記録されます。SYSCALL レコードには uid、auid、終了ステータス、key が含まれます。EXECVE レコードには引数の完全なリストが含まれます。さらに、コンテキスト用の CWD レコードと PATH レコードも記録されます。
注意すべき制限が 1 つあります。audit が記録するのは syscall であり、shell builtin 自体は syscall を実行しません。cd /root はプログラムを実行しません。bash のプロンプトで echo evil >> /etc/passwd と入力しても、プログラムは実行されません。echo とリダイレクトの両方が、すでに実行中の shell プロセス内で処理されるためです。そのため、execve ルールはプログラムを検出し、-w ルールは書き込みを検出します。どちらか一方だけでは不十分です。
最後に、設定をロックします。
## /etc/audit/rules.d/99-finalize.rules
-e 2-e 2 は、次回の再起動までルールセットを変更不可にします。読み込み後は auditctl -s が enabled 2 を報告し、ルールの追加や削除を試みると、root であっても Operation not permitted で失敗します。このファイルは最後に追加し、ルールを変更するたびに再起動が必要になることを想定してください。この制約が目的です。誰でも気付かれずに無効化できるルールセットは、証拠になりません。
誰も読まない監査ログはコンプライアンスのためだけに残る成果物です
auditd の問題は、必要な情報を取りこぼすことではありません。大量に記録するため、誰も確認しなくなり、結果としてログが質問に答えるためではなく、チェックリストを満たすためだけに存在することです。
何も調整する前に、自分のサーバーで計算してください。
sudo aureport -k --summary -i
sudo du -sh /var/log/audit1 つの sudo apt upgrade は短時間で終了するプロセスを数千個実行します。各プロセスには auid が付与されるため、1 回のパッケージ更新だけで、人が 1 週間に入力する操作量を上回ることがあります。これが、上記の抑制設定で dpkg とそのヘルパーを指定している理由です。抑制はユーザーではなく、必ず実行ファイル単位で行います。/usr/bin/dpkg に対する除外は、1 文で説明できる穴です。一方、アカウントに対する除外は、検出しようとしていた対象そのものと同じ形の穴になります。
各ルールの -k キーによって、1 か月後でもログを検索できます。ausearch -k sudoers は、答えを返せる質問です。フィルターのない ausearch は、読むことをやめるよう促す大量のテキストになります。収集システムがネイティブ形式ではなく JSON を必要とする場合は、laurel を使用できます。これは各イベントを、引数をデコードした 1 個の JSON オブジェクトに書き換える auditd プラグインです。他のプラグインと同様に /etc/audit/plugins.d/ に登録し、auditd は sudo pkill -HUP auditd の変更を取り込みます。
auditd のコストを正直に確認する
条件に一致する各システムコールは、カーネルによってレコードに整形され、ユーザー空間へ渡されます。コストは 2 か所で発生します。どちらも、他者が公開した数値から推測するのではなく、自分のワークロードで測定できます。
- CPU とレイテンシ。頻繁に fork するマシン、ビルドホスト、CI runner では、exec 1 回ごとにレコードが生成されます。カーネルの backlog が一杯になると、
--backlog_wait_timeにより、空きができるまでイベントを生成したプロセスをカーネルが停止します。そのため、audit の影響は CPU 使用率ではなく、ビルドの遅延として現れます。実際の負荷をかけた状態で、sudo auditctl -s内のbacklogとlostを監視してください。lostの増加はレコードが破棄されたことを示します。ログに気付かない欠落がある状態は、ログがない状態より危険です。欠落に気付かないまま、そのログを信頼してしまうためです。 - ディスク。
/etc/audit/auditd.confを読み、ディスクが一杯になったときの動作を意図的に決めてください。出荷時の値は、あくまで選択肢の 1 つです。max_log_file、num_logs、max_log_file_actionはローテーションを制御します。space_left_action、admin_space_left_action、disk_full_actionは緊急時の動作を制御します。選択肢の一部、たとえばhaltとsingleは、レコードを失うよりもマシンを停止させます。
/etc/audit/rules.d/audit.rules の -f 行は、同じ判断をカーネルレベルで指定するものです。-f 1 は audit の失敗を syslog に報告し、-f 2 はカーネルを panic させます。レコードを失うより、本当にサーバーを失うほうがよい場合にだけ 2 を選択してください。利用者が依存するサービスを実行している VPS では、代わりにローテーションを使用し、ストレージの問題をそのサーバーの外へ移してください。
ログをほぼリアルタイムでサーバー外へ転送する
インシデント報告で繰り返し明らかになるのが、この点です。侵害されたホスト内に残ったログは、侵害した攻撃者に編集される可能性があります。root は /var/log/auth.log を書き換え、/var/log/audit/audit.log を削除し、デーモンを停止できます。-e 2 はルールのアンロードを防ぎますが、rm には何も対処しません。ここまでの各層は、まずコピーがマシン外へ出て初めて証拠を生成できます。
Audit 自体の転送機能は、audispd-plugins の audisp-remote プラグインです。/etc/audit/plugins.d/au-remote.conf で有効にします。
active = yes
direction = out
path = /usr/sbin/audisp-remote
type = always
format = string再読み込みの前に、path と command -v audisp-remote が一致していることを確認してください。パスが間違っていると、journal に 1 行出力されるだけで、何も転送されません。/etc/audit/audisp-remote.conf に remote_server と port を設定し、collector 側では独自の auditd.conf に tcp_listen_port = 60 を設定します。sudo pkill -HUP auditd で再読み込みします。多くのイメージでは、unit ファイルが RefuseManualStop=yes を設定しているため systemctl restart auditd が拒否されます。そのため、シグナルを使う方法が確実です。
もう 1 つの方法では、すでに転送している syslog ストリームに audit のイベントを追加します。/etc/audit/plugins.d/syslog.conf には active = no が含まれています。yes に設定して再読み込みすると、audit のイベントが sudo の行やその他のログと同じストリームに入ります。その後、rsyslog で TLS(Transport Layer Security)を使用してまとめて転送します。これには rsyslog-gnutls パッケージが必要です。
# /etc/rsyslog.d/60-forward.conf
*.* action(type="omfwd"
target="logs.example.net" port="6514" protocol="tcp"
StreamDriver="gtls" StreamDriverMode="1"
StreamDriverAuthMode="x509/name"
StreamDriverPermittedPeers="logs.example.net"
action.resumeRetryCount="-1"
queue.type="linkedList" queue.filename="fwd" queue.saveOnShutdown="on")重要なのはキューの設定です。action.resumeRetryCount="-1" は無期限に再試行します。また、queue.saveOnShutdown="on" を指定したディスク補助キューは、collector に接続できない間もレコードを保持し、接続が復旧すると送信します。この 2 つがないと、collector の再起動によって証拠に空白が生じても、その空白の存在を知らせるものがありません。sudo systemctl restart rsyslog で適用し、信頼できる状態になる前に、レコードが実際に collector に到着していることを確認してください。
最後に、もう 1 つ確認すべき点があります。collector は、監査対象のユーザーがログインできないマシンでなければなりません。同じ管理者グループがログサーバーの root 権限も持っているなら、ファイルをコピーしただけで、保護したことにはなりません。認証情報、鍵、できればプロバイダーアカウントも分離してください。これは、複数の Linux サーバーを一元管理する方法を必要になる前に構築する価値がある理由と同じです。また、侵害された VPS の調査に取り組んでいるとき、最初の 1 時間を有効に使えるかどうかを分ける要因でもあります。
通常ユーザーが記録を書き換えられないことを確認する
思い込みで判断せず、実際に確認します。sudo を使わず、一般ユーザーのアカウントから実行します。
echo test >> /var/log/auth.log
cat /var/log/audit/audit.log
auditctl -D
id -nG次の結果がこの順で返ることを確認します。Permission denied。これは、auth.log が syslog 所有、グループ adm、モード 640 だからです。次に Permission denied。監査ログのモードは 600 で、所有者は root です。続いて、実行を拒否するエラーが返ります。監査ルールの変更には CAP_AUDIT_CONTROL が必要だからです。最後に、adm も systemd-journal も含まれないグループ一覧が表示されます。
最後の確認で失敗する人が多くいます。adm のメンバーになると /var/log/auth.log を読み取れるようになり、systemd-journal のメンバーになるとジャーナル全体を読み取れるようになります。どちらも書き込み権限は付与しないため、記録の改ざんはできません。ただし、どちらの場合も、そのサーバー上のすべての認証行を読み取れます。これは、フォーラムの回答から usermod -aG 行をコピーして決めるのではなく、意図的に判断すべき事項です。
最後に、再起動後も維持する必要がある次の 2 点を確認します。
sudo auditctl -s
systemctl is-enabled auditdenabled 2 は、次回の起動までルールセットがロックされることを示します。2 つ目のコマンドにある enabled は、その起動後に auditd が再び起動することを示します。次回のカーネル更新までしか維持されないルールセットは、監査証跡とはいえません。
FAQ
特定のユーザーが実行したすべてのコマンドを確認するにはどうすればよいですか?
id -u alice でそのユーザーの uid を確認し、ログイン uid で監査ログを検索します: sudo ausearch -ul 1000 -ts today -i。execve ルールだけに限定するには -k exec を追加します。ログイン uid はログイン時に設定され、su と sudo -i をまたいでも維持されるため、そのアカウントが開いた root shell 内で実行されたコマンドも捕捉できます。監査ルールが読み込まれた後に実行されたコマンドにだけ有効です。audit は、記録するよう設定されていなかったイベントの履歴を保持しないためです。先にデータの傾向を確認する場合は、sudo aureport -k --summary -i でルールごとの件数を表示できます。
ユーザーは、実行した内容を隠すために bash の履歴を削除できますか?
はい。特権は必要ありません。~/.bash_history はそのユーザーが所有し、モード 600 に設定されているため、編集、切り詰め、削除が可能です。unset HISTFILE で履歴への書き込みを停止したり、set +o history でセッション中の記録を停止したり、HISTCONTROL=ignorespace が設定されている場合に先頭へ空白を付けて入力して個々のコマンドを隠したりすることもできます。bash は shell の終了時にファイルを書き込むため、kill -9 $$ で終了させたセッションは何も記録しません。shell 履歴は手掛かりとして扱い、証拠とは見なさないでください。
sudo は sudo -i 内で起きたことを記録しますか?
いいえ。sudo が記録するのは実行を要求されたコマンドです。そのため、sudo -i では shell の起動が 1 行記録されるだけで、その後の内容は記録されません。その root shell で入力された各コマンドには sudo が関与しないため、sudo からは見えません。sudo su -、sudo bash、および shell escape が可能な許可済みプログラムも同じです。この差を埋める方法は 2 つあります。execve に監査ルールを設定し、元のログイン uid を付けてすべてのプログラムを記録する方法と、最初から shell を与えない sudoers ルールを設定する方法です。
auditd はサーバーの処理速度を低下させますか?
ワークロードが起動するプロセス数に完全に依存するため、数値を鵜呑みにせず測定してください。主にリクエストへ応答するサーバーでは exec の回数が少なく、影響はほとんどありません。ビルドホストや CI runner では exec が頻繁に発生するため、大きな影響が出ることがあります。kernel の audit backlog が満杯になると、イベントを生成したプロセスが空きができるまで停止するためです。実際の負荷をかけて sudo auditctl -s を実行し、backlog と lost を監視してください。lost が 0 より大きい場合は、記録が破棄されています。これは最も深刻な状態です。ログに見えない欠落が生じるためです。
監査ログはどこに保存すべきですか?
別のマシンに保存し、数秒単位の遅延で転送してください。監査対象ホストで root を取得したユーザーは /var/log/audit/audit.log を削除し、/var/log/auth.log を書き換えられるためです。そのため、ローカルコピーで回答できるのは、誰も隠そうとしなかったインシデントについてだけです。audisp-remote plugin で中央の auditd に転送するか、audit syslog plugin を有効にし、rsyslog で syslog 全体を TLS 経由で転送してください。collector には専用の認証情報を割り当て、監査対象のアカウントが collector にアクセスできないようにしてください。