Skip to content

Instantly share code, notes, and snippets.

@henning
Created September 27, 2017 12:25
Show Gist options
  • Save henning/2dda0b704426c66e78e355703a8dc177 to your computer and use it in GitHub Desktop.
Save henning/2dda0b704426c66e78e355703a8dc177 to your computer and use it in GitHub Desktop.
create k8s user, certificate, permissions and client config
#!/bin/bash
CLUSTERNAME=mycluster.mydomain
NAMESPACE=default
USERNAME=myclusteruser
GROUPNAME=mygroup
openssl genrsa -out ${USERNAME}.key 2048
CSR_FILE=$USERNAME.csr
KEY_FILE=$USERNAME.key
openssl req -new -key $KEY_FILE -out $CSR_FILE -subj "/CN=$USERNAME/O=$GROUPNAME"
CERTIFICATE_NAME=$USERNAME.$NAMESPACE
cat <<EOF | kubectl create -f -
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
name: $CERTIFICATE_NAME
spec:
groups:
- system:authenticated
request: $(cat $CSR_FILE | base64 | tr -d '\n')
usages:
- digital signature
- key encipherment
- server auth
EOF
kubectl certificate approve $CERTIFICATE_NAME
CRT_FILE=$USERNAME.crt
kubectl get csr $CERTIFICATE_NAME -o jsonpath='{.status.certificate}' | base64 -D > $CRT_FILE
cat <<EOF | kubectl create -f -
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
namespace: $NAMESPACE
name: deployment-manager
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["deployments", "replicasets", "pods"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] # You can also use ["*"]
EOF
cat <<EOF | kubectl create -f -
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: $USERNAME-deployment-manager-binding
namespace: $NAMESPACE
subjects:
- kind: User
name: $USERNAME
apiGroup: ""
roleRef:
kind: Role
name: deployment-manager
apiGroup: ""
EOF
kubectl config set-credentials $USERNAME \
--client-certificate=$(pwd)/$CRT_FILE \
--client-key=$(pwd)/$KEY_FILE
kubectl config set-context $USERNAME-context --cluster=$CLUSTERNAME --namespace=$NAMESPACE --user=$USERNAME
@hustshawn
Copy link

hustshawn commented May 30, 2019

Hi, I found your script and just modified a little bit according to my requirement. But just found, if I configured the user with the certs that issued by k8s api, it just cannot be authenticated by API server. And it is just simply indicated

No resources found.
error: You must be logged in to the server (Unauthorized)

How about your result?
Here is the script I used.

@hustshawn
Copy link

I suspect that the key which API server used to sign the request is not matched with that used in the API server authentication, or just the certificate chain issue that I should have to find an intermediate certificate and should be attached with the obtained certificate to make a cert chain.

@markAcomm
Copy link

markAcomm commented Jul 17, 2019

Thank you for posting this script. It is by far the most concise recipe I have seen yet.

This script is signing the certificate as if it was a to be used by a server, not a user. As such, it won't work for clients. The "server auth" on line 29 needs to be changed to "client auth"

@hustshawn
Copy link

It works now. Thank you so much for your instruction. May I know where can I find the related document that mentions the details about server auth and client auth? I once read the official document here, just not realized the issue here.

@markAcomm
Copy link

As I said, there are not good recipes available for doing this. Most of the Kubernetes documentation is focused on helping services communicate with each other securely. I found a KOPS or Kubenetes Jira ticket (cannot remember which) that mentioned it.

The list of valid Key Usages I found here: https://godoc.org/k8s.io/kubernetes/pkg/apis/certificates#KeyUsage

@henning
Copy link
Author

henning commented Jul 20, 2019

Hi guys!
Thanks for your updates and hints on this!
I'm currently not working with any kubernetes installation, so I have no possibilities (and time) to test and comment on these things... actually I dont even remember completely how I wrote it.
Vaguely I remember it's partly command copied from some kubernetes docs(2 years ago!), banged together in one script and made more flexible with the variables so it can be executed simply and repeatedly, without error-prone manual interaction.
It's 2 years old, so i'm, surprised it still works halfway for a fast changing software as k8s. Also, I think I remember being surprised that a thing as "create a user" needed such a lot of additional scripting - and I'm again surprised this is still the case.
But great if this helped you a bit.

Hope sometime I will be able to play with k8s stuff again and try your changes :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment