2.17. Linux ユーザー名前空間での Pod の実行
Linux ユーザー名前空間を使用すると、管理者はコンテナーのユーザーおよびグループ識別子 (UID および GID) を分離できるため、実行されているホストシステムとは異なる権限セットを、ユーザー名前空間でコンテナーに付与できます。これにより、ユーザー名前空間内で完全な権限を使用してプロセスを実行することをコンテナーに許可する一方で、ホストマシンに対する操作の権限をプロセスに与えないことが可能になります。
デフォルトでは、コンテナーはホストユーザー名前空間で実行されます。コンテナーをホストのユーザー名前空間で実行することは、そのユーザー名前空間でのみ使用可能な機能がコンテナーに必要な場合に便利です。しかし、ホストの名前空間で Pod を実行すると、コンテナーブレイクアウトの可能性など、セキュリティー上の懸念が生じます。コンテナーブレイクアウトが発生すると、別のコンテナー内のプロセスがホスト上に脱出し、そのプロセスがホスト上またはコンテナー内のファイルにアクセスしたり、ファイルを変更したりできるようになります。
個々のユーザー名前空間でコンテナーを実行すると、コンテナーブレイクアウトや、侵害されたコンテナーから他の Pod やノード自体に及ぶ可能性のあるその他のいくつかの脆弱性を軽減できます。
隔離されたユーザー名前空間で Pod を実行すると、Pod コンテナー内の UID/GID がホスト上の UID/GID と一致しなくなります。ファイルシステムの所有権が正しく機能するように、Linux カーネルは ID-mapped マウントを使用します。ID マップマウントは、仮想ファイルシステム (VFS) レイヤーにおいて、コンテナーとホスト間でユーザー ID を変換するものです。
現時点では、ネットワークファイルシステム (NFS) やその他のネットワーク/分散ファイルシステムなど、すべてのファイルシステムが ID-mapped マウントをサポートしているわけではありません。ID-mapped マウントをサポートしていないベンダーが提供する、NFS を基盤とした永続ボリュームを使用している Pod は、ユーザー名前空間で実行される際に、アクセスや権限の問題が発生する可能性があります。この動作は OpenShift Container Platform に固有のものではありません。これは、Kubernetes v1.33 以降のすべての Kubernetes ディストリビューションに適用されます。
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>.yamlCopy 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-podCopy to Clipboard Copied! Toggle word wrap Toggle overflow コンテナー内で使用されているユーザー ID とグループ ID を表示します。
id
sh-5.1$ idCopy 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 userCopy 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 10001 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-q8sh9Copy 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-q8sh9Copy to Clipboard Copied! Toggle word wrap Toggle overflow /hostをデバッグシェル内のルートディレクトリーとして設定します。chroot /host
sh-5.1# chroot /hostCopy to Clipboard Copied! Toggle word wrap Toggle overflow ノードによって使用されている UID を表示します。
lsns -t user
sh-5.1# lsns -t userCopy 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 10001 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- UID は、Pod 仕様で設定したものと異なる必要があります。
次のコマンドを使用してデバッグセッションを終了します。
exit
sh-5.1# exitCopy to Clipboard Copied! Toggle word wrap Toggle overflow exit
sh-5.1# exitCopy to Clipboard Copied! Toggle word wrap Toggle overflow
/procファイルシステムがコンテナーにunmaskedの状態でマウントされていることを確認します。これは、次のコマンドの出力に、読み取り/書き込み権限 (rw) が含まれていることからわかります。oc exec <pod_name> -- mount | grep /proc
$ oc exec <pod_name> -- mount | grep /procCopy 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