ProHoster > Blog > Administration > The ABC of Security in Kubernetes: Authentication, Authorization, Auditing
The ABC of Security in Kubernetes: Authentication, Authorization, Auditing
Sooner or later, in the operation of any system, the issue of security arises: providing authentication, separation of rights, auditing and other tasks. Already built for Kubernetes many solutions, which allow you to achieve standards compliance even in very demanding environments ... The same material is devoted to the basic security aspects implemented within the built-in K8s mechanisms. First of all, it will be useful to those who are starting to get acquainted with Kubernetes - as a starting point for studying issues related to security.
Authentication
There are two types of users in Kubernetes:
Service Accounts - accounts managed by the Kubernetes API;
Users - "normal" users managed by external, independent services.
The main difference between these types is that there are special objects for Service Accounts in the Kubernetes API (they are called like this - ServiceAccounts) that are bound to a namespace and a set of authorization data stored in the cluster in objects of type Secrets. Such users (Service Accounts) are mainly intended to manage access rights to the Kubernetes API of processes running in a Kubernetes cluster.
Ordinary Users, on the other hand, do not have entries in the Kubernetes API: they must be managed by external mechanisms. They are intended for people or processes living outside the cluster.
Each API request is tied to either a Service Account or a User, or is considered anonymous.
User authentication data includes:
Username β username (case sensitive!);
UID - a machine-readable user identification string that is "more consistent and unique than a username";
Groups β list of groups to which the user belongs;
Extras - additional fields that can be used by the authorization mechanism.
Kubernetes can use a large number of authentication mechanisms: X509 certificates, Bearer tokens, authentication proxy, HTTP Basic Auth. Using these mechanisms, you can implement a large number of authorization schemes: from a static password file to OpenID OAuth2.
Moreover, multiple authorization schemes can be used at the same time. By default, the cluster uses:
service account tokens - for Service Accounts;
X509 - for Users.
The issue of managing ServiceAccounts is beyond the scope of this article, and for those wishing to learn more about this issue, I recommend starting with official documentation pages. We will take a closer look at the issue of X509 certificates.
Certificates for Users (X.509)
The classic way to work with certificates involves:
processing the certificate request using the CA keys of the Kubernetes cluster, obtaining a user certificate (to obtain a certificate, you need to use an account that has access to the key of the Kubernetes cluster CA, which by default is located in /etc/kubernetes/pki/ca.key):
To facilitate the transfer of the config between accounts and servers, it is useful to edit the values ββof the following keys:
certificate-authority
client-certificate
client-key
To do this, you can encode the files specified in them using base64 and register them in the config, adding the suffix to the name of the keys -data, i.e. received certificate-authority-data etc.
Certificates with kubeadm
With release Kubernetes 1.15 working with certificates has become much easier thanks to the alpha version of its support in kubeadm utility. For example, here's what the generation of a configuration file with user keys might look like now:
kubeadm alpha kubeconfig user --client-name=mynewuser --apiserver-advertise-address 192.168.100.200
NB: Required advertise address can be viewed in the api-server config, which is located by default in /etc/kubernetes/manifests/kube-apiserver.yaml.
The resulting config will be printed to stdout. It must be kept in ~/.kube/config user account or to a file specified in an environment variable KUBECONFIG.
Dig deeper
For those who want to take a closer look at the issues described:
A separate article on working with certificates in the official Kubernetes documentation;
good article from Bitnami, in which the issue of certificates is touched upon from a practical point of view.
An authorized account, by default, does not have rights to act on the cluster. To grant permissions, Kubernetes implements an authorization mechanism.
Prior to version 1.6, Kubernetes used an authorization type called ABAC (Attribute-based access control). Details about it can be found in official documentation. This approach is currently considered legacy, but you can still use it at the same time as other authorization types.
The actual (and more flexible) way of separating access rights to a cluster is called RBAC (Role-based access control). It has been declared stable since version Kubernetes 1.8. RBAC implements a rights model that disallows everything that is not explicitly allowed. To enable RBAC, you need to start Kubernetes api-server with the parameter --authorization-mode=RBAC. The parameters are set in the manifest with the api-server configuration, which by default is located along the path /etc/kubernetes/manifests/kube-apiserver.yaml, in section command. However, by default, RBAC is already enabled, so most likely you should not worry about it: you can verify this by the value authorization-mode (in the already mentioned kube-apiserver.yaml). By the way, among its values ββthere may be other types of authorization (node, webhook, always allow), but we will leave their consideration beyond the scope of the material.
By the way, we have already published Article with a fairly detailed story about the principles and features of working with RBAC, so further I will limit myself to a brief listing of the basics and examples.
The following API entities are used to control access to Kubernetes via RBAC:
Role ΠΈ ClusterRole - roles that serve to describe access rights:
Role allows you to describe the rights within the namespace;
ClusterRole - within the cluster, including to cluster-specific objects such as nodes, non-resources urls (that is, not related to Kubernetes resources - for example, /version, /logs, /api*);
RoleBinding ΠΈ ClusterRoleBinding - used for binding Role ΠΈ ClusterRole to a user, user group, or ServiceAccount.
The Role and RoleBinding entities are namespace bound, i.e. must be within the same namespace. However, a RoleBinding can refer to a ClusterRole, which allows you to create a set of generic permissions and control access with them.
Roles describe rights using sets of rules containing:
resource names (resourceNames) - for the case when you need to provide access to a specific resource, and not to all resources of this type.
A more detailed breakdown of authorization in Kubernetes can be found on the page official documentation. Instead (or rather, in addition to this), I will give examples that illustrate its work.
RBAC Entity Examples
Simple Role, which allows you to get a list and status of pods and keep track of them in the namespace target-namespace:
Schematically, the architecture of Kubernetes can be represented as follows:
The key Kubernetes component responsible for processing requests is β api-server. All operations on the cluster go through it. You can read more about these internal mechanisms in the article "What happens in Kubernetes when you run kubectl run?Β».
System Auditing is an interesting feature in Kubernetes that is disabled by default. It allows you to log all calls to the Kubernetes API. As you might guess, all actions related to the control and change of the state of the cluster are performed through this API. A good description of its capabilities can (as usual) be found in official documentation K8s. In what follows, I will try to explain the topic in a simpler way.
So, to enable auditing, we need to pass three required parameters to the container in api-server, which are described in more detail below:
In addition to these three required parameters, there are many additional settings related to auditing: from log rotation to webhook descriptions. Example of log rotation parameters:
As already mentioned, all parameters are set in the manifest with the api-server configuration (by default /etc/kubernetes/manifests/kube-apiserver.yaml), in the section command. Let's go back to the 3 required parameters and analyze them:
audit-policy-file - the path to the YAML file with a description of the policy (policy) of the audit. We will return to its contents, but for now I will note that the file must be readable by the api-server process. Therefore, you need to mount it inside the container, for which you can add the following code to the appropriate sections of the config:
audit-log-format β audit log format. The default is json, but the legacy text format is also available (legacy).
Audit Policy
Now about the mentioned file with a description of the logging policy. The first concept of an audit policy is level, logging level. They are as follows:
None - do not log;
Metadata β log request metadata: user, request time, target resource (pod, namespace, etc.), action type (verb), etc.;
Request - log metadata and request body;
RequestResponse - log metadata, request body and response body.
The last two levelsRequest ΠΈ RequestResponse) do not log requests that did not access resources (references to the so-called non-resources urls).
Also, all requests go through several stages:
RequestReceived - the stage when the request is received by the handler and has not yet been transferred further along the chain of handlers;
ResponseStarted - The response headers are sent, but before the response body is sent. Generated for long running queries (for example, watch);
ResponseComplete - the response body has been sent, no more information will be sent;
Panic β Events are generated when an abnormal situation is detected.
To skip any stages, you can use omitStages.
In the policy file, we can describe several sections with different logging levels. The first matching rule found in the policy description will be applied.
The kubelet daemon listens for a change in the manifest with the api-server configuration and, if any, restarts the api-server container. But there is an important detail: changes in the policy file will be ignored. After making changes to the policy file, you will need to restart the api-server manually. Since api-server is started as static pod, team kubectl delete will not restart it. Will have to do it manually docker stop on kube-masters where the audit policy has been changed:
When enabling auditing, it is important to remember that load increases on kube-apiserver. In particular, the memory consumption for storing the query context increases. Logging starts only after the response header has been sent. The load also depends on the configuration of the audit policy.
Policy examples
Let's analyze the structure of policy files using examples.
Here is a simple file policyto log everything at the level Metadata:
In policy, you can specify a list of users (Users ΠΈ ServiceAccounts) and user groups. For example, this is how we will ignore system users, but log everything else at the level Request:
resources (Resources, As follows: pod, configmaps etc.) and resource groups (apiGroups).
Pay attention! Resources and resource groups (API groups, i.e. apiGroups), as well as their versions installed in the cluster, can be obtained using the commands:
kubectl api-resources
kubectl api-versions
The following audit policy is provided as a demonstration of the best practices in Alibaba Cloud documentation:
For prompt response to audit events, it is possible to describe webhook. This question is covered in official documentationI will leave it outside the scope of this article.
Results
This article provides an overview of the basic security mechanisms in Kubernetes clusters that allow creating personalized user accounts, separating their rights, and logging their actions. I hope it will be useful to those who are faced with such issues in theory or already in practice. I also recommend that you familiarize yourself with the list of other materials on the topic of security in Kubernetes, which is given in βPSβ, perhaps among them you will find the necessary details on the problems that are relevant to you.