Skip to content

marcuspaula-cloudsec/kubernetes-runtime-security

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Kubernetes Runtime Security

EKS cluster hardened from node to pod. Falco for runtime threat detection, Kyverno for policy enforcement, network policies for microsegmentation, pod security standards enforced — defense in depth for containerized workloads.

Architecture

  ┌─────────────────────────────────────────────────────┐
  │                    EKS Cluster                       │
  │                                                      │
  │  ┌──────────┐  ┌──────────┐  ┌──────────────────┐  │
  │  │ Kyverno  │  │  Falco   │  │  Network Policy  │  │
  │  │ Admission│  │  Runtime  │  │  (Calico/Cilium) │  │
  │  │ Control  │  │  Monitor  │  │                  │  │
  │  └────┬─────┘  └────┬─────┘  └────────┬─────────┘  │
  │       │              │                  │            │
  │  ┌────▼──────────────▼──────────────────▼────────┐  │
  │  │              Application Pods                  │  │
  │  │  ┌─────────┐  ┌─────────┐  ┌─────────┐      │  │
  │  │  │ Pod A   │  │ Pod B   │  │ Pod C   │      │  │
  │  │  │ non-root│  │ non-root│  │ non-root│      │  │
  │  │  │ ro-fs   │  │ ro-fs   │  │ ro-fs   │      │  │
  │  │  └─────────┘  └─────────┘  └─────────┘      │  │
  │  └───────────────────────────────────────────────┘  │
  └─────────────────────────────────────────────────────┘
          │                    │
    ┌─────▼──────┐      ┌─────▼──────┐
    │ CloudWatch │      │    SNS     │
    │   Logs     │      │   Alerts   │
    └────────────┘      └────────────┘

Security Layers

Layer Tool Purpose
Admission Kyverno Block non-compliant pods before they run
Runtime Falco Detect anomalous behavior inside running containers
Network Network Policies Microsegmentation — pods only talk to what they need
Pod Security PSS (Restricted) No root, no privilege escalation, read-only filesystem
Image Trivy Scan images for CVEs before deployment
Node Bottlerocket/hardened AMI Minimal OS attack surface

Kyverno Policies

Policy What It Blocks
disallow-privileged Containers running as privileged
require-non-root Containers running as root user
require-readonly-rootfs Writable root filesystem
disallow-host-namespaces hostPID, hostIPC, hostNetwork
restrict-image-registries Images from untrusted registries
require-labels Pods without mandatory labels (owner, team)
disallow-latest-tag Images using :latest tag

Falco Rules (Custom)

Rule Detects
Shell spawned in container Interactive shell (reverse shell, exec)
Sensitive file read /etc/shadow, /etc/passwd access
Outbound connection to crypto pool Cryptomining indicators
Binary downloaded and executed Malware staging pattern
Namespace admin binding created Privilege escalation attempt

Structure

.
├── README.md
├── architecture.png
├── terraform/
│   ├── eks-cluster.tf             # EKS with managed node groups
│   ├── eks-addons.tf              # CoreDNS, kube-proxy, VPC-CNI
│   ├── irsa.tf                    # IAM Roles for Service Accounts
│   └── variables.tf
├── kyverno/
│   ├── install.yaml               # Kyverno Helm values
│   └── policies/
│       ├── disallow-privileged.yaml
│       ├── require-non-root.yaml
│       ├── require-readonly-rootfs.yaml
│       ├── disallow-host-namespaces.yaml
│       ├── restrict-image-registries.yaml
│       ├── require-labels.yaml
│       └── disallow-latest-tag.yaml
├── falco/
│   ├── install.yaml               # Falco Helm values
│   ├── custom-rules.yaml          # Custom detection rules
│   └── alerting/
│       └── falco-sns-forwarder.yaml
├── network-policies/
│   ├── default-deny-all.yaml      # Deny all ingress/egress by default
│   ├── allow-dns.yaml             # Allow CoreDNS
│   ├── allow-app-to-db.yaml       # App → DB only
│   └── allow-ingress-controller.yaml
└── pod-security/
    ├── restricted-pss.yaml        # Pod Security Standard: Restricted
    └── namespace-labels.yaml      # Enforce PSS per namespace

Key Design Decisions

Why Kyverno over OPA/Gatekeeper

Kyverno uses native Kubernetes YAML — no Rego learning curve. Policies are readable by any K8s engineer. Supports mutation (auto-fix non-compliant resources) in addition to validation.

Why Default-Deny Network Policies

Kubernetes allows all pod-to-pod communication by default. A compromised pod can reach any service in the cluster. Default-deny inverts this — every connection must be explicitly allowed.

Why Pod Security Standards (Restricted)

The restricted profile enforces: non-root, no privilege escalation, read-only root filesystem, no host namespaces. This eliminates the most common container escape vectors.

Deployment

# 1. EKS cluster
cd terraform/ && terraform apply

# 2. Kyverno
helm install kyverno kyverno/kyverno -f kyverno/install.yaml

# 3. Kyverno policies
kubectl apply -f kyverno/policies/

# 4. Falco
helm install falco falcosecurity/falco -f falco/install.yaml

# 5. Network policies
kubectl apply -f network-policies/

Validation

# Test: try to run privileged pod (should be blocked by Kyverno)
kubectl run test --image=nginx --privileged=true
# Expected: admission webhook denied

# Test: verify Falco detects shell exec
kubectl exec -it <pod> -- /bin/sh
# Expected: Falco alert in CloudWatch

# Test: verify network isolation
kubectl exec -it app-pod -- curl db-service:5432
# Expected: allowed (explicit policy)
kubectl exec -it app-pod -- curl external-service:80
# Expected: blocked (default deny)

References


Built with Terraform + Helm + YAML | Defense in depth for K8s

About

EKS hardening with Falco, Kyverno, network policies, and pod security standards

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors