Kubernetes uses three steps to perform secure access and permissions-authentication (Authentication), authorization (Authorization) and admission (Admission). In this article, we first start to understand authentication (Authentication).

The first thing to consider in authentication is Identity.

Introduction to Identity Authentication

Kubernetes assumes that "user" is managed outside of Kubernetes. In a production environment, LDAP (Lightweight Directory Access Protocol), SSO (Single Sign-On), Kerberos or SAML (Security Assertion Markup Language) can be used for identity authentication management. In the development or test environment, other authentication strategies may also be used.

There is no object that expresses ordinary users in Kubernetes, so ordinary users cannot be added to the cluster through the API.

Overview of certification strategies

Kubernetes uses authentication proxy, bearer token, client certificate or HTTP basic authorization to authenticate API requests through authentication plugins. When making an HTTP request to the API server, the plug-in will try to associate the following attributes with the request:

  • Username: A string identifying the end user
  • UID: A string that identifies the end user, and tries to be more consistent than the username format, and each UID is unique.
  • Groups: A set of strings that associate users with a set of common grouped users
  • Extra fields: A mapping of strings, which holds additional information that the authorizer thinks may be useful.

All these values are opaque to the authentication system and only have meaning when the authorizer interprets them. Kubernetes administrators usually enable multiple authentication methods. The two most basic methods required are the service account token of the service account plus at least one other user authentication method.

X509 client certificate

  • Starting with Kubernetes 1.4, client certificates can use the certificate organization field to indicate the user's group membership.
  • To allow a user to have multiple group memberships, multiple organization fields need to be included in the certificate.
  • Enable client certificate authentication by passing the --client-ca-file=<FILE> option to the API server.
  • The referenced file must contain one or more certificate authorities to verify the client certificate submitted to the API server.
  • If the client certificate is presented and verified, the common name of the subject is used as the requested user name.

For example, use the openssl command line tool to generate a certificate signing request:

openssl req -new -key <pem_file>.pem -out <out-csr-file>.pem -subj "/CN=admin/O=prod/O=dev/O=uat"

This will create a CSR (Certificate Signing Request) for the username admin, which belongs to the following 3 groups: prod, dev, and uat.

Static token file

When the --token-auth-file=<FILENAME> option is given in the command line, API Server will read the bearer token from the file. Nowadays, tokens exist indefinitely, and the token list cannot be changed without restarting the API Server. The Token file is a csv file with at least 3 columns: token, user name, user uid, and there may be a group name (this is optional).

token, user, uid,"prod,dev,uat"

Please note: if you have more than 1 group, the column must use double quotes.

Put a bearer token in the request

When using bearer token authentication from an HTTP client, the API server expects the value of the authorization request header to be Bearer <Token>. The bearer token must be a sequence of characters, and it can be placed in the value of the HTTP request header just by using the encoding and quoting functions of HTTP. For example, if the Bearer Token is ad644f3f-bfch-295b-75bk-h9g8ngf36hb6, it will appear in the HTTP request header as shown below:

Authorization: Bearer ad644f3f-bfch-295b-75bk-h9g8ngf36hb6

Static password file

Enable basic authentication by passing the --basic-auth-file=<FILENAME> option to the API server. Now, the basic authentication credentials will continue indefinitely, and the password cannot be changed without restarting the API server.

The basic auth file is a csv file with at least 3 columns: password, user name, and user ID. In Kubernetes 1.6 and later, you can specify an optional fourth column that contains comma-separated group names. If you have multiple groups, you must enclose the value in column 4 with double quotes (").

password,user,uid,"group1,group2,group3"

When using basic authentication from an HTTP client, the API server expects the value of Authorizationheader to be:

Basic BASE64ENCODED(USER:PASSWORD)

Service account token

The service account is an automatically enabled identity authenticator that uses a signed bearer token to verify requests. The plugin requires 2 optional flags:

--service-account-key-file

A file containing the PEM encoding key used to sign the bearer token. If not specified, the TLS key of the API server will be used.

--service-account-lookip

If enabled, the tokens deleted from the API server will be revoked.

The service account is usually automatically created by the API server, and is associated with the Pod running in the cluster through the ServiceAccount admission controller.

Bearer Token will be mounted to a Pod in a well-known location and allow processes in the cluster to talk to the API Server. The account can be explicitly associated with the Pod using the serviceAccountName field of the PodSpec.

Note that serviceAccountName is usually omitted because this is done automatically.

Practice practice: Use ServiceAccount Token

Use the following command to create a ServiceAccount:

kubectl create serviceaccount testuser

The created key contains the public CA of the API server and the signed JSON web Token (JWT). The following command can display the yaml that reveals the relevant key:

kubectl get serviceaccount testuser -o yaml

The following command can display the available tokens:

kubectl get secrets

To get the encoded token data, please enter:

kubectl get secret testuser-token-mgtnp -o yaml

You can copy and paste the encoded token data to https://jwt.io/ to view the payload. Use the editor of your choice to enter the following yaml file (test-pod.yaml) to run a pod:

apiVersion: v1 
kind: pod 
metadata:  
  name: test-pod 
spec:  
  serviceAccountName: testuser  
  container:  
  - name: alpine:3.7    
    command:    
    - "sh"    
    - "-c"    
    - "sleep 100"

Then use the following command to start the pod:

kubectl apply -f test-pod.yaml

Use describe to view more detailed content:

kubectl describe test-pod

Now that we have a running pod called test-pod, let's enter interactive mode and run a shell:

kubectl exec -it test-pod -- sh

If you want to run a shell in a docker container, the command used is similar to the docker command. At this time, we will receive a prompt and enter the Alpine Linux system, which runs in a container in the pod. In order to open the token copied to the container, you need to run the following command:

cat /var/run/sercrets/kubernetes.io/serviceaccount/token

Copy the output and paste the token in the Encoded section On the other side you will get the token type, namespace, ServiceAccount name, key name, etc.

This almost shows you how Kubernetes authenticates the payload in the token in a very intuitive way.

Author:
Sudip Sengupta
link:
https://dzone.com/articles/kubernetes-authentication

Rancher
1.2k 声望2.5k 粉丝

Rancher是一个开源的企业级Kubernetes管理平台,实现了Kubernetes集群在混合云+本地数据中心的集中部署与管理。Rancher一向因操作体验的直观、极简备受用户青睐,被Forrester评为“2020年多云容器开发平台领导厂商...