Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions labs/lab9/falco/rules/custom-rules.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Lab 9 — custom Falco rules

- rule: Write to /tmp by container
desc: Detect writes to /tmp inside any container (not host)
condition: >
open_write
and container
and fd.name startswith /tmp
output: >
Write to /tmp by container (container=%container.name user=%user.name
file=%fd.name command=%proc.cmdline)
priority: WARNING
tags: [container, drift]

- rule: Possible Cryptominer Activity
desc: Detect known cryptominer process names or mining-pool port connections
condition: >
spawned_process
and container
and (
proc.name in (xmrig, ethminer, cgminer, claymore)
or
(evt.type=connect and fd.sockfamily=ip and (fd.name endswith ":3333" or fd.name endswith ":4444" or fd.name endswith ":5555" or fd.name endswith ":7777"))
)
output: >
Possible Cryptominer Activity (container=%container.name process=%proc.name
user=%user.name cmdline=%proc.cmdline)
priority: CRITICAL
tags: [container, mitre_execution, mitre_command_and_control]
24 changes: 24 additions & 0 deletions labs/lab9/manifests/bad-pod-no-resources.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: bad-pod-no-resources
spec:
replicas: 1
selector:
matchLabels:
app: bad-pod-no-resources
template:
metadata:
labels:
app: bad-pod-no-resources
spec:
securityContext:
runAsNonRoot: true
containers:
- name: app
image: alpine@sha256:91ef0af9f435b5d41d6e8dac8e63f146d1c7b4a5f0a0c0e8e8e8e8e8e8e8e8e8e8
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
25 changes: 25 additions & 0 deletions labs/lab9/manifests/bad-pod-runasroot.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: bad-pod-runasroot
spec:
replicas: 1
selector:
matchLabels:
app: bad-pod-runasroot
template:
metadata:
labels:
app: bad-pod-runasroot
spec:
containers:
- name: app
image: alpine@sha256:91ef0af9f435b5d41d6e8dac8e63f146d1c7b4a5f0a0c0e8e8e8e8e8e8e8e8e8
securityContext:
runAsNonRoot: false
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
resources:
limits:
memory: "128Mi"
31 changes: 31 additions & 0 deletions labs/lab9/manifests/good-pod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: good-pod
spec:
replicas: 1
selector:
matchLabels:
app: good-pod
template:
metadata:
labels:
app: good-pod
spec:
securityContext:
runAsNonRoot: true
containers:
- name: app
image: alpine@sha256:91ef0af9f435b5d41d6e8dac8e63f146d1c7b4a5f0a0c0e8e8e8e8e8e8e8e8e8
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
resources:
requests:
cpu: "50m"
memory: "64Mi"
limits:
cpu: "100m"
memory: "128Mi"
56 changes: 56 additions & 0 deletions labs/lab9/policies/extra/hardening.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package main

import rego.v1

has_value(arr, v) if {
some i
arr[i] == v
}

# 1. runAsNonRoot must be true (pod-level or container-level)
deny contains msg if {
input.kind == "Deployment"
c := input.spec.template.spec.containers[_]
not run_as_non_root(c)
msg := sprintf("container %q must set runAsNonRoot: true (pod or container securityContext)", [c.name])
}

run_as_non_root(c) if {
c.securityContext.runAsNonRoot == true
}

run_as_non_root(c) if {
input.spec.template.spec.securityContext.runAsNonRoot == true
}

# 2. allowPrivilegeEscalation must be false (every container)
deny contains msg if {
input.kind == "Deployment"
c := input.spec.template.spec.containers[_]
not c.securityContext.allowPrivilegeEscalation == false
msg := sprintf("container %q must set allowPrivilegeEscalation: false", [c.name])
}

# 3. capabilities.drop must include "ALL" (every container)
deny contains msg if {
input.kind == "Deployment"
c := input.spec.template.spec.containers[_]
not has_value(c.securityContext.capabilities.drop, "ALL")
msg := sprintf("container %q must drop ALL capabilities", [c.name])
}

# 4. resources.limits.memory must be set
deny contains msg if {
input.kind == "Deployment"
c := input.spec.template.spec.containers[_]
not c.resources.limits.memory
msg := sprintf("container %q missing resources.limits.memory", [c.name])
}

# 5. image must use sha256 digest, not :tag
deny contains msg if {
input.kind == "Deployment"
c := input.spec.template.spec.containers[_]
not contains(c.image, "@sha256:")
msg := sprintf("container %q image must use @sha256: digest pinning, not tag", [c.name])
}
Loading