diff --git a/k8s/kyverno-tls-for-ingress.yaml b/k8s/kyverno-tls-for-ingress.yaml new file mode 100644 index 00000000..5e99ee8c --- /dev/null +++ b/k8s/kyverno-tls-for-ingress.yaml @@ -0,0 +1,46 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: tls-for-ingress +spec: + rules: + - name: create-role + match: + resources: + kinds: + - Certificate + generate: + kind: Role + apiVersion: rbac.authorization.k8s.io/v1 + name: "{{request.object.metadata.name}}" + namespace: "{{request.object.metadata.namespace}}" + data: + rules: + - verbs: + - get + apiGroups: + - "" + resources: + - secrets + resourceNames: + - "{{request.object.metadata.name}}" + - name: create-rolebinding + match: + resources: + kinds: + - Certificate + generate: + kind: RoleBinding + apiVersion: rbac.authorization.k8s.io/v1 + name: "{{request.object.metadata.name}}" + namespace: "{{request.object.metadata.namespace}}" + data: + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: "{{request.object.metadata.name}}" + subjects: + - kind: ServiceAccount + name: default + namespace: "{{request.object.metadata.namespace}}" + diff --git a/slides/exercises/ingress-secret-policy-brief.md b/slides/exercises/ingress-secret-policy-brief.md new file mode 100644 index 00000000..b7900f40 --- /dev/null +++ b/slides/exercises/ingress-secret-policy-brief.md @@ -0,0 +1,15 @@ +## Exercise - Ingress Secret Policy + +*Implement policy to limit impact of ingress controller vulnerabilities.* + +(Mitigate e.g. CVE-2021-25742) + +- Deploy an ingress controller and cert-manager + +- Deploy a trivial web app secured with TLS + + (obtaining a cert with cert-manager + Let's Encrypt) + +- Prevent ingress controller from reading arbitrary secrets + +- Automatically grant selective access to TLS secrets, but not other secrets diff --git a/slides/exercises/ingress-secret-policy-details.md b/slides/exercises/ingress-secret-policy-details.md new file mode 100644 index 00000000..f3db5868 --- /dev/null +++ b/slides/exercises/ingress-secret-policy-details.md @@ -0,0 +1,63 @@ +# Exercise - Ingress Secret Policy + +- Most ingress controllers have access to all Secrets + + (so that they can access TLS keys and certs, which are stored in Secrets) + +- Ingress controller vulnerability can lead to full cluster compromise + + (by allowing attacker to access all secrets, including API tokens) + +- How can we prevent that? + +--- + +## Preparation + +- Deploy an ingress controller + +- Deploy cert-manager + +- Create a ClusterIssuer using Let's Encrypt + + (suggestion: also create a ClusterIssuer using LE's staging env) + +- Create a trivial web app (e.g. NGINX, `jpetazzo/color`...) + +- Create an Ingress for the app, with TLS enabled + +- Tell cert-manager to obtain a certificate for that Ingress + + (suggestion: use the `cert-manager.io/cluster-issuer` annotation) + +--- + +## Strategy + +- Remove the ingress controller's permission to read all Secrets + +- Grant selective access to Secrets + + (only give access to secrets that hold ingress TLS keys and certs) + +- Automatically grant access by using Kyverno's "generate" mechanism + + (automatically create Role + RoleBinding when Certificate is created) + +- Bonus: think about threat model for an insider attacker + + (and how to mitigate it) + +--- + +## Goal + +- When a Certificate (cert-manager CRD) is created, automatically create: + + - A Role granting read access to the Certificate's Secret + + - A RoleBinding granting that Role to our Ingress controller + +- Check that the Ingress controller TLS still works + +- ...But that the Ingress controller can't read other secrets