Last active
September 19, 2021 16:01
-
-
Save marcbachmann/fb03ea3780c97d146c822c90b461400f to your computer and use it in GitHub Desktop.
Kubernetes create user certificate
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -e | |
USERNAME=$1 | |
if ! grep -qE '^[a-zA-Z0-9.@\-\+_]{2,100}$' <<< "$USERNAME"; then | |
1>&2 echo -e "❌ Username is missing or contains invalid characters | |
Usage: ./kubernetes-create-user.sh [email protected] | |
Will create a certificate using subject '/[email protected]' | |
and write the credentials into the '[email protected]' file." | |
exit 1 | |
fi | |
CERT_KEY="$(openssl genrsa 2048 2> /dev/null)" | |
CERT_CSR=$(openssl req -new -subj "/CN=$USERNAME" -key /dev/stdin <<< "$CERT_KEY") | |
cat <<EOF | 1>/dev/null kubectl apply -f - | |
apiVersion: certificates.k8s.io/v1 | |
kind: CertificateSigningRequest | |
metadata: | |
name: $USERNAME | |
spec: | |
groups: [system:authenticated] | |
request: $(base64 <<< "$CERT_CSR" | tr -d "\n") | |
signerName: kubernetes.io/kube-apiserver-client | |
usages: [client auth] | |
EOF | |
1>&2 kubectl certificate approve $USERNAME > /dev/null | |
CERT_CRT="$(kubectl wait --for=condition=Approved=true csr/$USERNAME -o jsonpath="{.status.certificate}" | base64 -d)" | |
if [ "$CERT_CRT" == "" ]; then | |
# There is some kind of bug in kubernetes where | |
# the certificate is not present right after approval | |
# and there is no state to wait for. | |
sleep 1 | |
CERT_CRT="$(kubectl wait --for=condition=Approved=true csr/$USERNAME -o jsonpath="{.status.certificate}" | base64 -d)" | |
if [ "$CERT_CRT" == "" ]; then | |
1>&2 echo "❌ Failed to extract certificate. Try again." | |
kubectl delete csr $USERNAME > /dev/null | |
exit 1 | |
fi | |
fi | |
kubectl delete csr $USERNAME > /dev/null | |
CLUSTER_NAME=$(kubectl config view --minify --raw -o jsonpath="{.clusters[0].name}") | |
CLUSTER_CA=$(kubectl config view --minify --raw -o jsonpath="{.clusters[0].cluster['certificate-authority-data']}") | |
CLUSTER_SERVER=$(kubectl config view --minify --raw -o jsonpath="{.clusters[0].cluster['server']}") | |
cat <<EOF > $USERNAME.kubeconfig | |
apiVersion: v1 | |
kind: Config | |
current-context: $USERNAME@$CLUSTER_NAME | |
clusters: | |
- cluster: | |
certificate-authority-data: $CLUSTER_CA | |
server: $CLUSTER_SERVER | |
name: $CLUSTER_NAME | |
contexts: | |
- context: | |
cluster: $CLUSTER_NAME | |
user: $USERNAME | |
name: $USERNAME@$CLUSTER_NAME | |
users: | |
- name: $USERNAME | |
user: | |
client-certificate-data: $(base64 <<< "$CERT_CRT") | |
client-key-data: $(base64 <<< "$CERT_KEY") | |
EOF | |
1>&2 echo -e "✅ Kubernetes config written to '$USERNAME.kubeconfig'. | |
Test it using: \033[1mKUBECONFIG=$USERNAME.kubeconfig kubectl describe nodes\033[0m | |
Declare \033[1mrole bindings\033[0m manually to assign permissions before using it." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment