Link Search Menu Expand Document

Broken Authorization in Kubernetes

Kubernetes has many components and functionalities that need to be carefully configured in order to maintain the security of the cluster.

API Server

The API server is the pivotal point where the cluster’s security configuration is applied. All of the other components are able to interact directly with the cluster’s state store via its REST API.

For this reason, client access to the Kubernetes API should be authenticated, authorized, and encrypted.

Authentication strategies

Kubernetes uses client certificates, bearer tokens, an authenticating proxy, or HTTP basic auth to authenticate API requests through authentication plugins. The plugins attempt to associate the following attributes with each request:

  • Username: a string which identifies the end user.
  • UID: a unique string which identifies the end user.
  • Groups: associate users with a set of commonly grouped users.
  • Extra fields: a map of strings for additional information.

At a minimum, the service account tokens for service accounts and user authentication methods should be enabled.

The system:authenticated group is included in the list of groups for all authenticated users.

Starting from version 1.6, anonymous access is enabled by default if an authorization mode other than AlwaysAllow is used, and anonymous requests are not rejected but are given a username of system:anonymous and a group of system:unauthenticated.

API authorization

Role-based access control (RBAC) is an access control mechanism to regulate access to resources based on the roles within your organization. In Kubernetes, permissions are grouped into roles and combine verbs (get, create, delete) with resources (pods, services, nodes); permissions can be scoped to a namespace or to the entire cluster.

To enable RBAC, start the API server with the --authorization-mode flag set to a comma-separated list that includes RBAC; for example Node,RBAC.

The RBAC API declares four kinds of objects: Role, ClusterRole, RoleBinding, and ClusterRoleBinding.

Role and ClusterRole

Role and ClusterRole can be used to grant permissions. ClusterRole is cluster-scoped.

Here’s an example Role in the default namespace that can be used to grant read access to secrets:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: secret-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

RoleBinding and ClusterRoleBinding

RoleBinding and ClusterRoleBinding grant the permissions defined in a role to a user or set of subjects (users, groups, or service accounts). ClusterRoleBinding is cluster-scoped.

Here is an example of a RoleBinding that grants the secret-reader Role to the user jane within the default namespace. This allows jane to read secrets in the default namespace.

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-secrets
  namespace: default
subjects:
- kind: User
  name: jane
roleRef:
  kind: Role
  name: secret-reader

If you want to grant permissions to a Pod instead of a user, you can create a custom ServiceAccount to be referenced in the RoleBinding subjects list.

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: secret-reader-account
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-secrets
  namespace: default
subjects:
- kind: ServiceAccount
  name: secret-reader-account
roleRef:
  kind: Role
  name: secret-reader

Then set secret-reader-account as spec.serviceAccountName for any pod you want to entitle with such permissions.

Kubelet

Kubelet is an agent running on every node that should be configured correctly to prevent unauthorized access from the pods.

In prior versions of Kubernetes (prior to 1.7), Kubelet had read-write access to the Node and Pod APIs, allowing numerous resources to be taken control of in the event of a compromise. More recent versions introduced the Node Authorizer, which limits the kubelet to access only resources that are related specifically to the node on which the kubelet runs.

REST APIs are exposed on ports 10250 (read/write) and 10255 (read-only) ports.

Read-write port

Unrestricted access to the read-write port could result in a take over of the cluster, as it’s possible to run commands inside the pod’s containers or start new resources. This can’t be fully disabled because it is needed for metric collection and other important functions, so the access should be carefully controlled.

Kubelet should be configured to enforce authentication of all clients. The methods that can be enabled are X.509 client certificates, or requests with Authorization headers containing authentication tokens.

In the case of X.509 client certificates, the contents of a CA bundle need to be made available to the kubelet (--client-ca-file, authentication.x509.clientCAFile).

By default, when receiving anonymous requests, Kubelet passes them on for authorization, rather than rejecting them.

The authorization setting (authorization.mode, --authorization-mode) can operate in one of two modes; AlwaysAllow (default) or Webhook. The first option disables the authentication, while the Webhook value performs further checks to determine whether the subject is allowed to make the request.

To disable anonymous access and send 401 Unauthorized responses to unauthenticated requests, the anonymous settings (authentication.anonymous.enabled, --anonymous-auth) must be set to false.

Read only port

The read-only access could also be abused to disclose sensitive information regarding the cluster.

For this reason, the read-only port should be disabled by removing the option or by setting the option (readOnlyPort, --read-only-port ) to 0.

Etcd

Kubernetes uses etcd key-value store for storing cluster state and configurations. For this reason, getting write access to the etcd backend for the APIs is equivalent to granting cluster-admin access, and read access can be used to escalate fairly quickly. It listens on TCP port 2379 for client and TCP port 2380 for server-to-server communications.

In versions prior to etcd 2.1, authentication did not exist; however, etcd currently supports strong credentials such as mutual authentication via client certificates. This should always be used by creating a new key pair for every entity in the cluster that needs to access etcd API.

References

Kubernetes - Accessing the API

Kubernetes - Securing a Cluster

Kubernetes - Configure Service Accounts for Pods