我正在为安全研究做一些 POC,试图直接从工作节点访问命名空间机密。我在 GKE 上有一个运行 Kubernetes 1.20 的集群
我正在从工作(非主)节点运行以下命令:
curl -v $APISERVER/api/v1/namespaces/default/pods/ \
--cacert /etc/srv/kubernetes/pki/ca-certificates.crt \
--cert /var/lib/kubelet/pki/kubelet-client.crt \
--key /var/lib/kubelet/pki/kubelet-client.key
它工作正常。
但是,尝试获取秘密失败:
curl -v $APISERVER/api/v1/namespaces/default/secrets/ \
--cacert /etc/srv/kubernetes/pki/ca-certificates.crt \
--cert /var/lib/kubelet/pki/kubelet-client.crt \
--key /var/lib/kubelet/pki/kubelet-client.key
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "secrets is forbidden: User \"system:node:gke-XXX--YYY\" cannot list resource \"secrets\" in API group \"\" in the namespace \"pencil\": No Object name found",
"reason": "Forbidden",
"details": {
"kind": "secrets"
},
"code": 403
查看文档,我看到在节点上运行的 kubelet 应该能够访问机密:https ://kubernetes.io/docs/reference/access-authn-authz/node/
据我了解,授权由ClusterRole
system:node
. 看着它,我确实看到它对get
秘密有作用:
% kubectl get clusterrole system:node -o json
{
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
...
{
"apiGroups": [
""
],
"resources": [
"configmaps",
"secrets"
],
"verbs": [
"get",
"list",
"watch"
]
},
...
]
}
还有一些更相关的关于 kubelet 和 kube-apiserver 之间通信的文档:https ://kubernetes.io/docs/concepts/architecture/control-plane-node-communication/#node-to-control-plane