RBACで権限を切る
目標
ServiceAccountに最小権限を与え、その権限がネームスペースの境界を越えないことを確認し、クラスタースコープの権限とAggregated ClusterRoleまで構成します。
なぜ重要なのか
RBACの問題は、試験で配点が確実です。しかし、正解を作ることより、正解が合っているかを確認することのほうが重要です。kubectl auth can-i --as=は、SubjectAccessReviewを作成してapiserverに尋ねるだけで、実際のリクエストは送らないので、副作用なしに、何度でも確認できます。
このラボは、特にnoを確認するステップを入れています。RBACは累積するだけで拒否ルールがないので、誤ってClusterRoleBindingを使うと、意図したよりはるかに広く開きます。開いたかどうかは簡単に確認しますが、開いていないかどうかは、あまり確認しません。最小権限の原則は、「できないことを確認する習慣」なしには守られません。
ステップ
- ネームスペース
cka-rbacとcka-rbac-otherを作成してください。cka-rbacにServiceAccountdeploy-botを作成し、cka-rbac-otherには、境界確認用のConfigMapboundary-probeを1つ作成してください。 cka-rbacにRolepod-readerを作成してください。apiGroupsはcore(空文字列)、resourcesはpodsとpods/log、verbsはget、list、watchだけです。cka-rbacにRoleBindingpod-reader-bindを作成し、Rolepod-readerをServiceAccountcka-rbac/deploy-botに結び付けてください。deploy-botになりすました権限確認の結果を、/root/cka-rbac/can-i.txtに保存してください。cka-rbacでPodのgetがyesで、deleteはnoである必要があります。- 同じアカウントで、
cka-rbac-otherでPodを読めるかを確認して、/root/cka-rbac/boundary.txtに保存してください。結果はnoである必要があります。 - ClusterRole
node-viewer(apiGroups core、resourcesnodes、verbsget/list/watch)とClusterRoleBindingnode-viewer-bindを作成して、cka-rbac/deploy-botに結び付けてください。ノードのlistがyesになる必要があります。 - ClusterRole
cka-monitoring-endpointsを作成してください。ラベルはrbac.labhub.io/aggregate-to-monitoring=true、ルールはcoreグループのservicesとendpointsに対するget、listです。そしてClusterRolecka-monitoringを作成し、aggregationRuleがそのラベルをセレクターとして選ぶようにしてください。 cka-rbacにServiceAccountno-tokenを作成しますが、automountServiceAccountToken: falseにしてください。Podlocked-down(イメージnginx:1.27)を作成して、serviceAccountNameをno-tokenにし、PodのスペックでもautomountServiceAccountToken: falseを明示してください。このアカウントには、何の権限もバインドしないでください。
参考
- サービスアカウントになりすますときの名前は、
system:serviceaccount:<네임스페이스>:<이름>の形式です(プレースホルダーはネームスペースと名前です)。 - ステップ4、5のファイルには、コマンドの出力(yesまたはno)がそのまま入っていればよいです。
- よくあるミス1: ステップ3で、subjectsにnamespaceを忘れることです。同じネームスペースでも、明示する必要があります。
- よくあるミス2: ステップ6をRoleBindingで行うことです。ノードはクラスタースコープなので、ネームスペースのバインディングでは開けません。
サービスアカウントと実験用のネームスペース
ネームスペースcka-rbacとcka-rbac-otherを作成してください。cka-rbacにServiceAccountdeploy-botを作成し、cka-rbac-otherには、境界確認用のConfigMapboundary-probeを1つ作成してください。
サービスアカウントはネームスペーススコープです。境界を確認するには、アクセスしてはいけない側にも、リソースが1つある必要があります。
読み取り専用のRoleを作成する
cka-rbacにRolepod-readerを作成してください。apiGroupsはcore(空文字列)、resourcesはpodsとpods/log、verbsはget、list、watchだけです。
coreグループは、空文字列です。ログはPodとは別のサブリソースとして扱われるので、別に書く必要があります。書き込みの動詞を入れてはいけません。
RoleBindingで結び付ける
cka-rbacにRoleBindingpod-reader-bindを作成し、Rolepod-readerをServiceAccountcka-rbac/deploy-botに結び付けてください。
subjectsのkindはServiceAccountで、名前と一緒に、そのアカウントがあるネームスペースも書く必要があります。
権限が付いたか確認する
deploy-botになりすました権限確認の結果を、/root/cka-rbac/can-i.txtに保存してください。cka-rbacでPodのgetがyesで、deleteはnoである必要があります。
auth can-iは、実際のリクエストを送らず、尋ねるだけです。--asに入れるサービスアカウント名の形式が、決まっています。
ネームスペースの境界を越えられないことを確認する
同じアカウントで、cka-rbac-otherでPodを読めるかを確認して、/root/cka-rbac/boundary.txtに保存してください。結果はnoである必要があります。
ここでyesが返るなら、バインディングの種類を誤って選んでいます。RoleBindingとClusterRoleBindingの違いを、もう一度見てください。
クラスタースコープのリソースを開く
ClusterRolenode-viewer(apiGroups core、resourcesnodes、verbsget/list/watch)とClusterRoleBindingnode-viewer-bindを作成して、cka-rbac/deploy-botに結び付けてください。ノードのlistがyesになる必要があります。
ノードは、どのネームスペースにも属しません。ネームスペーススコープのバインディングでは、アクセスを与えられません。
Aggregated ClusterRoleを構成する
ClusterRolecka-monitoring-endpointsを作成してください。ラベルはrbac.labhub.io/aggregate-to-monitoring=true、ルールはcoreグループのservicesとendpointsに対するget、listです。そしてClusterRolecka-monitoringを作成し、aggregationRuleがそのラベルをセレクターとして選ぶようにしてください。
aggregationRuleを使うロールには、rulesを直接書きません。ルールは、ラベルの付いたほかのロールに書きます。
総合: トークンのないPodを作成する
cka-rbacにServiceAccountno-tokenを作成しますが、automountServiceAccountToken: falseにしてください。Podlocked-down(イメージnginx:1.27)を作成して、serviceAccountNameをno-tokenにし、PodのスペックでもautomountServiceAccountToken: falseを明示してください。このアカウントには、何の権限もバインドしないでください。
サービスアカウントとPodの両方で無効にでき、Pod側の設定が優先されます。両方に明示すると、意図が明確になります。