2.17. Linux ユーザー名前空間での Pod の実行
Linux ユーザー名前空間を使用すると、管理者はコンテナーのユーザーおよびグループ識別子 (UID および GID) を分離できるため、実行されているホストシステムとは異なる権限セットを、ユーザー名前空間でコンテナーに付与できます。これにより、ユーザー名前空間内で完全な権限を使用してプロセスを実行することをコンテナーに許可する一方で、ホストマシンに対する操作の権限をプロセスに与えないことが可能になります。
デフォルトでは、コンテナーはホストユーザー名前空間で実行されます。コンテナーをホストのユーザー名前空間で実行することは、そのユーザー名前空間でのみ使用可能な機能がコンテナーに必要な場合に便利です。しかし、ホストの名前空間で Pod を実行すると、コンテナーブレイクアウトの可能性など、セキュリティー上の懸念が生じます。コンテナーブレイクアウトが発生すると、別のコンテナー内のプロセスがホスト上に脱出し、そのプロセスがホスト上またはコンテナー内のファイルにアクセスしたり、ファイルを変更したりできるようになります。
個々のユーザー名前空間でコンテナーを実行すると、コンテナーブレイクアウトや、侵害されたコンテナーから他の Pod やノード自体に及ぶ可能性のあるその他のいくつかの脆弱性を軽減できます。
2.17.1. Linux ユーザー名前空間のサポートの設定 リンクのコピーリンクがクリップボードにコピーされました!
Linux ユーザー名前空間を設定するには、次の手順に示すように、Pod 仕様で hostUsers
パラメーターを false
に設定し、その他のいくつかの設定を行います。
ユーザー名前空間でワークロードを実行すると、fsGroup
、runAsGroup
、runAsUser
、supplementalGroups
などの Security Context Constraints (SCC) フィールドに、RunAsAny
を安全に設定できるようになります。これは、コンテナー外部の UID や GID が、これらのフィールドが表すコンテナー内部の UID や GID と異なるためです。
セキュリティーを強化するために、restricted-v3
または nested-container
SCC を使用できます。これらは、Linux ユーザー名前空間内のワークロード向けに特別に設計されたものです。SCC に userNamespaceLevel: RequirePodLevel
フィールドを設定すると、ワークロードが必ずユーザー名前空間で実行されます。SCC の詳細は、「Security Context Constraints の管理」を参照してください。
ワークロードに対して特定の SCC を必須とするには、oc adm policy add-scc-to-user
コマンドまたは oc adm policy add-scc-to-group
コマンドを使用して、特定のユーザーまたはグループに SCC を追加できます。詳細は、「OpenShift CLI 管理者コマンドリファレンス」を参照してください。
また、必要に応じて、Pod 仕様の procMount
パラメーターを使用して、Pod 内の /proc
ファイルシステムを unmasked
に設定することもできます。/proc
を unmasked
に設定することは、一般的に安全であると考えられていますが、設定すると、コンテナーランタイムのデフォルトのマスキング動作が無視されます。そのため、この設定は、hostUsers
を false
に設定する SCC と必ず組み合わせて使用してください。
手順
次のコマンドを実行して、Pod がデプロイされている OpenShift Container Platform の namespace のデフォルトユーザー ID (UID) およびグループ ID (GID) の範囲を編集します。
oc edit ns/<namespace_name>
$ oc edit ns/<namespace_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow namespace の例
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注記範囲 1000/10000 は、ID 1000 から始まる 10,000 個の値を意味するため、1000 から 10,999 までの範囲の ID を指定します。
適切な SCC を使用して動作するように設定したワークロードを作成し、
hostUsers
パラメーターをfalse
に設定して、Linux ユーザー名前空間の使用を有効にします。以下のような YAML ファイルを作成します。
Pod 仕様の例
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- このワークロードで使用する SCC を指定します。
- 2
- Pod をユーザー名前空間で実行するかどうかを指定します。
false
の場合、Pod は Pod 用に作成した新しいユーザー名前空間で実行されます。true
の場合、Pod はホストのユーザー名前空間で実行されます。デフォルトはtrue
です。 - 3
capabilities
は、完全な root アクセス権を与えることなく特権操作を許可します。技術的に言えば、ユーザー名前空間の中でケイパビリティーを設定する方が、ユーザー名前空間の外で設定するよりも安全です。ケイパビリティーのスコープがユーザー名前空間の内部にあることで制限され、一般的に安全であると考えられるためです。しかし、信頼できないワークロードにCAP_SYS_ADMIN
などの Pod ケイパビリティーを付与すると、コンテナー化されたプロセスがアクセスできる潜在的なカーネルの攻撃対象領域が広がり、悪用可能な脆弱性が発見されるおそれがあります。したがって、ユーザー名前空間内のケイパビリティーは、Pod セキュリティーアドミッションではbaseline
レベルで許可されます。- 4
- コンテナー内のプロセスを 0 以外の UID を持つユーザーで実行することを指定します。
- 5
- オプション: コンテナーに使用する proc マウントのタイプを指定します。
unmasked
値を設定すると、コンテナーの/proc
ファイルシステムが、コンテナーのプロセスによって読み取り/書き込み可能な状態でマウントされます。デフォルトはDefault
です。 - 6
- コンテナー内で実行されるプロセスのユーザー ID を指定します。これは、
namespace
オブジェクトで設定した範囲内に収まっている必要があります。 - 7
- コンテナー内で実行されるプロセスのグループ ID を指定します。これは、
namespace
オブジェクトで設定した範囲内に収まっている必要があります。
以下のコマンドを実行してオブジェクトを作成します。
oc create -f <file_name>.yaml
$ oc create -f <file_name>.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
検証
作成した Pod 内のコンテナーで使用されているユーザー ID とグループ ID を確認します。Pod は Linux ユーザー名前空間内にあります。
Pod 内のコンテナーでシェルセッションを開始します。
oc rsh -c <container_name> pod/<pod_name>
$ oc rsh -c <container_name> pod/<pod_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow コマンドの例
oc rsh -c userns-container_name pod/userns-pod
$ oc rsh -c userns-container_name pod/userns-pod
Copy to Clipboard Copied! Toggle word wrap Toggle overflow コンテナー内で使用されているユーザー ID とグループ ID を表示します。
id
sh-5.1$ id
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 出力例
uid=1000(1000) gid=1000(1000) groups=1000(1000)
uid=1000(1000) gid=1000(1000) groups=1000(1000)
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- コンテナーの UID とグループは、Pod 仕様で設定したものと同じである必要があります。
コンテナーのユーザー名前空間で使用されているユーザー ID を表示します。
lsns -t user
sh-5.1$ lsns -t user
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 出力例
NS TYPE NPROCS PID USER COMMAND 4026532447 user 3 1 1000 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1000
NS TYPE NPROCS PID USER COMMAND 4026532447 user 3 1 1000 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1000
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- プロセスの UID は、Pod 仕様で設定したものと同じである必要があります。
ノードによって使用されている UID を確認します。ノードは Linux ユーザー名前空間の外部にあります。このユーザー ID がコンテナーで使用されている UID と異なっている必要があります。
そのノードのデバッグセッションを開始します。
oc debug node/ci-ln-z5vppzb-72292-8zp2b-worker-c-q8sh9
$ oc debug node/ci-ln-z5vppzb-72292-8zp2b-worker-c-q8sh9
Copy to Clipboard Copied! Toggle word wrap Toggle overflow コマンドの例
oc debug node/ci-ln-z5vppzb-72292-8zp2b-worker-c-q8sh9
$ oc debug node/ci-ln-z5vppzb-72292-8zp2b-worker-c-q8sh9
Copy to Clipboard Copied! Toggle word wrap Toggle overflow /host
をデバッグシェル内のルートディレクトリーとして設定します。chroot /host
sh-5.1# chroot /host
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ノードによって使用されている UID を表示します。
lsns -t user
sh-5.1# lsns -t user
Copy to Clipboard Copied! Toggle word wrap Toggle overflow コマンドの例
NS TYPE NPROCS PID USER COMMAND 4026531837 user 233 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 28 4026532447 user 1 4767 2908816384 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1000
NS TYPE NPROCS PID USER COMMAND 4026531837 user 233 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 28 4026532447 user 1 4767 2908816384 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1000
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- UID は、Pod 仕様で設定したものと異なる必要があります。
次のコマンドを使用してデバッグセッションを終了します。
exit
sh-5.1# exit
Copy to Clipboard Copied! Toggle word wrap Toggle overflow exit
sh-5.1# exit
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
/proc
ファイルシステムがコンテナーにunmasked
の状態でマウントされていることを確認します。これは、次のコマンドの出力に、読み取り/書き込み権限 (rw
) が含まれていることからわかります。oc exec <pod_name> -- mount | grep /proc
$ oc exec <pod_name> -- mount | grep /proc
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 出力例
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
Copy to Clipboard Copied! Toggle word wrap Toggle overflow