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

コンテナの書き込みと実行の制限

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

説明

ワークロードの実行時保護では、書き込める場所と、そこから実行できる処理を確認します。設定名だけで保護範囲を判断せず、対象の操作と結果を照合します。

読取り専用のルートと書込み可能なtmpfsを持つコンテナを起動します。公開文字列だけを使い、書込み拒否、ハッシュ、直接実行の拒否とインタープリター経由の違いを確かめます。

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

1このページの検証用コンテナを起動する

/tmpにはrw,noexec,nosuidを指定します。

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'

ルート領域とは別の条件で/tmpを扱う構成です。これから同じ実体に対して操作します。

2ルート領域への書込みを試す

/lesson-deniedへ公開文字列を書こうとします。

docker exec lbox-workload-sample sh -c 'printf public > /lesson-deniedルート領域への書込みを試す'

Read-only file systemで拒否されます。この拒否はファイルシステムの読取り専用設定によるものです。

3一時領域へ同じ文字列を書き込む

/tmp/lesson-publicを作成し、内容を読みます。

docker exec lbox-workload-sample sh -c 'printf public > /tmp/lesson-public一時領域へ同じ文字列を書き込む; cat /tmp/lesson-public; echo'

publicが表示されます。ルートへの書込み拒否から、コンテナ内の全書込みが禁止されたとは言えません。

4書き込んだ内容のハッシュを取得する

sha256sumで実際のファイルを読みます。

docker exec lbox-workload-sample sh -c 'sha256sum書き込んだ内容のハッシュを取得する /tmp/lesson-public'

これは6バイトのpublicに対応するハッシュです。検知されたパス名だけでなく、内容の同一性を確認する値として使えます。

5一時領域のスクリプトを直接実行する

publicを表示するだけのスクリプトを置き、実行属性を付けて起動します。

docker exec lbox-workload-sample sh -c 'printf "#!/bin/sh\nprintf public\n" > /tmp/hello; chmod 700一時領域のスクリプトを直接実行する /tmp/hello; /tmp/hello'

Permission deniedです。実行属性があってもnoexecのマウントから直接実行できません。

6インタープリターがファイルを読む場合を確認する

shへスクリプトのパスを渡します。

docker exec lbox-workload-sample sh -c 'sh /tmp/helloインタープリターがファイルを読む場合を確認する; echo'

publicが表示されます。noexecは読み取り自体を禁止する設定ではなく、既存のインタープリターが内容を読む経路まで一律に止めるものではありません。

7拒否したパスと許可したファイルを読み直す

ルート側が作られていないことと、一時ファイルの属性を確認します。

docker exec lbox-workload-sample sh -c 'test ! -e拒否したパスと許可したファイルを読み直す /lesson-denied && printf "root unchanged\n"; stat -c "%A %U %G %s" /tmp/lesson-public'

root unchanged、権限-rw-r--r--、所有者root、6バイトです。拒否ログだけでなく、対象の保存状態も確認できました。

まとめ

書込み可能範囲はマウントごとに確認します。

直接実行とインタープリターによる読み取りは異なります。

操作結果をファイルの存在・属性・ハッシュで照合します。

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

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'
baf05bed70748b85f2709f04224577680b01330feb18fed6610cab508219a6d2
2
docker exec lbox-workload-sample sh -c 'printf public > /lesson-denied'
sh: can't create /lesson-denied: Read-only file system
3
docker exec lbox-workload-sample sh -c 'printf public > /tmp/lesson-public; cat /tmp/lesson-public; echo'
public
4
docker exec lbox-workload-sample sh -c 'sha256sum /tmp/lesson-public'
efa1f375d76194fa51a3556a97e641e61685f914d446979da50a551a4333ffd7  /tmp/lesson-public
5
docker exec lbox-workload-sample sh -c 'printf "#!/bin/sh\nprintf public\n" > /tmp/hello; chmod 700 /tmp/hello; /tmp/hello'
sh: /tmp/hello: Permission denied
6
docker exec lbox-workload-sample sh -c 'sh /tmp/hello; echo'
public
7
docker exec lbox-workload-sample sh -c 'test ! -e /lesson-denied && printf "root unchanged\n"; stat -c "%A %U %G %s" /tmp/lesson-public'
root unchanged
-rw-r--r-- root root 6

演習完了