RKE2 Image security Admission Controller

Page content

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
Advanced Kernel Security
Container Network Security
Secure Kubernetes Install
User Security

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