Created
January 23, 2025 19:32
-
-
Save Baarsgaard/49302e4b302860f740fb54d96f84297a to your computer and use it in GitHub Desktop.
Create new User kubeconfig using cert based authentication, requires a working kubeconfig with permission to create and sign `certificatesigningrequests`
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 -euo pipefail | |
| # Usage: | |
| USER="$1" | |
| ROLE="${2:-cluster-admin}" | |
| NAMESPACE="${3:-default}" | |
| log() { | |
| LVL="$1" | |
| MSG="$2" | |
| EXIT="${3:-}" | |
| # Log everything to stderr to not mix it with the final kubeconfig | |
| >&2 echo "$(date --iso-8601=seconds) $LVL $MSG" | |
| if [[ -n "$EXIT" ]]; then | |
| exit $EXIT | |
| fi | |
| } | |
| log info "Generating rsa key" | |
| openssl genrsa -out "$USER.key" 4096 | |
| log info "Generating Certificate Signing Request" | |
| openssl req -new -key "$USER.key" -nodes -out "$USER.csr" -config <(cat << CSRCNF | |
| [ req ] | |
| default_bits = 2048 | |
| prompt = no | |
| default_md = sha256 | |
| distinguished_name = dn | |
| [ dn ] | |
| CN = $USER | |
| O = developers | |
| [ v3_ext ] | |
| authorityKeyIdentifier=keyid,issuer:always | |
| basicConstraints=CA:FALSE | |
| keyUsage=keyEncipherment,dataEncipherment | |
| extendedKeyUsage=serverAuth,clientAuth | |
| CSRCNF | |
| ) | |
| CSR_B64="$(base64 -w 0 "$USER.csr")" | |
| log info "Create and apply Certificate Signing Request manifest" | |
| >/dev/null kubectl apply -f - << K8SCSR | |
| apiVersion: certificates.k8s.io/v1 | |
| kind: CertificateSigningRequest | |
| metadata: | |
| name: $USER-$ROLE | |
| namespace: $NAMESPACE | |
| spec: | |
| signerName: kubernetes.io/kube-apiserver-client | |
| groups: | |
| - system:authenticated | |
| request: $CSR_B64 | |
| usages: | |
| - client auth | |
| K8SCSR | |
| log info "Approve and Sign Certificate" | |
| >/dev/null kubectl certificate approve -n "$NAMESPACE" "$USER-$ROLE" | |
| log info "Get Certificate" | |
| kubectl get csr "$USER-$ROLE" -o jsonpath='{.status.certificate}' | base64 -d > "$USER.crt" | |
| >/dev/null kubectl delete csr "$USER-$ROLE" | |
| log info "Reading current kubeconfig" | |
| CURRENT_KUBECONFIG="$(kubectl config view --raw)" | |
| # Get current context | |
| CURRENT_CONTEXT="$(kubectl config current-context)" | |
| # Use name of context to find cluster name | |
| CLUSTER_NAME="$(yq ".contexts[] | select(.name == \"$CURRENT_CONTEXT\") | .context.cluster" <(echo "$CURRENT_KUBECONFIG"))" | |
| log info "Saving connection parameters to $USER.kubeconfig" | |
| >/dev/null kubectl config set-cluster "$CLUSTER_NAME" \ | |
| --kubeconfig="$USER.kubeconfig" \ | |
| --server="$(yq ".clusters[] | select(.name == \"$CLUSTER_NAME\") | .cluster.server" <(echo "$CURRENT_KUBECONFIG"))" \ | |
| --certificate-authority=<(:|openssl s_client -connect 127.0.0.1:41233 | grep -A 40 'BEGIN CERTIFICATE' | grep -B 40 'END CERTIFICATE') \ | |
| --embed-certs=true | |
| log info "Saving credentials(certificate) to $USER.kubeconfig" | |
| >/dev/null kubectl config set-credentials "$USER" \ | |
| --kubeconfig="$USER.kubeconfig" \ | |
| --client-certificate="$USER.crt" \ | |
| --client-key="$USER.key" \ | |
| --embed-certs=true | |
| log info "Saving $USER<->$CLUSTER_NAME context to $USER.kubeconfig" | |
| >/dev/null kubectl config set-context "$USER" \ | |
| --kubeconfig="$USER.kubeconfig" \ | |
| --cluster="$CLUSTER_NAME" \ | |
| --namespace="$NAMESPACE" \ | |
| --user="$USER" | |
| >/dev/null kubectl config use-context "$USER" \ | |
| --kubeconfig="$USER.kubeconfig" | |
| # Assign permissions to User as the last step | |
| kubectl apply -f - << CRB | |
| apiVersion: rbac.authorization.k8s.io/v1 | |
| kind: ClusterRoleBinding | |
| metadata: | |
| name: "$USER" | |
| roleRef: | |
| apiGroup: rbac.authorization.k8s.io | |
| kind: ClusterRole | |
| name: "$ROLE" | |
| subjects: | |
| - kind: User | |
| name: "$USER" | |
| apiGroup: rbac.authorization.k8s.io | |
| CRB | |
| log info "Test new kubeconfig: kubectl --kubeconfig $USER.kubeconfig get pods -n $NAMESPACE" | |
| >&2 kubectl config view --kubeconfig="$USER.kubeconfig" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment