jan-karel.com
Home / Security Measures / Cloud Security / Container Hardening

Container Hardening

Container Hardening

Container Hardening

Cloud Fast, Cloud Tight

Cloud environments change rapidly. That is why security here must move along by default and in an automated fashion.

For Container Hardening, automation is leading: guardrails in code, least privilege, and continuous drift control.

This way you maintain speed in the cloud, without security becoming dependent on manual luck.

Immediate measures (15 minutes)

Why this matters

The core of Container Hardening is risk reduction in practice. Technical context supports the choice of measures, but implementation and safeguarding are central.

Defensive measures

It would be irresponsible to only describe attack techniques without addressing the defences. Here is what actually works – and what is nothing more than security theatre.

Pod Security Standards

Kubernetes Pod Security Standards (PSS) replace the older PodSecurityPolicies and define three levels:

Level Description What it blocks
Privileged No restrictions Nothing – everything is allowed
Baseline Minimal restrictions Privileged containers, hostNetwork, hostPID, hostIPC
Restricted Maximum restrictions Root user, all host namespaces, privilege escalation, capabilities
# Enforcement via namespace labels
apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

Network Policies

# Default deny all ingress en egress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

---
# Sta alleen specifiek verkeer toe
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-webapp-to-db
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: database
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: webapp
    ports:
    - protocol: TCP
      port: 5432

---
# Blokkeer metadata service (cruciaal in cloud!)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: block-metadata
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0
        except:
        - 169.254.169.254/32

Tip: Network Policies only work if the CNI plugin supports them. Calico, Cilium, and WeaveNet support them. Flannel does not by default. Always check which CNI plugin is active before assuming that Network Policies are being enforced.

Runtime security: Falco

Falco is a runtime security tool that monitors syscalls and generates alerts on suspicious behaviour:

# Falco rule: detect container escape attempts
- rule: Container Escape via Mount
  desc: Detect mounting of the host filesystem from within a container
  condition: >
    evt.type = mount and container and
    evt.arg.source startswith "/dev/sd"
  output: >
    Container escape attempt detected
    (user=%user.name container=%container.name
     image=%container.image.repository
     source=%evt.arg.source)
  priority: CRITICAL

- rule: Docker Socket Accessed in Container
  desc: Detect access to the Docker socket from within a container
  condition: >
    evt.type in (open, openat) and
    container and fd.name = /var/run/docker.sock
  output: >
    Docker socket accessed from within container
    (user=%user.name container=%container.name
     image=%container.image.repository)
  priority: WARNING

Image scanning

# Trivy - vulnerability scanner
trivy image TARGET_IMAGE
trivy image --severity CRITICAL,HIGH TARGET_IMAGE

# Grype
grype TARGET_IMAGE

# Snyk
snyk container test TARGET_IMAGE

# In CI/CD pipeline:
# Block images with CRITICAL vulnerabilities
trivy image --exit-code 1 --severity CRITICAL TARGET_IMAGE

Reference table

Technique Category MITRE ATT&CK Complexity
Docker socket escape Container Escape T1611 - Escape to Host Low
Privileged container escape Container Escape T1611 Low
Cgroup release_agent Container Escape T1611 Medium
nsenter host escape Container Escape T1611 Low
Kernel exploit (container) Container Escape T1068 - Exploitation for Privilege Escalation High
runc overwrite (CVE-2019-5736) Container Escape T1611 Medium
Image layer secret extraction Credential Access T1552.001 - Credentials In Files Low
Registry enumeration Discovery T1613 - Container and Resource Discovery Low
Registry image poisoning Persistence T1525 - Implant Internal Image Medium
K8s API unauthenticated access Initial Access T1190 - Exploit Public-Facing Application Low
K8s secret theft Credential Access T1552.007 - Container API Low
K8s RBAC escalation Privilege Escalation T1078.001 - Default Accounts Medium
K8s pod creation escape Privilege Escalation T1610 - Deploy Container Medium
etcd credential dump Credential Access T1552.007 Medium
Metadata service abuse Credential Access T1552.005 - Cloud Instance Metadata API Low
DNS spoofing in cluster Collection T1557 - Adversary-in-the-Middle Medium
Service mesh bypass Defense Evasion T1562.001 - Disable or Modify Tools Medium
Admission controller bypass Defense Evasion T1562.001 High
CI/CD base image poisoning Supply Chain T1195.002 - Compromise Software Supply Chain Medium
Build pipeline compromise Execution T1204.003 - Malicious Image Medium

In the next chapter we leave the container and look at the system that builds, tests, and deploys those containers: the CI/CD pipeline. If containers are the cells in our digital prison, then the CI/CD pipeline is the factory that builds the cells. And that factory, it turns out, has its own doors and windows that aren't locked.

Op de hoogte blijven?

Ontvang maandelijks cybersecurity-inzichten in je inbox.

← Cloud Security ← Home