GKE CIS security control 6.6.4 requires clusters to be created with private endpoint enabled and public access disabled. When public access is disabled, CI/CD pipelines which need to deploy objects in the k8s cluster, not be able to.
This simple IAP proxy allows you to access a private GKE master control plane via the Identity Aware Proxy.
To deploy the IAP proxy you need the following:
- a google project id with a default network
- a GKE cluster with a private endpoint
- a Google DNS managed zone, which is publicly accessible
- a user you want to grant access
To configure your deployment, create a file .auto.tfvars
with the following content:
# project and region to deploy to IAP proxy into
project = "my-project"
region = "europe-west4"
## DNS managed zone accessible from the public internet
dns_managed_zone = "my-managed-zone"
## users you want to grant access via the IAP proxy
accessors = [
"user:[email protected]",
]
# support email address for the IAP brand.
# if there is an IAP brand in your project, make this empty string: ""
# To check whether you already have a brand, type `gcloud alpha iap oauth-brands list`
iap_support_email = "[email protected]"
To deploy the IAP proxy for GKE, type:
git clone https://github.com/binxio/simple-iap-proxy.git
cp .auto.tfvars simple-iap-proxy/examples/to-gke-cluster
terraform init
terraform apply
After the apply, the required IAP proxy command is printed:
iap_proxy_command = <<EOT
simple-iap-proxy client \
--target-url https://iap-proxy.google.binx.dev \
--iap-audience 1231123123-j9onig1ofcgle7iogv8fceu04v8hriuv.apps.googleusercontent.com \
--service-account [email protected] \
--key-file server.key \
--certificate-file server.crt \
--to-gke
EOT
To start the IAP proxy, you need a certificate. To generate a self-signed certificate, type:
simple-iap-proxy generate-certificate \
--key-file server.key \
--certificate-file server.crt
Or alternatively, use openssl:
openssl genrsa -out server.key 2048
openssl req -new -x509 -sha256 \
-key server.key \
-subj "/CN=simple-iap-proxy" \
-addext "subjectAltName = DNS:localhost" \
-days 3650 \
-out server.crt
Now you can start the proxy, by copying the command printed by terraform:
terraform output -raw iap_proxy_command | sh
The reason for the self-signed certificate is that kubectl will not send the credentials over HTTP.
To get the credentials for your cluster, type:
$ gcloud container clusters \
get-credentials cluster-1
To configure the kubectl access via the IAP proxy, type:
context_name=$(kubectl config current-context)
kubectl config set clusters.$context_name.certificate-authority-data $(base64 < server.crt)
kubectl config set clusters.$context_name.proxy-url https://localhost:8080
This points the context to the proxy and configure the self-signed certificate for the server.
Now you can use kubectl over IAP!
$ kubectl cluster-info dump
- The IAP protocol does not support websockets as Authorization header cannot be passed in. Commands which rely on websockets will fail (ie kubectl exec).