こんにちは!インシデントレスポンスの現場を渡り歩いているSOCアナリストです。
皆さんは、普段のアプリ開発やインフラ管理でDockerやKubernetesといった「コンテナ技術」をバリバリ使っていらっしゃいますよね。「動かすのが簡単」「環境をすぐ綺麗に作り直せる」というあの軽快さは、一度味わうと本当に手放せなくなります。
でも、セキュリティの現場にいる人間からすると、この「すぐ消える・新しくなる」というコンテナの特性は、時に事件現場の証拠がすべて跡形もなく消え去る悪夢のような側面を持っています。
今回は、コンテナ環境特有のフォレンジック(デジタル鑑識)の難しさと、現場で私たちがどうやって証拠をかき集めているのか、身近な例えを交えながら優しく紐解いていきたいと思います。一歩ずつ、一緒に学んでいきましょう!
—
1. コンテナ環境は「使い捨てのホテル」? 証拠が残らない理由
まず、コンテナがなぜフォレンジック泣かせなのか、身近な例えでお話ししますね。
従来の「仮想マシン(VM)」や物理サーバーは、例えるなら「自分の持ち家」のようなものです。部屋の壁に落書きされたり、床に足跡が残ったりすれば、警察(フォレンジック調査員)がやってきて、指紋を採ったり防犯カメラを確認したりできますよね。
一方、DockerやKubernetesなどのコンテナ環境は、さしずめ「1泊数千円のビジネスホテル」です。
宿泊客(コンテナ)がチェックアウトすると、清掃員が部屋を丸ごとリセットし、何事もなかったかのように次の客を迎えます。もし部屋の中で悪事を働いた客がいても、チェックアウトした瞬間に部屋ごとキレイさっぱり初期化されてしまうのです。
攻撃者がコンテナを踏み台にして不正なプログラムを実行し、その後コンテナを終了(停止)させてしまったらどうなるでしょうか? そう、「事件の痕跡(メモリ上の怪しいプロセスや、一時ファイル)が、消去されたホテルと一緒に消えてしまう」のです。これが、コンテナフォレンジックの最大の壁になります。
—
2. コンテナの「今」を切り取る! メモリと一時ファイルの保全
では、怪しい動きをしているコンテナを見つけたとき、私たちはどうやってその「瞬間」を捉えればよいのでしょうか。証拠が消えてしまう前に、コンテナの「メモリ(脳みそ)」と「一時ファイル(机の上のメモ)」をガッチリ保全するテクニックを見ていきましょう。
一般的なLinuxサーバーであれば dd コマンドや専用ツールでメモリダンプを取得しますが、コンテナの世界ではホストOSとリソースを共有しているため、アプローチが少し異なります。
ステップ1:コンテナが消える前にプロセスを覗き見する
コンテナがまだ生きているなら、ホストOS側からその息吹を感じ取ることができます。例えば、ホスト側からコンテナ内のプロセスを確認するには、コンテナのランタイムや nsenter というコマンドを使って、コンテナの空間に入り込みます。
以下のコマンド例を見てみてください。
# 【解説】ホストOSから、特定のコンテナ(ここではコンテナIDを指定)のプロセス名前空間に入り込み、
# 実行中の不審なプロセスを一覧で覗き見するためのコマンドです。
# まさに、チェックアウト直前のホテルの部屋にこっそり合鍵で入るようなイメージですね。
# 1. 調べたいコンテナのプロセスID(PID)をホスト側から探す
CONTAINER_ID="1234567890ab"
HOST_PID=$(docker inspect --format '{{.State.Pid}}' $CONTAINER_ID)
# 2. そのプロセス名前空間にアタッチして、実行中のプロセスを確認する
nsenter --target $HOST_PID --mount --uts --ipc --net --pid ps aux
もしここで、動くはずのない不審なプログラム(例えば、暗号資産のマイニングツールや、見覚えのない通信ツール)が動いていたとしたら、それが決定的な証拠になります。
ステップ2:コンテナの「ファイルシステム差分」を保存する
コンテナは、基本のイメージファイルの上に「変更された差分レイヤー」を重ねて動いています。コンテナを強制終了させてしまうとこの差分が消えるため、まずは「止めるな、逃がすな(停止させずに状態を保存しろ)」が鉄則です。
現在動いている状態を、そのまま新しいイメージとしてローカルに保存(コミット)してしまいましょう。
# 【解説】不審な動きをしているコンテナの「今この瞬間」のファイルシステムの差分を、
# 新しいDockerイメージとして切り出します。
# これにより、あとからじっくりと「机の上のメモ(不正なファイル)」を解析できるようになります。
docker commit -p 1234567890ab suspect_container_forensic_copy:20231105
-p オプションをつけることで、コンテナを一時停止(ポーズ)させてから安全にスナップショットを撮ることができます。これで証拠隠滅の時間をあたえずにホテルの部屋ごと保存完了です!
—
3. Kubernetes環境でのフォレンジックの現実
Docker単体ならまだしも、これが何百個ものコンテナが複雑に連携するKubernetes(K8s)環境になると、難易度は跳ね上がります。K8sでは、Podが自動的に別のノードに再作成されたり(K8sの自己修復機能)、オートスケーリングで消えたりするためです。
ここでインシデントレスポンスのプロが現場で行うベストプラクティスをいくつかご紹介します。
① ログの外部転送(セントラルロギング)の徹底
コンテナ内の /var/log や標準出力(Stdout)に吐き出されたログは、コンテナが消えると同時に消えます。ですから、「コンテナが死んでも、ログだけは安全な金庫にリアルタイムで転送されている状態」を作ることが最大の防御であり、フォレンジックの生命線です。
FluentdやElasticsearch、あるいはクラウドのログサービス(CloudWatch LogsやStackdriverなど)へ確実に流し込んでおきましょう。
② フォレンジック用Podの隔離(Network Policy)
もしKubernetes上の特定のPod(アプリ)が乗っ取られた疑いがある場合、慌ててそのPodを削除してはいけません! 削除すると証拠が消えます。
代わりに、Network Policyを使ってそのPodを外部のネットワークから完全に隔離(サンドボックス化)し、通信を遮断した状態でメモリやディスクの保全を行います。
# 【解説】Kubernetesで怪しい挙動を示すPodへのトラフィックを完全に遮断し、
# さらなる攻撃(横展開やデータ持ち出し)を防ぎつつ、安全にフォレンジック調査を行うためのNetworkPolicyの例です。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: isolate-compromised-pod
namespace: default
spec:
podSelector:
matchLabels:
app: vulnerable-web-app # 侵害が疑われるアプリのラベル
policyTypes:
- Ingress
- Egress
# Ingress(受信)も Egress(送信)もルールを空にすることで、すべての通信をブロックします
ingress: []
egress: []
このように、ネットワークの水道の蛇口をピタッと締めてから、じっくりと鑑識作業に入るのがプロの技です。
—
まとめ:コンテナ時代の防犯は「事前の備え」が9割
今回は、コンテナ環境におけるフォレンジックの難しさと、現場での泥臭い保全テクニックについてお話ししました。
コンテナは使い捨てで儚い存在だからこそ、
1. 「怪しいと思ったら、まずはコンテナを消さずにコミット(スナップショット)する」
2. 「ログは常に外の金庫へ逃がしておく」
3. 「隔離してじっくり調べる(Network Policyの活用)」
という心構えと備えが何よりも大切になります。
最初は難しく感じるかもしれませんが、実務の引き出しを少しずつ増やしていけば、どんなに足抜けの上手な侵入者でもしっかり尻尾を掴めるようになりますよ。
それでは、また次回のセキュリティ解説でお会いしましょう!安全なインフラライフを!
コメント