Preface
The goal of this article is to allow someone to access our Kubernetes server, using a certificate that only that user have access.
The certificate will allow the administrator to manage the permission associated with the user, and revoke as needed.
First, the openssl tool is used to generate a Key and CSR. Then, a role is assigned to the newly created user. Then, a kubeconfig is created specifically for that user. Finally, How to use that certificate and authenticate to the Kubernetes api server.
Private key
We will create a directory were all the certs will be store during this demonstration
mkdir ~/certs
We then create the private key for Laurent with the -out
flag to output result to laurent.key
file and 4096
the size of the key being 4096-bit
$ openssl genrsa -out ~/certs/laurent.key 4096 Generating RSA private key, 4096 bit long modulus (2 primes) .......................................................................................................++++ .......................................................................................................................................++++ e is 65537 (0x010001)
Certificate Signing Request (csr)
We will now prepare the certificate signing request configuration file. This is done in a text editor (for this demo we will use vi)
$ vi ~/certs/laurent.csr.cnf
Add the following content and adapt it to your need.
[ req ] default_bits = 2048 prompt = no default_md = sha256 distinguished_name = dn [ dn ] CN = laurent O = developers [ v3_ext ] authorityKeyIdentifier=keyid,issuer:always basicConstraints=CA:FALSE keyUsage=keyEncipherment,dataEncipherment extendedKeyUsage=serverAuth,clientAuth
The certificate signing request configuration file contains all necessary information, user identity, and proper usage parameters for the user. The last argument extendedKeyUsage=serverAuth,clientAuth will allow users to authenticate their local clients with the Leaseweb k8s cluster using the certificate once it’s signed.
Now the csr creation for Laurent.
$ openssl req -config ~/certs/laurent.csr.cnf -new -key ~/certs/laurent.key -nodes -out ~/certs/laurent.csr
We can take a look at the csr with this command
$ openssl req -in certs/laurent.csr --noout -text Certificate Request: Data: Version: 1 (0x0) Subject: CN = laurent, O = developers Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (4096 bit) Modulus: 00:c7:f1:2c:bf:e6:b0:d8:76:38:55:43:6a:b8:e1: [...]
Approval
We will now send this csr to kubernetes cluster and then approve it so that the user Laurent can access the cluster.
first we need the base64 of the csr file
$ cat ~/certs/laurent.csr | base64 | tr -d '\n' LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJRWJEQ0NBbFFDQVFBd0p6RVFNQTRHQTFVRUF3d0hiR0YxY21WdWRERVRNQkVHQTFVRUNnd [...]
Then create the following CertificateSigningRequest manifest
$ vi laurent-csr.yml
With this content
--- apiVersion: certificates.k8s.io/v1 kind: CertificateSigningRequest metadata: name: laurent-authentication spec: signerName: kubernetes.io/kube-apiserver-client groups: - system:authenticated request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJRWJEQ0NBbFFDQVFBd0p6RVFNQTRHQTFVRUF3d0hiR0YxY21WdWRERVRNQkVHQTFVRUNnd [...] usages: - client auth
Then we apply this manifest to k8s cluster
$ kubectl apply -f laurent-csr.yml certificatesigningrequest.certificates.k8s.io/laurent-authentication created
We will now approved the new csr and save it to our certs directory.
We approved the csr
$ kubectl certificate approve laurent-authentication
Then we get the newly approved certificated
kubectl get csr laurent-authentication -o jsonpath='{.status.certificate}' | base64 --decode > ~/certs/laurent.crt
This will decode the base64 and save the result to our laurent.crt
file.
kubeconfig
Next, you will create a specific kubeconfig file for the laurent user. This will give you more control over the user’s access to your cluster.
First you can make a copy of the kubeconfig you downloaded from the customer portal
cp <path_to_saved_kubeconfig> ~/certs/laurent.kubeconfig
We then modify the file and point the user section to the cert and key we have created.
apiVersion: v1 clusters: - cluster: certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FUR [...] server: https://212.7.193.11:6443 name: k8s-0000001 contexts: - context: cluster: k8s-0000001 user: laurent # <- This is what need to be change name: k8s-0000001 current-context: k8s-0000001 kind: Config preferences: {} users: - name: laurent user: client-certificate: certs/laurent.crt # <- This is what need to be change client-key: certs/laurent.key # <- This is what need to be change
Authentication
Finally, we test the newly created kubeconfig by authenticating
# kubectl --kubeconfig laurent.kubeconfig cluster-info To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. Error from server (Forbidden): services is forbidden: User "laurent" cannot list resource "services" in API group "" in the namespace "kube-system"
We get an access Forbidden
as we have a user but no role or permission setup yet.