2

I've tried to create user accounts with a client certificate.

I followed two tutorials but stuck with both options in an error with the message

https://medium.com/better-programming/k8s-tips-give-access-to-your-clusterwith-a-client-certificate-dfb3b71a76fe

https://docs.bitnami.com/kubernetes/how-to/configure-rbac-in-your-kubernetes-cluster/

I set the right user, server and the right context. I set the namespace but still the same error.

> kubectl get pods
You must be logged in to the server (Unauthorized) 

Did someone already experienced something similar? Or does someone knows what i'm doing wrong?

My k3s cluster version is 1.15.4.

Manuel
  • 1,928
  • 2
  • 16
  • 26
  • Are you able to login with the user you've just created? – ankidaemon Jan 28 '20 at 06:53
  • I followed the setup, like written on this pages, but it looks like it differs to a k3s installation. Maybe i made a mistake, many times?! Not sure, if i'm blind and can't see what i did wrong. – Manuel Jan 28 '20 at 11:17

2 Answers2

4

From the error you posted, your user is getting failed in Authentication phase only (HTTP error code: 401), you can validate the same using:

$ k get pods -v=6
...
I0123 16:34:18.842853   29373 helpers.go:203] server response object: [{
  ...
  "code": 401
}]
F0123 16:34:18.842907   29373 helpers.go:114] error: You must be logged in to the server (Unauthorized)

Debug your setup using below steps:

  1. Verify you are using the correct context and correct user as you expected (with * in CURRENT column):

    $ kubectl config get-contexts 
    CURRENT   NAME                          CLUSTER      AUTHINFO                NAMESPACE
    *         context-user-ca-signed        kubernetes   user-user-ca-signed     ns1
              kubernetes-admin@kubernetes   kubernetes   kubernetes-admin        
    
  2. Verify the CA certificate for Kubernetes API Server (assuming API server running as a Pod):

    $ sudo cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep -i "\-\-client-ca-file"
        - --client-ca-file=/etc/kubernetes/pki/ca.crt
    
    $ openssl x509 -in /etc/kubernetes/pki/ca.crt -text -noout | grep -i "Issuer:\|Subject:"
            Issuer: CN = kubernetes
            Subject: CN = kubernetes
    
  3. Verify your user's certificate is signed by above CA (Issuer CN of user's cert is same as Subject CN of CA cert, "kubernetes" here), which is configured in API server:

    $ kubectl config view --raw -o jsonpath="{.users[?(@.name == \"user-user-ca-signed\")].user.client-certificate-data}" | base64 -d > client.crt
    
    $ openssl x509 -in client.crt -text -noout | grep -i "Issuer:\|Subject:"
            Issuer: CN = kubernetes
            Subject: C = IN, ST = Some-State, O = Some-Organization, CN = user-ca-signed
    

If the above steps are fine for the user you created, you shall pass Authentication phase. But Authorization phase still needs to be configured using RBAC, ABAC or any other supported authorization mode, else you may still get HTTP error code: 403

$ kubectl get pods -v=6
I0123 16:59:41.350501   28553 helpers.go:203] server response object: [{
  ...
  "code": 403
}]
F0123 16:59:41.351080   28553 helpers.go:114] Error from server (Forbidden): pods is forbidden: User "user-ca-signed" cannot list resource "pods" in API group "" in the namespace "ns1": No policy matched.
  • Hello Ramesh, first of all thank you very much for your detailed answer. Unfortunately the config files in k3s are a bit different. I found the following file, which is hopefully the pendant to the default kubernetes installation. Found the file here: `/var/lib/rancher/k3s/server/cred/api-server.kubeconfig` But it doesn't contains the client-ca-file entry. Instead i have a `client-certificate: /var/lib/rancher/k3s/server/tls/client-kube-apiserver.crt` and a `certificate-authority: /var/lib/rancher/k3s/server/tls/server-ca.crt` – Manuel Jan 28 '20 at 10:34
  • Oh, and the issuere in the client-kube-apiserver.crt is another one. Funny part is, that i requested a csr with kubectl itself and approved it as well. Extracted the crt then, but the outcome is still another one. – Manuel Jan 28 '20 at 10:37
1

I finally found my answer in this ticket.

https://github.com/rancher/k3s/issues/684

The user huapox posted the following code:

[root@(⎈ |default:default) sec-rbac]$ cat t2.sh 
ws=/opt/sec-rbac
day=3650

clus_name="t1.k3s"
clus_ns="default"
user="koper"
#clus_url="https://10.200.100.183:7442"
clus_url="https://server:6443"  ##
ca_path=$ws/server/tls
rm -f $ca_path/*-ca.srl

ctx=gen && mkdir -p $ws/$ctx/{kube,keys} && cd $ws/$ctx
#############
ca1=client-ca
generate="keys/u-"$user
echo -e "\033[32m#>>GEN-KEY\033[0m"
#openssl genrsa -out $generate.key 2048
openssl ecparam -name prime256v1 -genkey -noout -out $generate.key
openssl req -new -key $generate.key -out $generate.csr -subj "/CN=${user}@${clus_name}/O=key-gen"
openssl x509 -req -in $generate.csr -CA $ca_path/$ca1.crt -CAkey $ca_path/$ca1.key -CAcreateserial -out $generate.crt -days $day

#-----------
#generate=$ca_path/client-admin  ##test
ca2=server-ca
embed=false
ctx2="$user@$clus_name"
config="kube/$user.kubeconfig"
echo -e "\033[32m#>>KUBE-CONFIG\033[0m" 
kubectl --kubeconfig=$config config set-cluster $clus_name --embed-certs=$embed --server=$clus_url --certificate-authority=$ca_path/$ca2.crt
kubectl --kubeconfig=$config config set-credentials $user --embed-certs=$embed --client-certificate=$generate.crt  --client-key=$generate.key
kubectl --kubeconfig=$config config set-context $ctx2 --cluster=$clus_name --namespace=$clus_ns --user=$user
kubectl --kubeconfig=$config config set current-context $ctx2
kubectl --kubeconfig=$config --context=$ctx2 get pods

Big thanks to huapox.

Manuel
  • 1,928
  • 2
  • 16
  • 26