Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Kubelet API bearer token authentication #215

Closed
dghubble opened this issue May 14, 2018 · 7 comments
Closed

Allow Kubelet API bearer token authentication #215

dghubble opened this issue May 14, 2018 · 7 comments

Comments

@dghubble
Copy link
Member

Feature Request

Feature

Today, Kubelet bearer token authentication is not permitted. Allow Kubelet bearer token authentication and enable Webhook authorization (required, as the default would be AlwaysAllow) to enable giving out more fine grained RBAC permissions related to nodes. One example use-case is reducing the Prometheus addon's RBAC privileges from node/proxy to node/metrics.

This impacts several areas where we need to be careful to avoid regressions:

  • kubectl commands
  • Prometheus addon
  • Potentially metric-server addon

More context: #191

@dghubble
Copy link
Member Author

Evaluating PR #191 showed simply adding --authentication-token-webhook and --authorization-mode=Webhook breaks kubectl logs, exec, port-forward, and other essentials (unusual). Some digging shows this seems to be a symptom of not using a special TLS organization in apiserver certificate generation.

Here's how it works.

Today

Today, Typhoon (along with bootkube and likely Tectonic)) do not enable Kubelet bearer token authentication. kubectl commands like exec, logs, port-forward authenticate with the apiserver and then apiserver uses its X509 --kubelet-client-certificate and --kubelet-client-key key to authenticate to a particular Kubelet. Requests succeed because the apiserver's certificate authenticates and the Kubelet defaults to AlwaysAllow authorization.

Verify the apiserver can present its TLS cert and do whatever it likes:

kubectl exec -it kube-apiserver-sr8z2 -n kube-system /bin/bash
curl --cert /etc/kubernetes/secrets/apiserver.crt --key /etc/kubernetes/secrets/apiserver.key  http://NODE-INTERNAL-IP:10250/metrics -k

This design is reasonable and has served well for a while. No reason to worry. The apiserver X509 certificate is generated upfront and kept safe, since it allows all-access to kubelets.

Kubelet Bearer Token Auth

Experiment with Kubelet bearer token authentication. Launch a cluster and enable Kubelet bearer token auth on one of the worker nodes by editing the unit file and restarting the kubelet.

--authentication-token-webhook
--authorization-mode=Webhook

This opens up the Kubelet to accepting bearer tokens (e.g. from a pod's service account), so we switch the default authorization from AlwaysAllow to Webhook. As a side-effect, that means the X509 client certificate requests must also be authorized now.

Try to get the logs of a pod on that node with kubectl or exec into the apiserver to repeat the verification above.

curl --cert /etc/kubernetes/secrets/apiserver.crt --key /etc/kubernetes/secrets/apiserver.key  http://NODE-INTERNAL-IP:10250/metrics -k
Forbidden (user=kube-apiserver, verb=get, resource=nodes, subresource=proxy)

While the apiserver.crt and apiserver.key are valid and authenticate just fine, they are not authorized. This is surprising. Enabling Kubelet authorization shows the apiserver is not actually authorized to perform log, exec, etc.

Tracking this back the apiserver TLS generation, I notice Typhoon, bootkube, and Tectonic all generate apiserver certificates with an ORG: kube-master:

I believe the special org is supposed to be system:masters. I launched a Typhoon cluster with modifications to the apiserver's ORG to system:masters. Now when I enable kublet bearer token auth, it does not break kubectl log, exec, port-forward, etc.

I'm not sure where ORG kube-master came from, but I suspect its wrong.

Note: In #191, someone claimed Tectonic was using kubelet token auth. I'm not 100% (since I can't see the proprietary bits and its a bit different), but given Tectonic is also using kube-master, I think its probably also not using token auth (or else they'd have kubectl issues).

@ericchiang
Copy link
Contributor

When you enable:

--authorization-mode=Webhook

that causes the kubelet to make an authorization query against the API server to determine if the subject can perform actions against the kubelet API. The following ClusterRole should satisfy all kubelet authorization queries:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: kubelet-api
rules:
- apiGroups: [""]
  resources: ["nodes/stats", "nodes/metrics", "nodes/log", "nodes/spec", "nodes/proxy"]
  verbs: ["get", "list", "update", "patch", "delete"]

Then bind it to whatever the API server's client certs authenticate as. X509 certs authenticate by CN -> username, and O -> group:

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: kubelet-api
subjects:
- kind: User
  name: kube-apiserver
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: kubelet-api
  apiGroup: rbac.authorization.k8s.io

@ericchiang
Copy link
Contributor

ericchiang commented May 14, 2018

The reason system:masters works is because it maps to an admin RBAC role. That works too, but wanted to explain why it works a little.

@dghubble
Copy link
Member Author

Awesome! Thanks for adding that.

I'm thinking to go with the kube-master -> system:masters switch. Since its the X509 certificate for the apiserver itself, it seems like it has a pretty legitimate claim to it.

dghubble added a commit to poseidon/terraform-render-bootstrap that referenced this issue May 14, 2018
* A kubernetes apiserver should be authorized to make requests
to kubelets using an admin role associated with system:masters
* Kubelet defaults to AlwaysAllow so an apiserver that presented
a valid certificate had all access to the Kubelet. With Webhook
authorization, we're making that admin access explicit
* Its important the apiserver be able to perform or proxy to
kubelets for kubectl log, exec, port-forward, etc.
* poseidon/typhoon#215
dghubble added a commit that referenced this issue May 14, 2018
* Require Webhook authorization to the Kubelet
* Switch apiserver X509 client cert org to systems:masters
to grant the apiserver admin and satisfy the authorization
requirement. kubectl commands like logs or exec that have
the apiserver make requests of a kubelet continue to work
as before
* https://kubernetes.io/docs/admin/kubelet-authentication-authorization/
* #215
dghubble-robot pushed a commit to poseidon/terraform-onprem-kubernetes that referenced this issue May 15, 2018
* Require Webhook authorization to the Kubelet
* Switch apiserver X509 client cert org to systems:masters
to grant the apiserver admin and satisfy the authorization
requirement. kubectl commands like logs or exec that have
the apiserver make requests of a kubelet continue to work
as before
* https://kubernetes.io/docs/admin/kubelet-authentication-authorization/
* poseidon/typhoon#215
@dghubble
Copy link
Member Author

Added in #216

dghubble-robot pushed a commit to poseidon/terraform-digitalocean-kubernetes that referenced this issue May 15, 2018
* Require Webhook authorization to the Kubelet
* Switch apiserver X509 client cert org to systems:masters
to grant the apiserver admin and satisfy the authorization
requirement. kubectl commands like logs or exec that have
the apiserver make requests of a kubelet continue to work
as before
* https://kubernetes.io/docs/admin/kubelet-authentication-authorization/
* poseidon/typhoon#215
dghubble-robot pushed a commit to poseidon/terraform-aws-kubernetes that referenced this issue May 15, 2018
* Require Webhook authorization to the Kubelet
* Switch apiserver X509 client cert org to systems:masters
to grant the apiserver admin and satisfy the authorization
requirement. kubectl commands like logs or exec that have
the apiserver make requests of a kubelet continue to work
as before
* https://kubernetes.io/docs/admin/kubelet-authentication-authorization/
* poseidon/typhoon#215
dghubble-robot pushed a commit to poseidon/terraform-google-kubernetes that referenced this issue May 15, 2018
* Require Webhook authorization to the Kubelet
* Switch apiserver X509 client cert org to systems:masters
to grant the apiserver admin and satisfy the authorization
requirement. kubectl commands like logs or exec that have
the apiserver make requests of a kubelet continue to work
as before
* https://kubernetes.io/docs/admin/kubelet-authentication-authorization/
* poseidon/typhoon#215
@aknuds1
Copy link
Contributor

aknuds1 commented May 15, 2018

Does this mean that Prometheus Operator/kube-prometheus now works with Typhoon as I set out to solve with #191?

@dghubble
Copy link
Member Author

Perhaps. You'd need to check their docs or try it to be sure, Prometheus Operator isn't something I'm going to be using or validating.

The motive was further improving the security of the Prometheus addon's manifests that are designed for usage with Typhoon. Great that it helps Prometheus Operator too. We recommend the Prometheus addon however. Compare the Prometheus addon's ClusterRole with the Prometheus Operator's ClusterRole and compare the flexibility and features of each. Choose what's best for you - these are addons atop a cluster after all and its your choice.

Snaipe pushed a commit to aristanetworks/monsoon that referenced this issue Apr 13, 2023
* Require Webhook authorization to the Kubelet
* Switch apiserver X509 client cert org to systems:masters
to grant the apiserver admin and satisfy the authorization
requirement. kubectl commands like logs or exec that have
the apiserver make requests of a kubelet continue to work
as before
* https://kubernetes.io/docs/admin/kubelet-authentication-authorization/
* poseidon#215
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants