今回は、「並列解析」の実装に入ります。
私のラボには、今後解析しなければならない検体が多く控えています。 これをデフォルトの「1VM」で回すと、1件2分としても約277日かかります。現実的ではありません。
そこで、ホストマシンのリソースを最大限活用し、5並列で同時解析を行う環境を構築しました。その全手順をまとめます。
環境
- CPU: Intel Core i7-13700K (16C/24T)
- RAM: 32GB
- Storage: * System/VMs: 1TB NVMe SSD
- Analysis Logs: 18TB HDD
- Target: Windows 10 x64
単純にVMをコピーするとディスク容量(NVMe)が多いため、リンククローンを使用します。これはベースとなるイメージを共有し、差分だけを各VMで持つ方式で、ディスク消費を抑えられます。
手順1:VMの複製(ホスト側)
1台ずつGUIで作るのは非効率なので、スクリプトで一気に生成します。
ベースとなるVM(win10)から、win10_2 〜 win10_5 までの5台を複製します。
以下のスクリプトを作成し、実行しました。
#!/bin/bash
export LIBVIRT_DEFAULT_URI=qemu:///system
# 環境に合わせてパスを指定
BASE_IMAGE="/var/lib/libvirt/images/win10.qcow2"
IMAGE_DIR="/var/lib/libvirt/images"
BASE_VM="win10"
# テンプレート作成
virsh dumpxml $BASE_VM > template.xml
echo "リンククローン作成開始..."
for i in {2..5}; do
NEW_VM="win10_$i"
NEW_DISK="$IMAGE_DIR/$NEW_VM.qcow2"
echo "Creating $NEW_VM ..."
# リンククローン作成 (qcow2の差分機能を利用)
qemu-img create -f qcow2 -F qcow2 -b "$BASE_IMAGE" "$NEW_DISK"
# 定義ファイルの作成と登録
cat template.xml | \
sed "s|<name>$BASE_VM</name>|<name>$NEW_VM</name>|g" | \
sed "s|<uuid>.*</uuid>||g" | \
sed "s|<mac address=.*/>||g" | \
sed "s|$BASE_IMAGE|$NEW_DISK|g" > "$NEW_VM.xml"
virsh define "$NEW_VM.xml"
rm "$NEW_VM.xml"
done
rm template.xml
echo "完了"
手順2:ゲストOSのネットワーク設定
ここだけは手作業が必要です。複製した各VMを起動し、固定IPを割り当てます。
合わせて、解析エージェント(agent.py)が起動した状態でスナップショットを取得します。
| VM Name | IP Address | Gateway | DNS | Snapshot Name |
|---|---|---|---|---|
| win10 | 192.168.55.2 | 192.168.55.1 | 8.8.8.8 | cape_snapshot1 |
| win10_2 | 192.168.55.3 | 共通 | 共通 | cape_snapshot1 |
| win10_3 | 192.168.55.4 | 共通 | 共通 | cape_snapshot1 |
| … | … | … | … | … |
| win10_5 | 192.168.55.6 | 共通 | 共通 | cape_snapshot1 |
スナップショットはVM起動中にホスト側からコマンドで取得するかGUIで取得します。
# 例: win10_2 の場合
virsh -c qemu:///system snapshot-create-as --domain win10_2 --name cape_snapshot1
※これを全台分繰り返します。
手順3:CAPE設定ファイルの修正
/opt/CAPEv2/conf/ 配下の設定ファイルをチューニングします。
cuckoo.conf (パフォーマンス設定)
メモリ32GB環境で安定稼働させるため、同時解析数を制限します。
[cuckoo]
# 並列数を5に設定
max_machines_count = 5
[resultserver]
# 同時接続リクエストを捌けるようにプールサイズを拡張
pool_size = 32
[timeouts]
# 解析時間を短縮 (デフォルト長すぎる場合は短縮)
default = 120
kvm.conf (VM登録)
作成したVMをCAPEに認識させます。
[kvm]
# 全VMをリストに追加
machines = win10,win10_2,win10_3,win10_4,win10_5
interface = virbr1
# --- ベースVM (既存) ---
[win10]
label = win10
platform = windows
ip = 192.168.55.2
snapshot = cape_snapshot1
# ...他設定
# --- 追加VM (例: win10_2) ---
[win10_2]
label = win10_2
platform = windows
ip = 192.168.55.3 # IPをずらす
snapshot = cape_snapshot1
interface = virbr1
resultserver_ip = 192.168.55.1
arch = x64
# ... win10_3 〜 win10_5 も同様にIPを変えて記述
手順4:ストレージの大容量化 (Bind Mount)
20万件の解析ログは数TBクラスになるため、NVMeには入りきりません。 前回の記事で解説した通り、Bind Mountを利用して18TB HDDにデータを逃がします。
※詳細は【CAPEv2】解析データをSSDからHDDへ逃がすを参照。
これで、どれだけ解析してもSSDの容量を圧迫することはありません。
手順5:稼働テスト
設定を反映させ、並列処理をテストします。
sudo systemctl restart cape
sudo systemctl restart cape-processor
WebUIからサンプル検体を10個ほど投入し、htop で負荷を確認します。
すべてのCPUコアが稼働し、virt-manager 上で5台のWindowsが同時に Runningになれば構築完了です。
本当はもっと多くのVMを用意して並列数を増やしたかったのですが、安定性を考えると5台で落ち着きました。