3

我遇到了新创建的 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在当前目录中生成 a 。问题是,使用该文件,我能够读取和编辑集群中的所有资源。我希望新创建的服务帐户没有权限,除非我通过 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使用新生成的配置接收所有查询的拒绝访问响应。

下面是一个 test-sa 服务帐户的 JWT 示例,它嵌入在config

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

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

4

3 回答 3

3

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

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]
于 2020-03-07T03:59:25.373 回答
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 集群的审核日志。也许不知何故,您的服务帐户被映射到谷歌服务帐户一,并因此获得授权。

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

于 2020-03-23T09:48:25.443 回答
2

事实证明,一个过度放任cluster-admin ClusterRoleBinding的人与该system:serviceaccounts团体有关。这导致我们集群中的所有服务帐户都具有cluster-admin特权。

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

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

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

此后,我们删除了这一过于宽松的规则,并对所有服务帐户权限进行了调整。

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

于 2020-05-22T17:52:33.050 回答