🐡

RBACで権限問題の追求の仕方

2021/02/21に公開

kubernetesでは権限設定にRBAC (Role Based Access Control) を使います。しかし、権限周りは一旦なにか問題が起きると
追跡が難しいです。ここで、その問題解決の一助となる情報をまとめます。

前提知識

このあたりは情報がありますので、さっくりと紹介だけ。

role, clusterrole

roleおよびclusteroleは、どの処理ができるかという権限を示します。この権限は、以下の3つで表現されます。

  • apiGroups:
  • 例: "" (コアのAPIグループ), "networking.k8s.io", "argoproj.io"
  • resources
  • 例: pods, secrets
  • verbs
    • 例: "get", "watch", "list"

同じ名前のresourceでも、apiGroupが違えば違うものですので、間違えないようにしてください。

例えば、以下の例では、apiGroup ""、すなわちコアのAPIグループに属しているpodsリソースをget、watch、listできる、という権限になります。
権限は許可しかなく、「deny」つまりここに示すことはできない、というものはありません。なにも書いてないならなにもできないのです。

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # "" はコアのAPIグループを示します
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

roleはnamespaceに属しています。従って、roleを見るためにはnamespaceを意識しなくてはなりません。
一方、cluster roleはroleとは異なり、namespaceに属していません。

rolebinding, clusterrolebindings

roleやclusterroleは、単に権限を示しているだけです。これをuserやserviceaccount等に付与してはじめて使えるようになります。この付与をrolebindgあるいはclusterrolebindingと言います。

rolebindingの例です。これはdefaultのnamespaceにあるpod-readerというroleをjaneというユーザーに割り当てています。

apiVersion: rbac.authorization.k8s.io/v1
# このRoleBindingは「jane」にNamespace「default」のポッドの読み取りを許可する
# そのNamespaceでRole「pod-reader」を既に持っている必要があります。
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects: # 一つ以上の「subject」を指定する必要があります
- kind: User
  name: jane # 「name」は大文字と小文字が区別されます
  apiGroup: rbac.authorization.k8s.io
roleRef: # 「roleRef」はRole/ClusterRoleへのバインドを指定します
  kind: Role #RoleまたはClusterRoleである必要があります
  name: pod-reader # これはバインドしたいRole名またはClusterRole名とマッチする必要があります
  apiGroup: rbac.authorization.k8s.io

roleが設定している権限を知る

describeを使います

kubectl describe role eks:fargate-manager

例えば、kube-system namespaceにある eks:fargate-manager のroleでなにができるかを知りたい場合は以下のようにします。

% kubectl describe role eks:fargate-manager -n kube-system
Name:         eks:fargate-manager
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"Role","metadata":{"annotations":{},"name":"eks:fargate-manager","namespace":"kube-sys...
PolicyRule:
  Resources   Non-Resource URLs  Resource Names  Verbs
  ---------   -----------------  --------------  -----
  configmaps  []                 []              [create]
  events      []                 []              [get list]
  configmaps  []                 [aws-auth]      [get update patch delete]

これで、例えばconfigmapsのcreateができることが分かります。
ちなみに、resouce namesで、aws-authという名前のconfigmapsに関してだけはget, update, patch, deleteができることも分かります。

ある特定の操作ができるかを調べる

ある操作を実行できるかどうかを調べるには auth can-i を使います。--as 以下を指定することで指定したユーザーやserviceaccountの権限を表示します。

kubectl auth can-i --list --as=eks:fargate-manager -n kube-system

先程のeks:fargate-managerのroleがbindingされている eks:fargate-manager ユーザーが、なにができるかを一覧表示してくます。

% kubectl auth can-i --list --as=eks:fargate-manager -n kube-system
Resources                                       Non-Resource URLs   Resource Names     Verbs
configmaps                                      []                  []                 [create]
pods/eviction                                   []                  []                 [create]
selfsubjectaccessreviews.authorization.k8s.io   []                  []                 [create]
selfsubjectrulesreviews.authorization.k8s.io    []                  []                 [create]
pods                                            []                  []                 [get list watch delete]
nodes                                           []                  []                 [get list watch]
events                                          []                  []                 [get list]
configmaps                                      []                  [aws-auth]         [get update patch delete]
                                                [/api/*]            []                 [get]
                                                [/api]              []                 [get]
                                                [/apis/*]           []                 [get]
                                                [/apis]             []                 [get]
                                                [/healthz]          []                 [get]
                                                [/healthz]          []                 [get]
                                                [/livez]            []                 [get]
                                                [/livez]            []                 [get]
                                                [/openapi/*]        []                 [get]
                                                [/openapi]          []                 [get]
                                                [/readyz]           []                 [get]
                                                [/readyz]           []                 [get]
                                                [/version/]         []                 [get]
                                                [/version/]         []                 [get]
                                                [/version]          []                 [get]
                                                [/version]          []                 [get]
podsecuritypolicies.policy                      []                  [eks.privileged]   [use]

この操作ができるかどうかだけを知りたい場合は、以下のようにverbとresourceを指定します。

kubectl auth can-i get events --as=eks:fargate-manager -n kube-system

返り値はyesかnoかだけとなるが、例えばnamespaceに存在しなかったりするとエラーとなるので調査が可能となります。

% kubectl auth can-i get events --as=eks:fargate-manager -n kube-system
yes
% kubectl auth can-i create events --as=eks:fargate-manager -n kube-system
no

どのようなリソースがあるか知る

現在どのようなresourceがあるかを知るためには以下のコマンドを使います。

kubectl api-resources

これで以下のようにresourceの名前とそのresourceが所属しているapi groupが分かります。(一部省略しています)

% kubectl api-resources
NAME                              SHORTNAMES           APIGROUP                       NAMESPACED   KIND
bindings                                                                              true         Binding
componentstatuses                 cs                                                  false        ComponentStatus
configmaps                        cm                                                  true         ConfigMap
endpoints                         ep                                                  true         Endpoints
events                            ev                                                  true         Event
subjectaccessreviews                                   authorization.k8s.io           false        SubjectAccessReview
horizontalpodautoscalers          hpa                  autoscaling                    true         HorizontalPodAutoscaler
cronjobs                          cj                   batch                          true         CronJob
jobs                                                   batch                          true         Job
certificatesigningrequests        csr                  certificates.k8s.io            false        CertificateSigningRequest
leases                                                 coordination.k8s.io            true         Lease
eniconfigs                                             crd.k8s.amazonaws.com          false        ENIConfig

そもそもどういうcustom resourceがあるか知りたい

kubectl get customresourcedefinitions

こういう感じで出てきます。

% kubectl get customresourcedefinitions
NAME                                         CREATED AT
alertmanagers.monitoring.coreos.com          2020-12-18T05:38:32Z
clusterworkflowtemplates.argoproj.io         2020-12-21T04:58:19Z
cronworkflows.argoproj.io                    2020-12-21T04:58:19Z
eniconfigs.crd.k8s.amazonaws.com             2020-12-18T03:57:57Z
prometheuses.monitoring.coreos.com           2020-12-18T05:38:32Z
prometheusrules.monitoring.coreos.com        2020-12-18T05:38:32Z
servicemonitors.monitoring.coreos.com        2020-12-18T05:38:32Z
workfloweventbindings.argoproj.io            2020-12-21T04:58:19Z
workflows.argoproj.io                        2020-12-21T04:58:19Z
workflowtemplates.argoproj.io                2020-12-21T04:58:19Z

Discussion