導入と設定

誤検知を減らす設定

許可リスト、保護するプロセス、脆弱性の受容を使い分けて、警告を減らします。減らしてはいけない警告の見分け方も学びます。

  • レベル: 基礎
  • 約40分
  • 2026-11-12

#警告を減らす手段は3つあります

RoamSwitch には、警告や自動の対応を減らす手段が3つあります。どれも、理由を書いて記録に残す作りです。何を減らすのかが、それぞれ違います。

手段減るもの記録の場所反映
許可リスト(roamswitch server allowlist)決めた規則とプロセスの組への、封じ込め/var/lib/roamswitch/ebpf_guard_allowlist.jsonすぐ(再起動は不要)
止めないプロセス(protected_processes)そのプロセスの凍結と kill/etc/roamswitch/server.confサービスの再起動のあと
脆弱性の受容(roamswitch vuln-accept)パッケージの CVE の「要対応」の件数~/.config/roamswitch/vuln_acceptances.json次の照合から

許可リストは、カーネル層の侵入検知と自律隔離 のためのものです。許可した組の検知も、記録と通知は続きます(通知は冷却時間ごとに1回)。止まるのは封じ込めで、ホスト全体の隔離への格上げにも数えられません。ここはコードで確かめました。

この講座では、使い捨ての Ubuntu 24.04 の VM で、3つを順に使います。足す、効いたかを確かめる、期限を迎える、取り消す、の順です。

#許可リストに、理由と期限をつけて足す

許可リストの1件は、規則(rule)とプロセス(process)の組です。規則の名前もプロセスの名前も、完全に一致したときだけ効きます。同じ規則でも、別のプログラムの検知は、これまでどおり封じ込められます。

許可を足して、一覧を見る

許可リストに書き込む操作です(変更を伴う操作です)。元に戻すには、sudo roamswitch server allowlist remove <rule> <process> を実行します。

規則の名前は、練習用の例です。実際には、検知したときの規則の名前とプロセス名を書きます。検知の履歴は sudo roamswitch server ebpf で見られます。

sudo roamswitch server allowlist add "Reverse shell" backup-agent
sudo roamswitch server allowlist add "Reverse shell" backup-agent --days 14 夜間バックアップがリモートへ接続するため
sudo roamswitch server allowlist add "Outbound connection to C2" rsync --exe /usr/bin/rsync --days 7 毎晩の rsync によるミラー
sudo roamswitch server allowlist add "X" rsync --days 400 長い
sudo roamswitch server allowlist list
出力の抜粋
  エラー: 許可には理由が要ります。コマンドの最後に、理由を書いてください。
  期限: 2026-11-26(あと 14 日。延ばすときは renew)
  ✓ 許可リストに追加しました: rule="Reverse shell" process="backup-agent"
  ⚠ 警告: 名前のみの許可エントリです。プロセス名は変更するだけで偽装できるため、悪意あるプロセスが同名にリネームすると検知を回避できます。--exe <絶対パス> で実行ファイルに紐づけることを推奨します。
  期限: 2026-11-19(あと 7 日。延ばすときは renew)
  ✓ 許可リストに追加しました: rule="Outbound connection to C2" process="rsync" exe="/usr/bin/rsync"
  エラー: --days には 1 から 365 の数を指定してください(既定は 30)。

  2026-11-12T01:29:44+00:00
    rule: Reverse shell
    process: backup-agent
    exe: (未指定: 名前のみ・偽装可能)
    理由: 夜間バックアップがリモートへ接続するため
    追加した人: admin
    期限: 2026-11-26 (あと 14 日)

  2026-11-12T01:29:44+00:00
    rule: Outbound connection to C2
    process: rsync
    exe: /usr/bin/rsync
    理由: 毎晩の rsync によるミラー
    追加した人: admin
    期限: 2026-11-19 (あと 7 日)

読み取れることは4つです。

  • 理由は必須です。最後の引数が理由になります。理由がないと、追加されず、終了コード 1 で終わります
  • 期限は既定で 30 日、最長 365 日です。400 日は受け付けません
  • 名前だけの許可には警告が出ます。同じ名前に変えたマルウェアも、許可を受け継ぐからです
  • 一覧には、理由、追加した人、期限が残ります。先頭の時刻は UTC です(日本時間は 9 時間足します)
効いているかを test で確かめる

allowlist test は、ガードがそのプロセスをどう扱うかを答えます。何も変更しません。

sudo roamswitch server allowlist test "Outbound connection to C2" rsync --exe /usr/bin/rsync
sudo roamswitch server allowlist test "Outbound connection to C2" rsync --exe /tmp/rsync
sudo roamswitch server allowlist test "Reverse shell" sshd
sudo roamswitch server allowlist renew "Reverse shell" backup-agent --days 30
sudo roamswitch server allowlist remove "Reverse shell" backup-agent
出力の抜粋
  rule: Outbound connection to C2
  process: rsync
  exe: /usr/bin/rsync

  ✗ 凍結・kill の保護: 保護対象ではありません。
  ✓ 許可リスト: この rule と process の組み合わせは許可されています。ガードは何もしません。

  結論: 許可リストにあるため、ガードはこのプロセスに何もしません。

  rule: Outbound connection to C2
  process: rsync
  exe: /tmp/rsync

  ✗ 凍結・kill の保護: 保護対象ではありません。
  ✗ 許可リスト: 許可されていません。

  結論: 許可も保護もありません。ガードの方針(guard.yaml)に従って封じ込めの対象になります。

  rule: Reverse shell
  process: sshd
  exe: (不明)

  ✓ 凍結・kill の保護: 保護対象(組み込みの一覧)。ガードは凍結も kill もしません。
    PATH で見つけた /usr/sbin/sshd として判定しました。動いているプロセスの場所が違うときは、--pid で確かめてください。
  ✗ 許可リスト: 許可されていません。

  結論: 検知の通知は出ますが、このプロセスは凍結も kill もされません。eBPF ガードは、このプロセスを隔離せず、記録と通知だけにします。プロセスを特定しない、ホスト全体への対応は変わりません。

  ✓ 期限を 2026-12-12 に延ばしました。
  ✓ 許可リストから削除しました。

--exe を付けた許可は、/tmp/rsync には効きません。名前が同じでも、実行ファイルの場所が違うからです。

sshd は、何も足さなくても保護されています。組み込みの一覧にあるためです。保護は凍結と kill を止めますが、ホスト全体への対応は止めません。

renew は、今日から数えた日数で期限を延ばします。remove は1件を消します。消す相手がないときは「該当するエントリが見つかりませんでした。」と出て、終了コード 1 で終わります。

#封じ込めが止めないプロセスを指定する

封じ込めが止めないプロセスの指定 は、設定 protected_processes で指定します。ランサムウェア、ランタイムガード、カナリアの自動の封じ込めが、凍結も kill もしないプロセスです。組み込みの一覧(init、コンテナランタイム、sshd、パッケージ管理、RoamSwitch 自身)に足されます。既定は空です。

書き方は2つあります(server.conf.example の注記)。

  • プロセス名: 実行ファイルが /usr、/bin、/opt などのシステムの場所にあるときだけ効きます
  • 絶対パス: その実行ファイルだけに一致します。システムの場所の外に入れたソフトに使います
名前とパスで指定して、test で比べる

設定ファイルを書き換える操作です(変更を伴う操作です)。最後に空に戻します。

同じ中身の練習用プログラムを、/opt と /tmp に置いて動かします。中身は sleep の複製です。

sudo mkdir -p /opt/demo/bin; sudo cp /usr/bin/sleep /opt/demo/bin/worker; cp /usr/bin/sleep /tmp/worker
nohup /opt/demo/bin/worker 3600 >/dev/null 2>&1 &
P1=$!
nohup /tmp/worker 3600 >/dev/null 2>&1 &
P2=$!
sudo roamswitch server config set protected_processes "worker,../x"
sudo roamswitch server config set protected_processes worker
sudo roamswitch server allowlist test "Reverse shell" --pid $P1
sudo roamswitch server allowlist test "Reverse shell" --pid $P2
sudo roamswitch server config set protected_processes /tmp/worker
sudo roamswitch server allowlist test "Reverse shell" --pid $P2
sudo roamswitch server config set protected_processes ""
kill $P1 $P2
出力の抜粋
Error: protected_processes: '../x' is not a process name or an absolute path
  ✓ サーバー設定を更新・保存しました。 (protected_processes = worker)
  反映するには: sudo systemctl restart roamswitch-server または sudo roamswitch server restart

  exe: /opt/demo/bin/worker
  ✓ 凍結・kill の保護: 保護対象(server.conf の protected_processes、名前)。ガードは凍結も kill もしません。
  注意: server.conf は roamswitch-server の起動のあとに変わっています。上の判定は今の server.conf の protected_processes によるもので、動いているデーモンには再起動まで効きません(sudo roamswitch server restart)。

  exe: /tmp/worker
  ✗ 凍結・kill の保護: 名前は保護の一覧にありますが、実行ファイルが /tmp/worker にあり、システムの場所の外なので保護されません(名前の偽装を防ぐため)。

  ✓ サーバー設定を更新・保存しました。 (protected_processes = /tmp/worker)
  exe: /tmp/worker
  ✓ 凍結・kill の保護: 保護対象(server.conf の protected_processes、実行ファイルのパス)。ガードは凍結も kill もしません。

  ✓ サーバー設定を更新・保存しました。 (protected_processes = )

名前で書いた worker は、/opt のものだけを守りました。/tmp の同名のものは守られません。../x のような値は、保存されずにエラーになります。

--pid を使うと、動いているプロセスの実行ファイルの場所で判定します。名前だけで聞くより確かです。

test は保存した設定を読み、デーモンは起動時に読みます

allowlist test は、server.conf に保存した protected_processes を、その場で読んで答えます。デーモンが読むのは起動したときだけです(コードで確認)。

保存した直後の test は「保護対象」と答えますが、動いているデーモンには、まだ効いていません。そのため test の最後に「注意: server.conf は roamswitch-server の起動のあとに変わっています」と出ます。保存したら sudo roamswitch server restart を実行します。再起動したあとの test には、この注意は出ませんでした。許可リストのほうは、再起動しなくても効きます。

やってはいけないこと
  • /tmp などのパスを protected_processes に書く。 上の演習は、比べるためにわざと書きました。誰でも書き込める場所のファイルは、別の中身に差し替えられます
  • 名前だけの許可を、そのまま使い続ける。 警告が出たら、--exe を付けて足し直し、名前だけのほうは remove します
  • よく考えずに最長の期限にする。 期限は、見直す日です

#脆弱性を、理由と期限をつけて受容する

パッケージの既知の脆弱性の照合 (roamswitch scan-packages)は、入っているパッケージを、手元の既知の CVE の対応表と照合します。通信はしません。対応表は roamswitch-updater が配ります。届く前は、何も検出しません。

脆弱性の受容 は、そのうちの1件を、理由と期限を付けて「要対応」の数から外します。検出は一覧に残ります。

照合して、1件を受容し、取り消す

受容の記録を書き込む操作です(変更を伴う操作です)。元に戻すには --revoke を使います。

対応表は、入れたときに roamswitch-update.service が1回取りに行きます。前の版から上げたときも、まだ無ければ取りに行きます。この VM では、上げたときに届いていました。届いていないときは、sudo systemctl start roamswitch-update.service で1回動かします。

roamswitch scan-packages
roamswitch vuln-accept Ubuntu pyjwt CVE-2026-102274 --version 2.7.0-1ubuntu0.3
roamswitch vuln-accept Ubuntu pyjwt CVE-2026-102274 --version 2.7.0 --reason "x"
roamswitch vuln-accept Ubuntu pyjwt CVE-2026-102274 --version 2.7.0-1ubuntu0.3 --days 7 --reason "PyJWKSet を使うアプリがなく、次の定期更新で上げる"
roamswitch vuln-accept --list
roamswitch scan-packages | grep -A3 "CVE-2026-102274"
roamswitch vuln-accept --revoke Ubuntu pyjwt CVE-2026-102274 --version 2.7.0
出力の抜粋
  要対応 15 件 / 受容中 0 件(うち 14 日以内に期限が来るもの 0 件) / 期限切れで要対応に戻ったもの 0 件

  CVE-2026-111497  [Ubuntu 24.04] brotli 1.1.0-2build2 (CVSS 9.8)
    KEV  米国CISAが、実際に悪用されていることを確認した脆弱性です。
    EPSS 83% (2026-11-09)  (悪用が確認された数字ではなく、悪用される見込みの目安です)
    📦 パッケージ: libbrotli1
    修正版: 1.1.0-2ubuntu0.1

  CVE-2026-102274  [Ubuntu 24.04] pyjwt 2.7.0-1ubuntu0.3 (CVSS 7.5)
    EPSS 0.5% (2026-11-09)  (悪用が確認された数字ではなく、悪用される見込みの目安です)
    📦 パッケージ: python3-jwt
    修正版: 2.7.0-1ubuntu0.4

理由が必要です。--reason に、受容する理由を書いてください。
注意: Ubuntu pyjwt 2.7.0 の CVE-2026-102274 は、今の照合結果にありません。受容は記録しましたが、バージョンやCVE-IDが違うか、そのパッケージが入っていない可能性があります。照合結果の表示どおりかどうか、roamswitch scan-packages で確かめてください(間違いなら --revoke で取り消せます)。
受容しました: Ubuntu pyjwt 2.7.0 CVE-2026-102274。2027-02-10 まで要対応の数から外します(検出は一覧に残ります)。別のバージョンには効きません。期限が来ると要対応に戻り、記録が残ります。
受容しました: Ubuntu pyjwt 2.7.0-1ubuntu0.3 CVE-2026-102274。2026-11-19 まで要対応の数から外します(検出は一覧に残ります)。別のバージョンには効きません。期限が来ると要対応に戻り、記録が残ります。

  Ubuntu pyjwt CVE-2026-102274 (2.7.0-1ubuntu0.3)
    期限: 2026-11-19 (あと 7 日)
    理由: PyJWKSet を使うアプリがなく、次の定期更新で上げる
    記録: admin (2026-11-12)

  Ubuntu pyjwt CVE-2026-102274 (2.7.0)
    期限: 2027-02-10 (あと 90 日)
    理由: x
    記録: admin (2026-11-12)

  CVE-2026-102274  [Ubuntu 24.04] pyjwt 2.7.0-1ubuntu0.3 (CVSS 7.5)
    EPSS 0.5% (2026-11-09)  (悪用が確認された数字ではなく、悪用される見込みの目安です)
    受容中 (2026-11-19 まで): PyJWKSet を使うアプリがなく、次の定期更新で上げる
    📦 パッケージ: python3-jwt
受容を取り消しました: Ubuntu pyjwt 2.7.0 CVE-2026-102274。この検出は要対応に戻ります。

パッケージの名前と版は、照合結果のとおりに書きます。Ubuntu では、ソースパッケージ名(pyjwt)とその版です。入っているパッケージ名(python3-jwt)ではありません。

理由がないと、記録されず、終了コード 2 で終わります。版を間違えると、注意が出たうえで受容は記録されますが、どの検出にも効きません。--revoke で取り消します。期限を書かないと、既定の 90 日になります。最長は 365 日です。

受容した検出は、一覧から消えません。「受容中」と理由が、その検出の下に出ます。

受容するか、更新するか

照合結果に「修正版」の行があれば、まず更新を考えます。受容は、すぐに更新できないとき、影響しないと調べて言えるときの記録です。

  • 修正版がある → 更新します。受容するなら、次の更新までの短い期限にします
  • 修正版がない → 悪用が確認された脆弱性に、修正版がない の手順で、使われ方を調べてから決めます
  • KEV(実際に悪用が確認されたもの)で修正版がある → 受容しないで更新します

KEV で修正版がある検出も、受容は記録されます。そのときは注意が出ます。VM で CVSS 9.8 の KEV の brotli を受容すると、次の行が出ました。

実行結果
注意: CVE-2026-111497 は、米国CISAが実際に悪用されていることを確認した脆弱性(KEV)で、修正版 1.1.0-2ubuntu0.1 が出ています。受容より先に、更新を考えてください。

受容を止めるのは、記録する人の判断です。試したあとは roamswitch vuln-accept --revoke Ubuntu brotli CVE-2026-111497 --version 1.1.0-2build2 で取り消します。

#期限が切れたときの動き

許可も受容も、期限が来ると効かなくなります。記録は一覧に残ります。ここでは、VM の時計を進めて、期限切れを起こします。

時計を動かすのは、使い捨ての環境だけにします

許可と受容の期限は、これまでに見た最も新しい時刻で判定します。時計を戻しただけでは、切れた許可と受容は戻りません。NTP で時計が合うと、本来の期限まで効きます(下の演習で確認)。それでも、本番のサーバーで時計を進めると、時計が合うまでのあいだ、許可がまとめて切れます。通知の履歴からは、進めた時計で 7 日より前の記録が消え、時計を戻しても戻りません。

時計を8日進めて、両方の期限切れを見る

システムの時計を変える操作です(変更を伴う操作です)。最後の2行で元に戻します。

前の演習の、期限 2026-11-19 の許可(rsync)と受容(pyjwt)を使います。

sudo timedatectl set-ntp false
sudo date -s "+8 days"
roamswitch vuln-accept --list
roamswitch scan-packages | sed -n 7,8p
sudo roamswitch server allowlist list
sudo roamswitch server allowlist test "Outbound connection to C2" rsync --exe /usr/bin/rsync
roamswitch notifications
出力の抜粋
  Ubuntu pyjwt CVE-2026-102274 (2.7.0-1ubuntu0.3)
    期限: 2026-11-19 (期限切れ(要対応に戻っています))

  要対応 15 件 / 受容中 0 件(うち 14 日以内に期限が来るもの 0 件) / 期限切れで要対応に戻ったもの 1 件
  受容の期限が切れました: Ubuntu pyjwt 2.7.0-1ubuntu0.3 CVE-2026-102274(記録しました)

    rule: Outbound connection to C2
    process: rsync
    exe: /usr/bin/rsync
    期限: 2026-11-19 (切れています。許可は効いていません)

  ✗ 許可リスト: 許可の期限が切れています。ガードは通常どおり動きます(renew で延ばせます)。
  結論: 許可も保護もありません。ガードの方針(guard.yaml)に従って封じ込めの対象になります。

  2026-11-20T01:30:03.753742342+00:00
  受容の期限が切れました
    Ubuntu pyjwt 2.7.0-1ubuntu0.3 の CVE-2026-102274: 2026-11-19 までの受容が切れました。要対応に戻ります。
    インシデントタイムラインには、まだ記録していません(タイムラインは root だけが書けます)。次に sudo roamswitch scan-packages で照合したときに記録します。ここ(通知履歴)には記録しました。

受容が切れた検出は「期限切れで要対応に戻ったもの」として、別に数えられます。通知の履歴にも1回残ります。一般ユーザーの照合では、タイムラインには書きません。続けて sudo roamswitch scan-packages を実行すると、sudo roamswitch timeline に [Risk Acceptance] の行が入りました。

切れた許可は、一覧に「切れています」と出ます。ガードは、許可がなかったときと同じに動きます。続けるなら renew で延ばし、要らなければ remove で消します。

timedatectl set-ntp false は、systemd-timesyncd のユニットのリンク(/etc/systemd/system/dbus-org.freedesktop.timesync1.service)を消します。そのため、数秒後に重要ファイルの改ざんの通知が1件出ました。自分の操作なので、ここでは問題ありません。

時計を戻し、NTP の同期を入れ直します。同期するまで待ってから、もう一度確かめます。

sudo date -s "-8 days"
sudo roamswitch server allowlist test "Outbound connection to C2" rsync --exe /usr/bin/rsync | grep '許可リスト'
sudo timedatectl set-ntp true
until timedatectl show -p NTPSynchronized --value | grep -q yes; do sleep 2; done
sudo roamswitch server allowlist test "Outbound connection to C2" rsync --exe /usr/bin/rsync | grep '許可リスト'
roamswitch vuln-accept --list | grep 期限
出力の抜粋
  ✗ 許可リスト: 許可の期限が切れています。ガードは通常どおり動きます(renew で延ばせます)。
  ✓ 許可リスト: この rule と process の組み合わせは許可されています。ガードは何もしません。
    期限: 2026-11-19 (あと 7 日)

時計を戻しただけでは、許可は切れたままでした。NTP で時計が合うと、許可も受容も、本来の期限(2026-11-19)まで効くように戻りました。

#減らしてはいけない警告

減らす手段は、誤検知だと説明できるときに使います。説明できない警告は、減らさずに調べます。

演習の途中で、/tmp/worker を動かしたとき、プロセス実行の記録と攻撃手口の検知 が1件の通知を出していました。

通知の履歴(roamswitch notifications、出力の抜粋)
  🔎 不審な実行パターンを検知
    一時ディレクトリ・削除済み・memfd からの実行 (EXR-002)
    プロセス: /tmp/worker (PID: 1281) / 重要度: 中
    詳細: 誰でも書き込めるディレクトリからの実行です。分類: tmp、パス: /tmp/worker
    次の確認コマンド: sudo roamswitch events tree 1281
    (通知のみ・遮断はしていません)
    プロセス: admin / /tmp/worker / コマンド: /tmp/worker 3600 (pid 1281)
    親プロセス: bash ← script ← dash ← tart-guest-agent ← systemd

動かした利用者(admin)、コマンド、親プロセスの系譜も出ます。今回は、自分で置いたファイルなので、説明できます。本番で心当たりがなければ、sudo roamswitch events tree <PID> で、何が起動したのかを先に見ます。

減らしてよいかを、3つの問いで決める
  1. 何が、なぜ動いたかを説明できますか。 自分が入れたソフトで、決まった時刻に、決まった動きをするなら、説明できます
  2. 実行ファイルの場所は、システムの場所か、自分が管理する場所ですか。 /tmp や /dev/shm のような、誰でも書き込める場所なら、減らしません
  3. 狭く書けますか。 許可リストなら --exe を付け、期限を短くします。許可リストは、設計として、規則とプロセスの組で書きます。規則を丸ごと止める書き方はありません

1つでも「いいえ」なら、減らさずに調べます。

減らしてはいけない警告
  • 心当たりのない、一時ディレクトリからの実行。 攻撃の入口でよく使われます
  • 修正版が出ている KEV の検出。 受容ではなく、更新します
  • 入れた覚えのないプロセスへの封じ込め。 許可を足す前に、sudo roamswitch events tree <PID> で起動元を確かめます
  • ホスト全体の隔離が働いた検知。 最も重い段階です。原因を調べる前に、許可を足して次から止めることはしません

#見えない部分

この講座で確かめた範囲

使い捨ての Ubuntu 24.04 の VM で、許可リストの追加・確認・延長・削除、protected_processes の判定、脆弱性の受容と期限切れを、実際に動かしました。

  • 実際の検知と封じ込めは、起こしていません。 この VM では、eBPF ガードのセンサー(Falco・Tetragon)が動いていません。許可と保護の効き目は、allowlist test の判定で見ました
  • 許可した組の検知も、通知と記録は続きます(コードで確認)。通知を静かにする手段ではありません
  • allowlist test の答えは、保存した設定に基づきます。 protected_processes は、デーモンを再起動するまで効きません
  • 受容は、リスクを下げません。 下げるのは、更新、削除、停止です
確認問題

「名前だけの許可エントリです」と警告が出ました。正しい対応はどれですか

解説を見る

プロセス名は、名前を変えるだけで偽装できます。--exe を付けると、場所が違う同名のプログラムには効きません。演習では、/tmp/rsync に許可が効かないことを、test で確かめました。

確認問題

protected_processes を保存した直後、test が「保護対象」と答えました。このとき正しいのはどれですか

解説を見る

設定を保存したときの出力にも「反映するには: sudo systemctl restart roamswitch-server」と出ます。許可リストとは違い、protected_processes はデーモンが起動するときに読みます。

#次に学ぶこと

扱う機能
確認した内容

2026-11-12に確認しました。対象は Linux 1.17.39 です。公開版の Linux 1.17.39 が入った使い捨ての Ubuntu 24.04 の VM(server.conf なしから)で、許可リストの追加・test・延長・削除、protected_processes の名前とパスの判定と再起動のあとの test、scan-packages と vuln-accept の受容・取り消し(KEV の注意を含む)、時計を8日進めた期限切れとタイムラインへの記録、時計を戻して NTP で合わせたあとに許可と受容が本来の期限まで効くことを日英で実行し、language=ja で記録した通知を LANG=en で読み直しました。許可した組の通知が続くこととデーモンの読み込みの時期はソースで確かめました。

コマンドの出力は、製品の版や環境によって変わります。違いが出たら、まず製品の版を確かめてください。