#状況
どちらも RoamSwitch の通知で、「リソース枯渇ガード: 持続的な高CPU使用を検知」です。続けて、同僚から連絡が来ます。「サーバーが重くて、画面がなかなか返ってきません。」
CPU やメモリが尽きる原因は、さまざまです。夜間の集計が長引いただけのこともあります。メモリの上限に当たって、落ちては起き上がるサービスのこともあります。入り込んだ攻撃者が置いた、暗号資産の採掘プログラム(マイナー)のこともあります。
運用者が決めるのは、次の3つです。どのプロセスが原因か。正当な処理か、置かれたものか。止めるか、制限するか。
この講座は、その判断と手順を、使い捨ての VM の中で実際に起こして確かめる手順書です。
| 順番 | すること | 使うもの |
|---|---|---|
| 1. 起こす | 無害な負荷を3つ動かす | systemd-run、Python |
| 2. 見る | 通知と記録を読む | リソース枯渇とクラッシュの検知、通知の履歴、インシデントのタイムライン |
| 3. 調べる | どのプロセスか、親は何か、いつからかを決める | ps、ss、プロセス実行の記録と攻撃手口の検知 |
| 4. 対応する | 止める、制限する、再発を防ぐ | systemctl、kill、ユニットの設定 |
| 5. 元に戻す | 練習の場を片付ける |
検知の仕組みと、メモリの増え続け・コンテナのクラッシュの起こし方は、コンテナとサーバー で扱いました。この講座は、通知が来たあとの判断と手順に絞ります。
この講座は、CPU を使い切るプロセスと、メモリを使い切るサービスを、わざと動かします。メモリを使うサービスには、MemoryMax=100M の上限を付けます。上限の中で止まるので、VM 全体のメモリは尽きません。負荷はすべて VM の中だけで動かし、外には何も送りません。
#練習の場を用意する
リソース枯渇とクラッシュの検知 は、通知だけをします。プロセスを止めることはありません。CPU の判定の既定は、次のとおりです(/etc/roamswitch/server.conf.example と、ソースの既定値)。
| キー | 既定 | 意味 |
|---|---|---|
resource_guard_cpu_enabled | true | CPU を使い続けるプロセスを見る |
resource_guard_cpu_sample_interval_secs | 60 | CPU を測る間隔(秒) |
resource_guard_cpu_window_secs | 600 | 判定する区間(秒) |
resource_guard_cpu_min_samples | 8 | 判定に要る測定の回数 |
resource_guard_cpu_pct_threshold | 80 | 1コアあたり、この % 以上を「高い」と数える |
区間の中の測定の 9 割以上が 80% 以上だと、通知が出ます。メモリの判定と違い、待ち受けていないプロセスも対象です。採掘のプログラムは、外へつなぐだけで、待ち受けないためです。
既定では、判定に 8 分ほどかかります。演習では、測る間隔を 10 秒にします。クラッシュの繰り返しを読むログの監査も、許される最小の 300 秒にします(変更を伴う操作です。最後の演習で戻します)。どれも、反映には再起動が要ります。
sudo roamswitch server config set resource_guard_rss_sample_interval_secs 10
sudo roamswitch server config set resource_guard_cpu_sample_interval_secs 10
sudo roamswitch server config set log_audit_interval_secs 300
sudo roamswitch server restart ✓ サーバー設定を更新・保存しました。 (resource_guard_rss_sample_interval_secs = 10)
反映するには: sudo systemctl restart roamswitch-server または sudo roamswitch server restart
✓ サーバー設定を更新・保存しました。 (resource_guard_cpu_sample_interval_secs = 10)
✓ サーバー設定を更新・保存しました。 (log_audit_interval_secs = 300)
🔄 roamswitch-server サービスを再起動中...
✓ roamswitch-server サービスを正常に再起動しました。メモリと CPU の、両方の間隔を縮めます。再起動の直後は、実行の記録がまだ始まっていないことがあります。次の演習は、30 秒ほど待ってから始めます。
間隔が短いと、デーモンが /proc を読む回数が増えます。ビルドのような短い山でも、通知が出やすくなります。演習のあとは、既定に戻してください。
#CPU を使い続けるプロセスを見つける
無害な負荷を、2つの形で動かします。
- 夜間の集計:
lab-report.serviceとして、nobodyで動く。CPU を回すだけ - 置かれたマイナー:
python3を/var/tmp/.cache/kswapd0にコピーして動かす。カーネルのスレッドに似せた名前で、127.0.0.1:3333につなぎ続ける。止められても、親のシェルが 5 秒後に動かし直す
3333 番は、採掘のプールがよく使う番号です。VM の中に、つながりを受けるだけの lab-pool.service を置き、外のプールの代わりにします。
プロセスを動かす操作です(変更を伴う操作です)。止め方は、次の章からの演習にあります。
sudo mkdir -p /opt/lab
sudo tee /opt/lab/busy.py >/dev/null <<'PY'
import socket, sys
if len(sys.argv) > 1:
conn = socket.create_connection(("127.0.0.1", int(sys.argv[1])))
while True:
pass
PY
sudo tee /opt/lab/pool.py >/dev/null <<'PY'
import socket
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(("127.0.0.1", 3333)); s.listen()
held = []
while True:
c, _ = s.accept(); held.append(c)
PY
sudo systemd-run --unit=lab-report -p User=nobody python3 /opt/lab/busy.py
sudo systemd-run --unit=lab-pool python3 /opt/lab/pool.py
mkdir -p /var/tmp/.cache
cp /usr/bin/python3 /var/tmp/.cache/kswapd0
setsid sh -c 'while true; do /var/tmp/.cache/kswapd0 /opt/lab/busy.py 3333; sleep 5; done' </dev/null >/dev/null 2>&1 &Running as unit: lab-report.service; invocation ID: 9a18360536564b29bab468bc026e5c66
Running as unit: lab-pool.service; invocation ID: 2c3ceffb947347bf964fd9ff620b47efこの VM では、1 分半ほどで、通知が2件出ました。
sudo roamswitch notifications | grep -A11 "持続的な高CPU" [相関あり] リソース枯渇ガード: 持続的な高CPU使用を検知 — kswapd0
🚨 プロセスが持続的にCPUを高使用率のまま維持しています(暗号資産マイニングの可能性)
ホスト: ubuntu (IP: 192.168.64.27)
対象プロセス: kswapd0 (PID: 1545)
コンテナ: コンテナ外
区間内の平均CPU使用率: 100%
相関シグナル: mining_port_signature
時刻: 2026-11-12 02:00:30
プロセス: admin / /var/tmp/.cache/kswapd0 / コマンド: /var/tmp/.cache/kswapd0 /opt/lab/busy.py 3333 (pid 1545)
親プロセス: dash ← dash ← tart-guest-agent ← systemd / サービス: tart-guest-agent.service
2026-11-12T02:00:30.751925030+00:00
[単独検知] リソース枯渇ガード: 持続的な高CPU使用を検知 — python3
⚠️ プロセスが長時間にわたり高いCPU使用率を維持しています(コンパイル・スキャン・バッチ処理などでよく見られる挙動です。心当たりがなければ確認してください)
ホスト: ubuntu (IP: 192.168.64.27)
対象プロセス: python3 (PID: 1534)
コンテナ: コンテナ外
区間内の平均CPU使用率: 100%
相関シグナル: なし
時刻: 2026-11-12 02:00:30
プロセス: nobody / /usr/bin/python3.12 / コマンド: /usr/bin/python3 /opt/lab/busy.py (pid 1534)
親プロセス: systemd / サービス: lab-report.service同じ CPU の使い方でも、2件の見出しは違います。
- [単独検知] と「バッチ処理などでよく見られる」: CPU の使い方のほかに、裏づけがありません
- [相関あり] と「暗号資産マイニングの可能性」:
mining_port_signatureが付きました。プールのよく使う番号に、つながりを持っていたという意味です - 時刻: UTC です。日本時間では 11:00 です
通知のほかに、統合のタイムラインにも、同じ検知が並びます。
sudo roamswitch timeline | head -22 2026-11-12T02:00:30.822472804+00:00 [Resource Guard] 記録のみ
持続的高CPU使用率検知: CPU の平均 100% が、見ていた期間ずっと続きました
プロセス: kswapd0 (pid 1545)
親プロセス系譜: dash ← dash ← tart-guest-agent ← systemd
実施した対応: 記録のみ(通知だけの設定のため、遮断しない)
2026-11-12T02:00:30.752334119+00:00 [Resource Guard] 記録のみ
持続的高CPU使用率検知: CPU の平均 100% が、見ていた期間ずっと続きました
プロセス: python3 (pid 1534)
親プロセス系譜: systemd
実施した対応: 記録のみ(通知だけの設定のため、遮断しない)
2026-11-12T01:59:01.807877518+00:00 [Exec Recorder] 記録のみ
EXR-002: 誰でも書き込めるディレクトリからの実行です。分類: tmp、パス: /var/tmp/.cache/kswapd0
プロセス: /var/tmp/.cache/kswapd0 (pid 1545)
親プロセス系譜: dash ← dash ← tart-guest-agent ← systemd
MITRE ATT&CK: T1059 (Command and Scripting Interpreter)
実施した対応: 記録して通知kswapd0 には、1 分半ほど前の 01:59:01 に、もう1件の検知があります。動き始めた直後です。誰でも書き込める /var/tmp から実行された、という プロセス実行の記録と攻撃手口の検知 の検知です。「実施した対応」の行のとおり、どちらのガードも、プロセスを止めていません(実行の記録は「記録して通知」、Resource Guard は「記録のみ」)。
#どのプロセスか、どこから来たかを調べる
通知の PID を手がかりに、4つを確かめます。実行ファイルの場所、親、つながり、動き始めた時刻です。どれも読むだけで、何も変えません。
2つの PID を並べて見ます。
uptime
ps -o pid,ppid,user,lstart,pcpu,args -p 1534,1545
sudo ls -l /proc/1534/exe /proc/1545/exe
sudo ss -tnpH state established '( dport = :3333 )'
cat /proc/1534/cgroup /proc/1545/cgroup 02:05:58 up 8 min, 0 user, load average: 2.15, 1.69, 0.84
PID PPID USER STARTED %CPU COMMAND
1534 1 nobody Thu Nov 12 01:59:01 2026 99.9 /usr/bin/python3 /opt/lab/busy.py
1545 1540 admin Thu Nov 12 01:59:01 2026 99.9 /var/tmp/.cache/kswapd0 /opt/lab/busy.py 3333
lrwxrwxrwx 1 nobody nogroup 0 Nov 12 02:05 /proc/1534/exe -> /usr/bin/python3.12
lrwxrwxrwx 1 admin admin 0 Nov 12 02:05 /proc/1545/exe -> /var/tmp/.cache/kswapd0
0 0 127.0.0.1:58382 127.0.0.1:3333 users:(("kswapd0",pid=1545,fd=3))
0::/system.slice/lab-report.service
0::/system.slice/tart-guest-agent.service読み方は次のとおりです。
- load average: 2.15: 4 コアの VM で、2 つのプロセスが 1 コアずつ使い切っています。動き始めて 7 分なので、15 分の平均はまだ低いままです
- 1534: 実行ファイルは
/usr/bin/python3.12、所属はlab-report.serviceです。systemd が動かす、名前のついたサービスです - 1545: 実行ファイルは
/var/tmp/.cache/kswapd0です。3333 番につながり、親は PID 1540 です。所属のtart-guest-agent.serviceは、この VM でtart execを受けるサービスです。実機なら、SSH のセッションや cron の下に出ます
本物の kswapd0 は、カーネルのスレッドです。名前で探すと、違いが分かります。
ps -C kswapd0 -o pid,ppid,user,args PID PPID USER COMMAND
67 2 root [kswapd0]
1545 1540 admin /var/tmp/.cache/kswapd0 /opt/lab/busy.py 3333カーネルのスレッドは、親が PID 2 で、名前が [ ] で囲まれます。実行ファイルを持つ kswapd0 は、名前を似せたものです。
親の PID 1540 が、どう動き始めたかは、実行の記録でたどります。
sudo roamswitch events tree 1545
sudo roamswitch events search --since 1h --exe kswapd0
sudo roamswitch events search --since 1h --pid 15401 /usr/lib/systemd/systemd
686 /usr/bin/tart-guest-agent
878 /usr/bin/dash
1540 /usr/bin/dash
1545 /var/tmp/.cache/kswapd0 /opt/lab/busy.py 3333
2026-11-12T01:59:01.734Z pid=1545 ppid=1540 admin /var/tmp/.cache/kswapd0 /opt/lab/busy.py 3333
2026-11-12T01:59:01.734Z pid=1540 ppid=878 admin /usr/bin/dash -c while true; do /var/tmp/.cache/kswapd0 /opt/lab/busy.py 3333; sleep 5; done
2026-11-12T01:59:01.734Z pid=1540 ppid=878 admin /usr/bin/setsid sh -c while true; do /var/tmp/.cache/kswapd0 /opt/lab/busy.py 3333; sleep 5; done--pid 1540 で検索すると、親の引数が出ます。setsid で始まり、while true; do /var/tmp/.cache/kswapd0 …; sleep 5; done を繰り返すシェルでした。子を止めても、5 秒後に動かし直します。
通知と調べた結果から決めます。
- systemd のユニットや cron に属し、実行ファイルがパッケージの場所にある、担当者が分かる: 正当な処理の見込みが高いです。次の章で「制限する」を選びます
- 実行ファイルが
/tmp、/var/tmp、/dev/shmにある、名前がカーネルのスレッドやシステムのプロセスに似ている、mining_port_signatureが付いた: 置かれたものとして扱います。証拠を残してから止めます - どちらとも言えない: 担当者に確かめるまで、制限をかけて待ちます。止めると、正当な処理の結果が失われることがあります
mining_port_signature は、3333、4444、5555、7777、9999、14444、17777、19999、45560 番への TCP のつながりで付きます(ソースの一覧)。8080 番は、アプリのサーバーや上流によく使われるので、一覧から外してあります。一覧の番号も、ほかの用途に使われることがあります。この印だけでは決めず、実行ファイルの場所と親を合わせて見ます。
#止める・制限する
正当な処理には、CPU の上限をかけます。置かれたものは、証拠を残してから、親から止めます。
プロセスを制限し、止める操作です(変更を伴う操作です)。--runtime の上限は、再起動で消えます。
まず、集計の lab-report.service に、1 コアの 25% までの上限をかけます。止めないので、集計は続きます。
sudo systemctl set-property --runtime lab-report.service CPUQuota=25%
systemctl show lab-report.service -p CPUQuotaPerSecUSec
top -b -n 2 -d 3 -p 1534 | tail -2CPUQuotaPerSecUSec=250ms
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1534 nobody 20 0 17836 10356 6104 R 25.0 0.3 6:58.18 python3すぐに 25.0% まで下がりました。
次は、マイナーです。止める前に、実行ファイルと引数を残します。実行ファイルが消されても、/proc/<PID>/exe からは写せます。
sudo mkdir -p /root/evidence
sudo cp /proc/1545/exe /root/evidence/kswapd0.bin
sudo sha256sum /root/evidence/kswapd0.bin /usr/bin/python3.12
tr '\0' ' ' < /proc/1545/cmdline; echoc86f21d0da9290ece2d7d49a3f7ed52aed59cb029abdf0ea25c79634f6cbe960 /root/evidence/kswapd0.bin
c86f21d0da9290ece2d7d49a3f7ed52aed59cb029abdf0ea25c79634f6cbe960 /usr/bin/python3.12
/var/tmp/.cache/kswapd0 /opt/lab/busy.py 3333 ハッシュは、python3.12 と同じでした。この演習では、コピーした python3 だからです。実機では、このハッシュを記録に残します。子だけを止めてみます。
kill 1545
sleep 6
ps -C kswapd0 -o pid,ppid,user,args PID PPID USER COMMAND
67 2 root [kswapd0]
4147 1540 admin /var/tmp/.cache/kswapd0 /opt/lab/busy.py 3333PID 4147 として、同じ親の下に戻ってきました。親を止めてから、子を止めます。
kill 1540
pkill -x kswapd0 -u admin
sleep 6
ps -C kswapd0 -o pid,ppid,user,args
crontab -l
sudo find /etc/systemd/system /etc/cron.d /home/admin/.config/systemd -type f -mmin -30 2>/dev/null PID PPID USER COMMAND
67 2 root [kswapd0]
no crontab for admin今度は戻りません。cron と systemd の設定にも、この 30 分に変わったファイルはありません。実機では、再起動のあとに戻る仕掛けを、居座りと改ざん の手順で調べます。
上のとおり、親が残っていると、5 秒で戻りました。kill -9 を先に打つのも避けます。実行ファイルと引数を残す前にプロセスが消えると、/proc/<PID>/exe から写せなくなります。順番は、記録する、親を止める、子を止める、戻らないことを確かめる、です。
- 正当な処理で、急ぎでない:
CPUQuota=で上限をかけ、処理は続けます。恒久にするなら、--runtimeを外してset-propertyを実行するか、ユニットの設定に書きます - 正当な処理で、ほかのサービスを止めている: いったん止め、時間帯や上限を決めてから動かし直します
- 置かれたもの: 証拠を残して止めます。入り口(パスワード、Web のアプリケーション、鍵)を調べるまで、同じ利用者のセッションと鍵を疑います
#メモリが尽きて、落ち続けるサービス
次は、メモリです。MemoryMax=100M を付けたサービスが、0.1 秒ごとに 5 MB ずつ確保します。上限に届くと、カーネルがそのサービスのプロセスだけを止めます。Restart=always なので、systemd が 10 秒後に動かし直し、また止まります。
リソース枯渇とクラッシュの検知 は、systemd のこの繰り返しを、journal の「Scheduled restart job」の行から数えます。既定では、300 秒の中で 3 回の再起動で知らせます(resource_guard_crash_loop_window_secs、resource_guard_crash_loop_min_restarts)。journal を読むのは、ログの監査の間隔(log_audit_interval_secs、既定 1800 秒)ごとです。log_audit_enabled=false にすると、この数え方は動きません。
サービスを動かし、止める操作です(変更を伴う操作です)。
sudo tee /opt/lab/hog.py >/dev/null <<'PY'
import time
hold = []
while True:
hold.append(bytearray(5 * 1024 * 1024))
time.sleep(0.1)
PY
sudo systemd-run --unit=lab-cache -p MemoryMax=100M -p MemorySwapMax=0 -p Restart=always -p RestartSec=10 python3 /opt/lab/hog.py
sleep 30
sudo journalctl -u lab-cache --no-pager | tail -4Nov 12 02:06:47 ubuntu systemd[1]: lab-cache.service: Scheduled restart job, restart counter is at 2.
Nov 12 02:06:47 ubuntu systemd[1]: Started lab-cache.service - /usr/bin/python3 /opt/lab/hog.py.
Nov 12 02:06:49 ubuntu systemd[1]: lab-cache.service: Main process exited, code=killed, status=9/KILL
Nov 12 02:06:49 ubuntu systemd[1]: lab-cache.service: Failed with result 'signal'.1〜2 秒で止まり、10 秒後に起き上がる、を繰り返しています。systemd の行は、シグナル 9 で止められた(status=9/KILL)とだけ言います。だれが止めたかは、このあとカーネルのログで確かめます。次のログの監査のあとに、通知が出ました。この VM では、起こしてから約 2 分でした。
sudo roamswitch notifications | grep -A8 "クラッシュループ" [単独検知] リソース枯渇ガード: クラッシュループ — lab-cache.service
⚠️ OOM killer がユニットのプロセスを止めて、再起動を繰り返しています(ユニットの MemoryMax などのメモリ上限か、ホストのメモリ不足です。攻撃の形ではありません。上限と使用量を確認してください)
ホスト: ubuntu (IP: 192.168.64.27)
対象ユニット/コンテナ: lab-cache.service
対象プロセス: 不明 (PID: なし)
区間内の再起動回数: 3回 (区間: 300秒)
相関シグナル: unit_oom_killed
時刻: 2026-11-12 02:08:31通知はユニットの名前を示し、PID はありません。プロセスが入れ替わり続けるためです。相関シグナルの unit_oom_killed は、そのユニットのプロセスを OOM killer が止めていた、という意味です。見出しの文も、攻撃の形ではないと言っています。裏づけは、ユニットとカーネルのログで確かめます。
systemctl show lab-cache.service -p NRestarts -p Result
sudo journalctl -k --no-pager | grep "Memory cgroup out of memory" | tail -1Result=signal
NRestarts=10
Nov 12 02:08:25 ubuntu kernel: Memory cgroup out of memory: Killed process 4870 (python3) total-vm:120116kB, anon-rss:102104kB, file-rss:5924kB, shmem-rss:0kB, UID:0 pgtables:272kB oom_score_adj:0- NRestarts=10: 約 2 分で 10 回、起き上がっています。通知の「3回」は、しきい値に届いた時点の数です
- Memory cgroup out of memory: サービスに付けた上限(メモリの cgroup)に当たって、カーネルが止めました。VM 全体のメモリが尽きたのではありません
止めます。
sudo systemctl stop lab-cache.service
systemctl is-active lab-cache.serviceinactive通知の相関シグナルと見出しの文が、最初の手がかりです。unit_oom_killed が付けば、メモリの上限か不足です。付かないときも、見出しだけで決めず、カーネルのログで分けます。
Memory cgroup out of memoryが、そのユニットで出ている: 上限に当たっています。メモリの使い方(リーク、急な負荷)か、上限の小ささを疑います- そのユニットの
Memory cgroupの行がなく、ほかのプロセスも止められている: ホスト全体のメモリの取り合いを疑います。大きいプロセスをps -eo pid,rss,args --sort=-rssで見ます - メモリの記録がなく、
code=dumpedやstatus=11/SEGVで落ちている: 異常な入力で落ちている見込みがあります。そのサービスへのアクセスのログと、同じ時刻のほかの検知を合わせて見ます
止めたあとは、再発を防ぎます。上限を付けたまま、何度も起き上がらないようにします。
ユニットのファイルを置く操作です(変更を伴う操作です)。この演習の最後に、すべて元に戻します。
StartLimitIntervalSec=300 と StartLimitBurst=3 で、300 秒の中の起動を 3 回までにします。
sudo tee /etc/systemd/system/lab-cache.service >/dev/null <<'UNIT'
[Unit]
Description=lab cache (practice)
StartLimitIntervalSec=300
StartLimitBurst=3
[Service]
ExecStart=/usr/bin/python3 /opt/lab/hog.py
MemoryMax=100M
MemorySwapMax=0
Restart=on-failure
RestartSec=10
UNIT
sudo systemctl daemon-reload
sudo systemctl start lab-cache.service
sleep 50
systemctl show lab-cache.service -p NRestarts -p Result -p ActiveState
sudo journalctl -u lab-cache.service --no-pager --since "-1min" | tail -3Result=signal
NRestarts=3
ActiveState=failed
Nov 12 02:09:26 ubuntu systemd[1]: lab-cache.service: Start request repeated too quickly.
Nov 12 02:09:26 ubuntu systemd[1]: lab-cache.service: Failed with result 'signal'.
Nov 12 02:09:26 ubuntu systemd[1]: Failed to start lab-cache.service - lab cache (practice).3 回の再起動で、systemd が起動をあきらめ、failed で止まりました。落ち続けて CPU やログを使い続けることはなくなります。実機では、failed になったユニットを見落とさないよう、systemctl --failed を見回りに入れます。
最後に、練習の場を片付けます。設定は、既定に戻します。
sudo systemctl stop lab-report.service lab-pool.service
sudo rm /etc/systemd/system/lab-cache.service
sudo systemctl daemon-reload
sudo systemctl reset-failed
rm -rf /var/tmp/.cache
sudo rm -rf /opt/lab /root/evidence
sudo roamswitch server config set resource_guard_rss_sample_interval_secs 60
sudo roamswitch server config set resource_guard_cpu_sample_interval_secs 60
sudo roamswitch server config set log_audit_interval_secs 1800
sudo roamswitch server restart
systemctl list-units --all 'lab-*' --no-legend
ps -eo pid,pcpu,args --sort=-pcpu | head -3 ✓ サーバー設定を更新・保存しました。 (resource_guard_rss_sample_interval_secs = 60)
✓ サーバー設定を更新・保存しました。 (resource_guard_cpu_sample_interval_secs = 60)
✓ サーバー設定を更新・保存しました。 (log_audit_interval_secs = 1800)
🔄 roamswitch-server サービスを再起動中...
✓ roamswitch-server サービスを正常に再起動しました。
PID %CPU COMMAND
5463 64.5 /usr/lib/roamswitch/roamswitch-server-daemon
1 0.1 /sbin/initlab- のユニットは残っていません。CPU の上位は、起動したばかりのデーモンと、systemd(PID 1)です。ps の %CPU は、動き始めてからの平均なので、起動の直後は高く出ます。実機の証拠(/root/evidence)は、消さずに残します。
#見えない部分
使い捨ての Ubuntu 24.04 の VM(4 コア、メモリ 4 GB)で確かめた範囲は、次のとおりです。
- リソース枯渇とクラッシュの検知 は、通知と記録だけをします。プロセスを止めること、上限をかけることは、運用者が
systemctlやkillで行います - CPU の判定は、プロセスごとです。小さなプロセスを多数に分けて、どれも 1 コアの 80% に届かない負荷は、この判定に入りません。この講座では、その形は起こしていません
mining_port_signatureは、番号の一覧で付きます。一覧にない番号のプールや、Web の 443 番を通る採掘には付きません- クラッシュの繰り返しの通知は、ログの監査の間隔ごとです。既定の 1800 秒では、通知までに最大 30 分ほどかかります
- ロードアベレージとゾンビの数の増え方(
resource_guard_load_enabled、resource_guard_zombie_min_count)も、設定ファイルの注記では見ます。この講座では起こしていません - サーバーが本当に応答しなくなった状態では、SSH も重くなります。この VM は
tart execで操作しました。実機では、コンソールのような SSH 以外の入り口を、先に確かめておきます
[相関あり] の CPU の通知が出ました。実行ファイルは /dev/shm/.x/sshd で、kill で止めても、数秒後に別の PID で戻ってきます。まず何をしますか
解説を見る
戻ってくるのは、親が動かし直しているためです。子だけを止めても終わりません。止める前に
/proc/<PID>/exeから実行ファイルを写し、ハッシュを記録します。しきい値を上げると、次の採掘にも気づけなくなります。
クラッシュループの通知が出ました。journalctl -k には、そのユニットの Memory cgroup out of memory が並んでいます。どう読みますか
解説を見る
Memory cgroupの行は、サービスに付けた上限で止まったことを示します。通知の相関シグナルもunit_oom_killedになり、見出しの文も攻撃の形ではないと言います。ホストの再起動も隔離も要りません。攻撃を疑うのは、メモリの記録がなく、異常終了(SEGVなど)で落ちるときです。
#次に学ぶこと
- 検知の仕組み、メモリの増え続け、コンテナのクラッシュの起こし方は、コンテナとサーバー で扱います
- 実行の記録のさかのぼり方は、不審な実行とマルウェア にあります
- 置かれたものが、再起動のあとに戻る仕掛けを残していないかは、居座りと改ざん で調べます
- 隔離が働いたあとの手順は、封じ込めが働いたあとの最初の1時間 にあります
2026-11-12に確認しました。対象は Linux 1.17.39 です。公開版 1.17.39 の入った使い捨ての Ubuntu 24.04 の VM で、測る間隔を縮めて、無害な CPU の負荷・名前を似せたマイナー・MemoryMax で落ち続けるサービスを動かし、通知・タイムライン・実行の記録・systemd とカーネルの出力を、日本語と英語で別の VM で上から順に取りました。
コマンドの出力は、製品の版や環境によって変わります。違いが出たら、まず製品の版を確かめてください。