新的 Kubernetes 服务帐户似乎具有集群管理员权限

New Kubernetes service account appears to have cluster admin permissions

我遇到了新创建的 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"

}

需要考虑的事情...

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

您可以通过运行命令查看服务账号的权限

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]

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

不幸的是,基于令牌的登录活动未记录在 GKE 集群的 Cloud Logs 控制台的审计日志中:(。

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

如果你的"test-sa"服务帐号被RBAC以某种方式允许执行特定操作,我仍然会尝试研究Audit Logs of your GKE cluster. Maybe somehow your service account is being mapped to google service account一个,从而获得授权。

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

结果是一个过于宽容的 cluster-admin ClusterRoleBinding 被绑定到 system:serviceaccounts 组。这导致我们集群中的所有服务帐户都具有 cluster-admin 权限。

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

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

WARNING: Never apply this rule to your cluster ☝️

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

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