What is KubeArmor?

What is KubeArmor?

KubeArmor is a runtime security enforcement system for Kubernetes. It enhances the security of containerized applications by applying security policies at the system call level. These policies help control the behavior of containers, ensuring that only allowed actions are performed and protecting against malicious activities.

Architecture

Support Matrix

KubeArmor supports following types of workloads:

  1. K8s orchestrated: Workloads deployed as k8s orchestrated containers. In this case, Kubearmor is deployed as a k8s daemonset. Note, KubeArmor supports policy enforcement on both k8s-pods (KubeArmorPolicy) as well as k8s-nodes (KubeArmorHostPolicy).

  2. Containerized: Workloads that are containerized but not k8s orchestrated are supported. KubeArmor installed in systemd mode can be used to protect such workloads.

  3. VM/Bare-Metals: Workloads deployed on Virtual Machines or Bare Metal i.e. workloads directly operating as host/system processes. In this case, Kubearmor is deployed in systemd mode.

Run k3s cluster

curl -sfL https://get.k3s.io | sh - 
# Check for Ready node, takes ~30 seconds 
sudo k3s kubectl get node 
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml

Handson Securing Kubernetes Resources

Installation of Kuberarmor

helm repo add kubearmor https://kubearmor.github.io/charts
helm repo update kubearmor
helm upgrade --install kubearmor-operator kubearmor/kubearmor-operator -n kubearmor --create-namespace
kubectl apply -f https://raw.githubusercontent.com/kubearmor/KubeArmor/main/pkg/KubeArmorOperator/config/samples/sample-config.yml

Karmor CLI

curl -sfL http://get.kubearmor.io/ | sudo sh -s -- -b /usr/local/bin

Policy for Securing kubernetes cluster

kubectl create deployment nginx --image=nginx
POD=$(kubectl get pod -l app=nginx -o name)

Policy Violations notification using kArmor CLI

karmor logs -n default --json

Feature 1: Deny Execution of package management

Package managers can be utilized in the runtime environment to fetch new binaries, expanding the attack surface of the pods. Hackers often use these tools to download extra software (like masscan) to advance their objectives. It's advisable to disable package managers in production environments.

cat <<EOF | kubectl apply -f -
apiVersion: security.kubearmor.com/v1
kind: KubeArmorPolicy
metadata:
  name: block-pkg-mgmt-tools-exec
spec:
  selector:
    matchLabels:
      app: nginx
  process:
    matchPaths:
    - path: /usr/bin/apt
    - path: /usr/bin/apt-get
  action:
    Block
EOF

Now execute the apt command to download the masscan tool.

kubectl exec -it $POD -- bash -c "apt update && apt install masscan"

Feature 2 : Deny access to service account token

By default, Kubernetes mounts the service account token in every pod, even if no application uses it. Attackers can exploit these service account tokens to move laterally within the cluster.

kubectl exec -it $POD -- bash
(inside pod) $ curl https://$KUBERNETES_PORT_443_TCP_ADDR/api --insecure --header "Authorization: Bearer $(cat /run/secrets/kubernetes.io/serviceaccount/token)"
{                                
  "kind": "APIVersions",      
  "versions": [                 
    "v1"                      
  ],                          
  "serverAddressByClientCIDRs": [
    {
      "clientCIDR": "0.0.0.0/0",
      "serverAddress": "ip-10-0-48-51.us-east-2.compute.internal:443"
    }
  ]
}

Service Token are able to see

Lets apply a policy to block access to service account token:

cat <<EOF | kubectl apply -f -
apiVersion: security.kubearmor.com/v1
kind: KubeArmorPolicy
metadata:
  name: block-service-access-token-access
spec:
  selector:
    matchLabels:
      app: nginx
  file:
    matchDirectories:
    - dir: /run/secrets/kubernetes.io/serviceaccount/
      recursive: true
  action:
    Block
EOF

now anyone tries to access service token it get permission denied

kubectl exec -it $POD -- bash
(inside pod) $ curl https://$KUBERNETES_PORT_443_TCP_ADDR/api --insecure --header "Authorization: Bearer $(cat /run/secrets/kubernetes.io/serviceaccount/token)"
cat: /run/secrets/kubernetes.io/serviceaccount/token: Permission denied
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "forbidden: User \"system:anonymous\" cannot get path \"/api\"",
  "reason": "Forbidden",
  "details": {},
  "code": 403
}

Feature 3 : Block access for folder/paths

Access to certain folders/paths might have to be audited for compliance/reporting reasons.

File Visibility is disabled by default to minimize telemetry. Some file based policies will need that enabled. To enable file visibility on a namespace level:

kubectl annotate ns default kubearmor-visibility="process,file,network" --overwrite
cat <<EOF | kubectl apply -f -
apiVersion: security.kubearmor.com/v1
kind: KubeArmorPolicy
metadata:
  name: audit-etc-nginx-access
spec:
  selector:
    matchLabels:
      app: nginx
  file:
    matchDirectories:
    - dir: /etc/nginx/
      recursive: true  
  action:
    Audit
EOF

Feature 4: Zero Trust Least Permissive Policy: Allow Only Nginx to Execute in the Pod, Deny Everything Else

Least permissive policies require specifying allowed actions or operations and denying everything else. Using KubeArmor, you can create policies that define which actions are permitted and choose to either audit or deny the rest.

The security posture determines the handling of operations not on the allowed list: they can be either audited (allowed but alerted) or denied (blocked and alerted).

By default, the security posture is set to audit. Let's switch the security posture to default deny

# Change the security posture to default deny

kubectl annotate ns default kubearmor-file-posture=block --overwrite
cat <<EOF | kubectl apply -f -
apiVersion: security.kubearmor.com/v1
kind: KubeArmorPolicy
metadata:
  name: only-allow-nginx-exec
spec:
  selector:
    matchLabels:
      app: nginx
  file:
    matchDirectories:
    - dir: /
      recursive: true  
  process:
    matchPaths:
    - path: /usr/sbin/nginx
    - path: /usr/bin/bash
  action:
    Allow
EOF

Least permissive policies require one to allow certain actions/operations and deny rest. With KubeArmor it is possible to specify as part of the policy as to what actions should be allowed and deny/audit the rest.

Security Posture defines what happens to the operations that are not in the allowed list. Should it be audited (allow but alert), or denied (block and alert)?

kubectl exec -it $POD -- bash -c "chroot"

By default the security posture is set to audit. Lets change the security posture to default deny.Block Engress on pod

To block only egress traffic on port 8080 for a specific pod using KubeArmor, you can define a more granular policy. Here is how you can create and apply such a policy

Create a KubeArmor Policy: Create a KubeArmor policy in YAML format to block egress traffic on port 8080 for the identified pod. Save the following YAML content to a file named block-egress-port-8080.yaml:

apiVersion: security.kubearmor.com/v1
kind: KubeArmorPolicy
metadata:
  name: block-egress-port-8080
  namespace: <your-namespace> # Replace with your pod's namespace
spec:
  selector:
    matchLabels:
      app: <your-pod-label> # Replace with your pod's label
  egress:
  - action:
      Block: true
    protocol: TCP
    ports:
    - 8080
  • Replace <your-namespace> with the namespace of your pod and <your-pod-label> with the appropriate label of your pod.

  • Apply the Policy: Apply the policy using the kubectl apply command

  •         kubectl apply -f block-egress-port-8080.yaml
    
  • Verify the Policy: Verify that the policy has been applied and that egress traffic on port 8080 is blocked for the specified pod.

      kubectl get ksp -n <your-namespace>
    
    1. You can also check the logs to ensure that egress traffic on port 8080 is being blocked as expected.