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 ~/certsWe 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.cnfAdd 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,clientAuthThe 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 is signed.
Now the CSR creation for Laurent:
$ openssl req -config ~/certs/laurent.csr.cnf -new -key ~/certs/laurent.key -nodes -out ~/certs/laurent.csrWe 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 Certificate Signing Request manifest:
$ vi laurent-csr.ymlWith this content: laurent-csr.yml
---
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 authThen we apply this manifest to k8s cluster:
$ kubectl apply -f laurent-csr.yml
certificatesigningrequest.certificates.k8s.io/laurent-authentication createdWe will now approve the new CSR and save it to our certs directory.
We approved the CSR:
$ kubectl certificate approve laurent-authenticationThen we get the newly approved certificated:
kubectl get csr laurent-authentication -o jsonpath='{.status.certificate}' | base64 --decode > ~/certs/laurent.crtThis 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.kubeconfigWe then modify the file and point the user section to the cert and key we have created.
laurent.kubeconfig
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 changeAuthentication
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.


