Container & Kubernetes Security
Cloud-Native Security Tools
4 min read
Runtime detection, policy enforcement, and admission control are essential layers in Kubernetes security. Tools like Falco, OPA/Gatekeeper, and Kyverno provide defense-in-depth for cloud-native workloads.
Runtime Threat Detection
Falco - Runtime Security
Falco detects anomalous behavior at runtime by monitoring system calls:
# Falco installation via Helm
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm install falco falcosecurity/falco \
--set falco.grpc.enabled=true \
--set falco.grpcOutput.enabled=true
Default detection rules:
# Detect shell spawned in container
- rule: Terminal shell in container
desc: Detect shell execution in a container
condition: >
spawned_process and container and
shell_procs and proc.tty != 0 and
container_entrypoint
output: >
Shell spawned in container (user=%user.name container=%container.name
shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline)
priority: NOTICE
tags: [container, shell, mitre_execution]
# Detect sensitive file access
- rule: Read sensitive file in container
desc: Attempt to read sensitive files like /etc/shadow
condition: >
open_read and container and
sensitive_files and not proc.name in (allowed_readers)
output: >
Sensitive file read in container (user=%user.name
file=%fd.name container=%container.name)
priority: WARNING
tags: [container, filesystem, mitre_credential_access]
Custom Falco Rules
# Detect cryptocurrency mining
- rule: Detect crypto mining process
desc: Detect processes commonly associated with crypto mining
condition: >
spawned_process and container and
proc.name in (xmrig, minerd, cpuminer, cgminer, bfgminer)
output: >
Crypto mining process detected (user=%user.name container=%container.name
process=%proc.name cmdline=%proc.cmdline)
priority: CRITICAL
tags: [container, crypto, mitre_resource_hijacking]
# Detect outbound connection to suspicious ports
- rule: Outbound connection to mining pool
desc: Detect connections to common mining pool ports
condition: >
outbound and container and
fd.sport in (3333, 4444, 5555, 7777, 8888, 9999)
output: >
Suspicious outbound connection (container=%container.name
connection=%fd.name)
priority: WARNING
Policy Enforcement with OPA Gatekeeper
Gatekeeper Architecture
┌─────────────────────────────────────────────────────┐
│ Kubernetes API │
└──────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ Admission Webhook │
│ ┌─────────────────────────────────────────────┐ │
│ │ OPA Gatekeeper │ │
│ │ ┌──────────────┐ ┌──────────────────────┐ │ │
│ │ │ Constraint │ │ ConstraintTemplate │ │ │
│ │ │ (Instance) │ │ (Policy Definition) │ │ │
│ │ └──────────────┘ └──────────────────────┘ │ │
│ └─────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
Installing Gatekeeper
# Install Gatekeeper
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/v3.14.0/deploy/gatekeeper.yaml
# Verify installation
kubectl get pods -n gatekeeper-system
Constraint Templates and Constraints
Require labels on all resources:
# ConstraintTemplate - defines the policy schema
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
spec:
crd:
spec:
names:
kind: K8sRequiredLabels
validation:
openAPIV3Schema:
type: object
properties:
labels:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
violation[{"msg": msg}] {
provided := {label | input.review.object.metadata.labels[label]}
required := {label | label := input.parameters.labels[_]}
missing := required - provided
count(missing) > 0
msg := sprintf("Missing required labels: %v", [missing])
}
---
# Constraint - applies the policy
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: require-team-label
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
parameters:
labels: ["team", "environment"]
Block privileged containers:
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8sblockprivileged
spec:
crd:
spec:
names:
kind: K8sBlockPrivileged
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8sblockprivileged
violation[{"msg": msg}] {
c := input.review.object.spec.containers[_]
c.securityContext.privileged == true
msg := sprintf("Privileged container not allowed: %v", [c.name])
}
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sBlockPrivileged
metadata:
name: block-privileged-containers
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
Kyverno - Kubernetes Native Policy Engine
Kyverno Advantages
| Feature | Kyverno | OPA Gatekeeper |
|---|---|---|
| Language | YAML (native K8s) | Rego (learning curve) |
| Mutation | Built-in | Separate admission |
| Generation | Create resources | Not supported |
| Complexity | Lower | Higher |
Kyverno Policy Examples
Require resource limits:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-resource-limits
spec:
validationFailureAction: Enforce
rules:
- name: check-resource-limits
match:
any:
- resources:
kinds:
- Pod
validate:
message: "CPU and memory limits are required"
pattern:
spec:
containers:
- resources:
limits:
memory: "?*"
cpu: "?*"
Auto-add labels (mutation):
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-default-labels
spec:
rules:
- name: add-team-label
match:
any:
- resources:
kinds:
- Pod
mutate:
patchStrategicMerge:
metadata:
labels:
managed-by: kyverno
+(team): platform
Admission Controllers
Built-in Admission Controllers
# Check enabled admission controllers
kubectl api-versions | grep admission
# Key admission controllers
# - PodSecurity (replaces PodSecurityPolicy)
# - ResourceQuota
# - LimitRanger
# - ValidatingAdmissionWebhook
# - MutatingAdmissionWebhook
Validating Webhook Example
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: image-policy-webhook
webhooks:
- name: validate.images.example.com
admissionReviewVersions: ["v1"]
sideEffects: None
clientConfig:
service:
name: image-policy-service
namespace: security
path: "/validate"
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
failurePolicy: Fail
matchPolicy: Exact
Security Tool Comparison
| Capability | Falco | Gatekeeper | Kyverno |
|---|---|---|---|
| Runtime detection | Yes | No | No |
| Admission control | No | Yes | Yes |
| Policy language | YAML/JSON | Rego | YAML |
| Resource mutation | No | Limited | Yes |
| Resource generation | No | No | Yes |
| System call monitoring | Yes | No | No |
Next, we'll cover supply chain security including image signing, SBOM, and vulnerability management. :::