RKE2 Image security Admission Controller
In a previous post we talked about Admission Controllers. In this post I will show you how to use an Admission Controller to test image vulnerabilities.
Parts of the K8S Security Lab series
Container Runetime Security
- Part1: How to deploy CRI-O with Firecracker?
- Part2: How to deploy CRI-O with gVisor?
- Part3: How to deploy containerd with Firecracker?
- Part4: How to deploy containerd with gVisor?
- Part5: How to deploy containerd with kata containers?
Advanced Kernel Security
- Part1: Hardening Kubernetes with seccomp
- Part2: Linux user namespace management wit CRI-O in Kubernetes
- Part3: Hardening Kubernetes with seccomp
Network Security
- Part1: RKE2 Install With Calico
- Part2: RKE2 Install With Cilium
- Part3: CNI-Genie: network separation with multiple CNI
- Part3: Configurre network wit nmstate operator
- Part3: Kubernetes Network Policy
- Part4: Kubernetes with external Ingress Controller with vxlan
- Part4: Kubernetes with external Ingress Controller with bgp
- Part4: Central authentication with oauth2-proxy
- Part5: Secure your applications with Pomerium Ingress Controller
- Part6: CrowdSec Intrusion Detection System (IDS) for Kubernetes
- Part7: Kubernetes audit logs and Falco
Secure Kubernetes Install
- Part1: Best Practices to keeping Kubernetes Clusters Secure
- Part2: Kubernetes Secure Install
- Part3: Kubernetes Hardening Guide with CIS 1.6 Benchmark
- Part4: Kubernetes Certificate Rotation
User Security
- Part1: How to create kubeconfig?
- Part2: How to create Users in Kubernetes the right way?
- Part3: Kubernetes Single Sign-on with Pinniped OpenID Connect
- Part4: Kubectl authentication with Kuberos Depricated !!
- Part5: Kubernetes authentication with Keycloak and gangway Depricated !!
- Part6: kube-openid-connect 1.0 Depricated !!
Image Security
Pod Security
- Part1: Using Admission Controllers
- Part2: RKE2 Pod Security Policy
- Part3: Kubernetes Pod Security Admission
- Part4: Kubernetes: How to migrate Pod Security Policy to Pod Security Admission?
- Part5: Pod Security Standards using Kyverno
- Part6: Kubernetes Cluster Policy with Kyverno
Secret Security
- Part1: Kubernetes and Vault integration
- Part2: Kubernetes External Vault integration
- Part3: ArgoCD and kubeseal to encript secrets
- Part4: Flux2 and kubeseal to encrypt secrets
- Part5: Flux2 and Mozilla SOPS to encrypt secrets
Monitoring and Observability
- Part6: K8S Logging And Monitoring
- Part7: Install Grafana Loki with Helm3
Backup
There is multiple tools to scan vulnerabilities, but less Admission Controller to use them. I found multiple solution for Anchore Engine so the first step is to deploy with its helm chart. In RKE2 I will use Rancher’s Helm controller what is preinstalled.
Then we can Deploy an Admission Controller to us this tool to automaticle scann any image deploy in the cluster and reject if is vulnerable. As I sad before there is multiple solution for this. One is Anchore’s own Admission Controller but I will use Banzaicloud’s solution because this easier to deploy. Sadly anchore-image-validator run as root so we need to use my predifinde PSP to allow this.
nano /var/lib/rancher/rke2/server/manifests/10_image-security.yaml
---
apiVersion: v1
kind: Namespace
metadata:
name: securty-system
---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: anchore-enginn
namespace: kube-system
spec:
repo: "https://charts.anchore.io"
chart: anchore-engine
targetNamespace: securty-system
valuesContent: |-
postgresql:
postgresPassword: Password1
persistence:
size: 10Gi
anchoreGlobal:
defaultAdminPassword: Password1
defaultAdminEmail: devopstales@mydomain.intra
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: psp-rolebinding-securty-system
namespace: securty-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system-unrestricted-psp-role
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:serviceaccounts
---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: anchore-policy-validator
namespace: kube-system
spec:
repo: "https://kubernetes-charts.banzaicloud.com"
chart: anchore-policy-validator
targetNamespace: securty-system
valuesContent: |-
externalAnchore:
anchoreHost: "http://anchore-enginn-anchore-engine-api:8228/v1/"
anchoreUser: admin
anchorePass: Password1
rbac:
psp:
enabled: true
createPolicies: true
During deploying this chart, it’s creating predefined policy bundles and activates AllowAll
by default if createPolicies
flag is set.
Bundle Name | Description |
---|---|
Allow all and warn bundle | Allow all images and warn if vulnerabilities are found |
Reject critical bundle | Reject deploying images that contain critical vulnerabiliy |
Reject high bundle | Reject deploying images that contain high vulnerabiliy |
Block root bundle | Block deploying images that using root as effective user |
Deny all images | Deny all imagest to deploy |
Test the Admission Controller
kubectl run --image=busybox -- sleep 3600
Error from server: admission webhook "pods.anchore-policy-validator.admission.banzaicloud.com" denied the request: Image failed policy check: busybox
kubectl describe audits busybox1
Name: busybox1
Namespace:
Labels: fakerelease=true
Annotations: <none>
API Version: security.banzaicloud.com/v1alpha1
Kind: Audit
Metadata:
Creation Timestamp: 2020-11-29T10:20:41Z
Generation: 1
Managed Fields:
API Version: security.banzaicloud.com/v1alpha1
Fields Type: FieldsV1
fieldsV1:
f:metadata:
f:labels:
.:
f:fakerelease:
f:spec:
.:
f:action:
f:image:
f:releaseName:
f:resource:
f:result:
f:status:
.:
f:state:
Manager: anchore-image-validator
Operation: Update
Time: 2020-11-29T10:20:41Z
Resource Version: 39174
Self Link: /apis/security.banzaicloud.com/v1alpha1/audits/busybox1
UID: 1e90c8b0-fffa-45f6-a986-d9fd269f0a83
Spec:
Action: reject
Image:
Image Digest:
Image Name:
Image Tag:
Last Updated:
Release Name: busybox1
Resource: Pod
Result:
Image failed policy check: busybox
Status:
State:
Events: <none>
The default policy is deny All Image theat failed on policy check but we can white list a specific image or set createPolicies
to true
in Banzaicloud’s Helm chart to create default AllowAll Policy.
kubectl apply -f - << EOF
apiVersion: security.banzaicloud.com/v1alpha1
kind: WhiteListItem
metadata:
name: busybox1
spec:
reason: testing
creator: devopstales-sa
EOF
kubectl run busybox1 --image=busybox -- sleep 3600
pod/busybox1 created
kubectl get whitelistitems -o wide -o=custom-columns=NAME:.metadata.name,CREATOR:.spec.creator,REASON:.spec.reason
NAME CREATOR REASON
busybox1 devopstales-sa testing
kubectl get audits -o wide -o=custom-columns=NAME:.metadata.name,RELEASE:.spec.releaseName,IMAGES:.spec.image,RESULT:.spec.result
NAME RELEASE IMAGES RESULT
busybox1 busybox1 [map[imageDigest: imageName: imageTag: lastUpdated:]] [Image failed policy check: busybox]
You can find the config files in my github repo: https://github.com/devopstales/k8s_sec_lab