一覧SP-17-1 · CWPP:ワークロードの保護

コンテナイメージと実行環境の識別

イメージ、動いている実体、ファイルとログの保存場所を対応付けて確認します。

説明

CWPPはコンテナや仮想マシンなどのワークロードを保護します。配布するイメージと、そこから作られた実行中の実体では、識別子も検査する状態も異なります。

Alpineの固定イメージからコンテナを起動し、イメージID、プロセス、マウント、実行状態をDockerコマンドで調べます。同じターミナルの履歴に値を残して照合します。

イメージ、動いている実体、ファイルとログの保存場所を対応付けて確認します。

1固定イメージからコンテナを作成する

sha256でイメージを固定し、ネットワークなし、ルート領域は読取り専用として起動します。

docker run -d --name lbox-workload-sample --network none --read-only固定イメージからコンテナを作成する --tmpfs /tmp:rw,noexec,nosuid,size=1m sha256:5291449c3df73caf6ed85e649dec1b9e818b39a5d8c871e97afc13e9cd5e8fa8 sh -c 'echo public-start; sleep 600'

返った長い値は新しいコンテナIDです。作成元のイメージIDとは別の値で、実行単位を識別します。

2作成元のイメージIDを読む

inspectでコンテナが参照するImageを取得します。

docker inspect --format '{{.Image}}作成元のイメージIDを読む' lbox-workload-sample

起動時に指定したsha256と一致します。タグ名だけでは指す内容が後で変わる場合があるため、調査時点の内容を特定する値を残します。

3実行時の保護設定を読む

ルート領域とネットワークの設定を同時に取得します。

docker inspect --format '{{.HostConfig.ReadonlyRootfs}}実行時の保護設定を読む {{.HostConfig.NetworkMode}}' lbox-workload-sample

true noneです。イメージの内容だけでは、この起動時設定までは分かりません。配備時の条件も保護の確認対象です。

4コンテナ内のプロセスを確認する

/proc/1/statusから名前、PID、UIDを取得します。

docker exec lbox-workload-sample sh -c 'sed -n "/^Name:/p;/^Pid:/p;/^Uid:/p" /proc/1/statusコンテナ内のプロセスを確認する'

sleepがPID 1、UIDは0です。これはコンテナ内のPIDです。ホスト側のPIDやクラウドのサービスIDとは別の識別情報として扱います。

5書込み可能な領域の例外を読む

/tmpのマウント設定を表示します。

docker inspect --format '{{json .HostConfig.Tmpfs}}書込み可能な領域の例外を読む' lbox-workload-sample

ルートが読取り専用でも/tmpはrwです。noexecとnosuidも指定され、容量上限は1 MiBです。マウントごとの例外まで調べます。

6稼働状態を確認する

現在のRunningを取得します。

docker inspect --format '{{.State.Running}}稼働状態を確認する' lbox-workload-sample

trueです。設定が存在することと、対象プロセスが動いていることを別々に確認できます。

7停止後の状態を読み直す

停止要求の後で再度Runningを取得します。

docker stop停止後の状態を読み直す -t 1 lbox-workload-sample docker inspect --format '{{.State.Running}}' lbox-workload-sample

falseになりました。作成元のイメージは残っていても、このコンテナの実行は終了しています。

まとめ

イメージIDとコンテナIDを分けて記録します。

プロセス・マウント・起動設定を実行中の実体へ対応付けます。

停止要求の後で実際の稼働状態を確認します。

操作履歴と解説を振り返れます。

Docker / Alpine 3.22 / ネットワークなし・読取り専用コンテナ

1
docker run -d --name lbox-workload-sample --network none --read-only --tmpfs /tmp:rw,noexec,nosuid,size=1m sha256:5291449c3df73caf6ed85e649dec1b9e818b39a5d8c871e97afc13e9cd5e8fa8 sh -c 'echo public-start; sleep 600'
4fd7ebca9e348cc46305883c93e978d8bdd1b07963405fcd4720c3f7a3953d7d
2
docker inspect --format '{{.Image}}' lbox-workload-sample
sha256:5291449c3df73caf6ed85e649dec1b9e818b39a5d8c871e97afc13e9cd5e8fa8
3
docker inspect --format '{{.HostConfig.ReadonlyRootfs}} {{.HostConfig.NetworkMode}}' lbox-workload-sample
true none
4
docker exec lbox-workload-sample sh -c 'sed -n "/^Name:/p;/^Pid:/p;/^Uid:/p" /proc/1/status'
Name:	sleep
Pid:	1
Uid:	0	0	0	0
5
docker inspect --format '{{json .HostConfig.Tmpfs}}' lbox-workload-sample
{"/tmp":"rw,noexec,nosuid,size=1m"}
6
docker inspect --format '{{.State.Running}}' lbox-workload-sample
true
7
docker stop -t 1 lbox-workload-sample docker inspect --format '{{.State.Running}}' lbox-workload-sample
lbox-workload-sample
false

演習完了