【问题标题】:New Kubernetes service account appears to have cluster admin permissions新的 Kubernetes 服务帐户似乎具有集群管理员权限
【发布时间】:2020-06-19 13:36:45
【问题描述】:

我遇到了新创建的 Kubernetes 服务帐户的奇怪行为。看来他们的令牌在我们的集群中提供了无限的访问权限。

如果我创建一个新的命名空间,在该命名空间内创建一个新的服务帐户,然后在新的 kube 配置中使用服务帐户的令牌,我就可以在集群中执行所有操作。

# SERVER is the only variable you'll need to change to replicate on your own cluster
SERVER=https://k8s-api.example.com
NAMESPACE=test-namespace
SERVICE_ACCOUNT=test-sa

# Create a new namespace and service account
kubectl create namespace "${NAMESPACE}"
kubectl create serviceaccount -n "${NAMESPACE}" "${SERVICE_ACCOUNT}"

SECRET_NAME=$(kubectl get serviceaccount "${SERVICE_ACCOUNT}" --namespace=test-namespace -o jsonpath='{.secrets[*].name}')
CA=$(kubectl get secret -n "${NAMESPACE}" "${SECRET_NAME}" -o jsonpath='{.data.ca\.crt}')
TOKEN=$(kubectl get secret -n "${NAMESPACE}" "${SECRET_NAME}" -o jsonpath='{.data.token}' | base64 --decode)

# Create the config file using the certificate authority and token from the newly created
# service account
echo "
apiVersion: v1
kind: Config
clusters:
- name: test-cluster
  cluster:
    certificate-authority-data: ${CA}
    server: ${SERVER}
contexts:
- name: test-context
  context:
    cluster: test-cluster
    namespace: ${NAMESPACE}
    user: ${SERVICE_ACCOUNT}
current-context: test-context
users:
- name: ${SERVICE_ACCOUNT}
  user:
    token: ${TOKEN}
" > config

将 ^ 作为 shell 脚本运行会在当前目录中生成 config。问题是,使用该文件,我能够读取和编辑集群中的所有资源。我希望新创建的服务帐户没有权限,除非我通过 RBAC 明确授予它们。

# All pods are shown, including kube-system pods
KUBECONFIG=./config kubectl get pods --all-namespaces

# And I can edit any of them
KUBECONFIG=./config kubectl edit pods -n kube-system some-pod

我没有向新创建的服务帐户添加任何角色绑定,因此我希望它使用新生成的配置接收所有kubectl 查询的拒绝访问响应。

下面是嵌入在config 中的 test-sa 服务帐户的 JWT 示例:

{
  "iss": "kubernetes/serviceaccount",
  "kubernetes.io/serviceaccount/namespace": "test-namespace",
  "kubernetes.io/serviceaccount/secret.name": "test-sa-token-fpfb4",
  "kubernetes.io/serviceaccount/service-account.name": "test-sa",
  "kubernetes.io/serviceaccount/service-account.uid": "7d2ecd36-b709-4299-9ec9-b3a0d754c770",
  "sub": "system:serviceaccount:test-namespace:test-sa"

}

需要考虑的事项...

  • 我看到rbac.authorization.k8s.io/v1 和集群中似乎启用了 RBAC rbac.authorization.k8s.io/v1beta1kubectl api-versions | grep rbac 的输出中,如this post 中所建议的那样。值得注意的是,kubectl cluster-info dump | grep authorization-mode,正如对同一问题的另一个答案所建议的那样,没有显示输出。这是否表明实际上并未启用 RBAC?
  • 我的用户拥有cluster-admin 角色权限,但我不希望这些权限转移到使用它创建的服务帐户。
  • 我们正在 GKE 上运行我们的集群。
  • 据我所知,我们在集群中没有任何非正统的 RBAC 角色或绑定会导致这种情况。我可能遗漏了一些东西,或者我通常不知道会导致这种情况的 K8s RBAC 配置。

我的假设是否正确,即新创建的服务帐户应该具有极其有限的集群访问权限,并且如果没有将许可的角色绑定附加到新服务帐户,上述场景不应该是可能的?对这里发生的事情有什么想法,或者我可以限制 test-sa 的访问吗?

【问题讨论】:

  • 尝试运行此命令以确保该命令正在使用您的新服务帐户运行:kubectl config view --template='{{ range .contexts }}{{ if eq .name "'$(kubectl config current-context)'" }}Current user: {{ .context.user }}{{ end }}{{ end }}'
  • 是的,kubectl 确实使用了正确的上下文:Current user: test-sa
  • 很奇怪,因为我运行了与您发布的完全相同的命令,对我来说,测试命令显示Error from server (Forbidden): pods "some-pod" is forbidden: User "system:serviceaccount:test-namespace:test-sa" cannot get resource "pods" in API group "" in the namespace "kube-system"。我已经检查了kubectl auth can-i,但我的结果没有*.* 资源......我试图弄清楚它为什么会发生。什么是 Kubernetes 版本?
  • 我刚刚创建了一个全新的 GKE 集群(版本 1.15.x,与我们遇到问题的其他集群相同),并且新创建的服务帐户似乎没有相同的过度允许访问此股票集群,就像他们在展示问题的集群中所做的那样。我们收到您描述的相同的禁止错误,并且我们也没有在kubectl auth can-i 命令中列出*.* 规则。这让我觉得 @ArghyaSadhu 是正确的,因为我们的其他集群中的某些配置不正确。

标签: kubernetes google-kubernetes-engine kubeconfig


【解决方案1】:

您可以通过运行命令检查服务帐户的权限

kubectl auth can-i --list --as=system:serviceaccount:test-namespace:test-sa

如果您看到下面的输出,则默认情况下服务帐户获得的权限非常有限。

Resources                                       Non-Resource URLs   Resource Names   Verbs
selfsubjectaccessreviews.authorization.k8s.io   []                  []               [create]
selfsubjectrulesreviews.authorization.k8s.io    []                  []               [create]
                                                [/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]

【讨论】:

  • 这是一个非常有用的命令!这是我们集群的输出:pastebin.com/raw/zXbk8fR6。顶部的两行看起来特别可疑,因为它们不在您的示例中,而且它们似乎提供了跨集群资源的广泛权限。
  • 知道什么会导致全新的服务帐户获得这样的权限吗?
  • 您是否有一个外部 webhook 可能正在执行 RBAC,即为任何服务帐户分配管理员角色?如果你做 kubectl get rolebinding 会得到什么
  • defaulttest-namespace 命名空间中的 kubectl get rolebinding 未显示任何意外的角色绑定。调查我们是否正在使用外部 webhook 进行身份验证...
【解决方案2】:

无法在我的测试实验室中的三个不同 K8S 版本(包括 v1.15.3、v1.14.10-gke.17、v1.11.7-gke.12 - 使用基本身份验证)上重现您的问题启用)。

很遗憾,基于令牌的登录活动未记录在 GKE 集群的 Cloud Logs 控制台的 AuditLogs 中:(。

据我所知,仅记录通过 Google Cloud 的数据访问操作(基于 AIM = kubectl 使用 google auth 提供程序)。

如果您的"test-sa" 服务帐户以某种方式被 RBAC 允许执行特定操作,我仍然会尝试研究您的 GKE 集群的Audit Logs。也许不知何故您的服务帐户被映射到google service account 一个,因此被授权。

您可以随时联系GCP官方支持渠道,进一步排查您的异常情况。

【讨论】:

    【解决方案3】:

    原来过于宽松的cluster-admin ClusterRoleBinding 绑定到system:serviceaccounts 组。这导致我们集群中的所有服务帐户都拥有cluster-admin 权限。

    似乎在集群生命的早期某个地方创建了以下ClusterRoleBinding

    kubectl create clusterrolebinding serviceaccounts-cluster-admin --clusterrole=cluster-admin  --group=system:serviceaccounts
    

    警告:切勿将此规则应用于您的集群☝️

    我们已经删除了这个过于宽松的规则,并调整了所有服务帐户的权限。

    感谢为这个问题提供了有用的答案和 cmets 的人们。他们有助于确定这个问题。这是一个非常危险的 RBAC 配置,我们很高兴能够解决它。

    【讨论】:

      猜你喜欢
      • 2018-11-16
      • 1970-01-01
      • 2019-08-17
      • 1970-01-01
      • 2018-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-15
      相关资源
      最近更新 更多