diff --git a/slides/exercises/ingress-secret-policy-details.md b/slides/exercises/ingress-secret-policy-details.md index 3e51d9f7..2d6dedaa 100644 --- a/slides/exercises/ingress-secret-policy-details.md +++ b/slides/exercises/ingress-secret-policy-details.md @@ -8,56 +8,86 @@ (by allowing attacker to access all secrets, including API tokens) +- See for instance [CVE-2021-25742](https://github.com/kubernetes/ingress-nginx/issues/7837) + - How can we prevent that? --- -## Preparation +## Step 1: Ingress Controller -- Deploy an ingress controller +- Deploy an Ingress Controller -- Deploy cert-manager - -- Create a ClusterIssuer using Let's Encrypt - - (suggestion: also create a ClusterIssuer using LE's staging env) + (e.g. Traefik or NGINX; you can use @@LINK[k8s/traefik-v2.yaml]) - Create a trivial web app (e.g. NGINX, `jpetazzo/color`...) +- Expose it with an Ingress + + (e.g. use `app..nip.io`) + +- Check that you can access it through `http://app..nip.io` + +--- + +## Step 2: cert-manager + +- Deploy cert-manager + +- Create a ClusterIssuer using Let's Encrypt staging environment + + (e.g. with @@LINK[k8s/cm-clusterissuer.yaml]) + - Create an Ingress for the app, with TLS enabled + (e.g. use `appsecure..nip.io`) + - Tell cert-manager to obtain a certificate for that Ingress - (suggestion: use the `cert-manager.io/cluster-issuer` annotation) + - option 1: manually create a Certificate (e.g. with @@LINK[k8s/cm-certificate.yaml]) + + - option 2: use the `cert-manager.io/cluster-issuer` annotation + +- Check that you get the Let's Encrypt certificate was issued --- -## Strategy +## Step 3: RBAC -- Remove the ingress controller's permission to read all Secrets +- Remove the Ingress Controller's permission to read all Secrets -- Grant selective access to Secrets +- Restart the Ingress Controller - (only give access to secrets that hold ingress TLS keys and certs) +- Check that https://appsecure doesn't serve the Let's Encrypt cert -- Automatically grant access by using Kyverno's "generate" mechanism +- Grant permission to read the certificate's Secret - (automatically create Role + RoleBinding when Certificate is created) - -- Bonus: think about threat model for an insider attacker - - (and how to mitigate it) +- Check that https://appsecure serve the Let's Encrypt cert again --- -## Goal +## Step 4: Kyverno -- When a Certificate (cert-manager CRD) is created, automatically create: +- Install Kyverno - - A Role granting read access to the Certificate's Secret +- Write a Kyverno policy to automatically grant permission to read Secrets - - A RoleBinding granting that Role to our Ingress controller + (e.g. when a cert-manager Certificate is created) -- Check that the Ingress controller TLS still works +- Check @@LINK[k8s/kyverno-namespace-setup.yaml] for inspiration -- ...But that the Ingress controller can't read other secrets +- Hint: you need to automatically create a Role and RoleBinding + +- Create another app + another Ingress with TLS + +- Check that the Certificate, Secret, Role, RoleBinding are created + +- Check that the new app correctly serves the Let's Encrypt cert + +--- + +## Step 5: double-check + +- Check that the Ingres Controller can't access other secrets + + (e.g. by manually creating a Secret and checking with `kubectl exec`?)