CKS Guide
The 4C's of cloud native computing
The 4C's of cloud native computing represent security in depth where each "C" stands for level of isolation from outside in.
| Layer | Description |
|---|---|
| Cloud | Security of entire infrastructure hosting the servers. Public/Private etc. |
| Cluster | Kubernetes cluster |
| Container | Docker containers. Running, for example in privilege mode. |
| Code | Binaries, source code, code configuration, no TLS, variables in code, etc. |
Admission controllers
Image policy webhook
Admission configuration
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: ImagePolicyWebhook
configuration:
imagePolicy:
kubeConfigFile: <path-to-kubeconfig-file>
allowTTL: 50
denyTTL: 50
retryBackoff: 500
defaultAllow: true[!NOTE]
defaultAllow: trueif admission webhook server is not reachable, all request will be allowed
Enable admission controller
If Kubernetes components are deployed as daemons, edit service configuration file by systemctl edit service_name, else if Kubernetes has been deployed using kubeadm, simply edit pod manifest vim /etc/kubernetes/manifests/kube-apiserver.yaml and add ImagePolicyWebhook to --enable-admission-plugins= section as well as pass admission control config file via --admission-control-config-file=
Pod Decision Tree
Seccomp
How syscalls work
How to check if Seccomp is enabled
Check seccomp status on the process
# 1. ssh into container
# 2. list processes
ps -ef
# 3. grep for seccomp status
grep -i seccomp /proc/{PID}/statusIf the result is 2 it means that seccomp is enabled for the container
Seccomp modes
| Mode | Description |
|---|---|
| Mode 0 | Disabled |
| Mode 1 | Strict - will block all calls except read, write, exec, sigreadon |
| Mode 2 | Filtered - filter selectively |
Seccomp filter json file
there are 2 profile types:
- whitelist: only specified syscalls are allowed, all others are rejected
- blacklist: all syscalls are allowed, unless specified in the file
Docker seccomp filter
By default Docker enables seccomp filter (mode 2).
It blocks around 60 of the around 300 syscalls available with default profile
[!TIP] How to check what syscalls are blocked? Run amicontained tool as container to see syscalls blocked by default docker profile
docker run r.j3ss.co/amicontained amicontainedRun amicontained tool as pod to see syscalls blocked by Kubernetes default profile
k run amicontained --image r.j3ss.co/amicontained amicontained -- amidontainedcheck pod logs
k logs amicontained
Enable seccomp in Kubernetes
Create a pod using yaml spec and enable RuntimeDefault profile under securityContext of pod
Custom seccomp profile in Kubenetes
[!ATTENTION] default seccomp profile is located at
/var/lib/kubelet/seccomp. Custom seccomp profile path must be relative to this path
apiVersion: v1
kind: Pod
metadata:
name: audit-pod
labels:
app: audit-pod
spec:
securityContext:
seccompProfile:
type: Localhost
localhostProfile: profiles/audit.json
containers:
- name: test-container
image: hashicorp/http-echo:0.2.3
args:
- "-text=just made some syscalls!"
securityContext:
allowPrivilegeEscalation: false[!NOTE] In order to apply new seccomp profile, pod must be deleted and re-created. use
k recreate -fcommand
Seccomp logs
By default seccomp logs will be saved in /var/log/syslog
You can easily tail logs for specific pod by tail -f /var/log/syslog | grep {pod_name}
AppArmor
- restrict access to specific objects in the system
- determines what resources can be used by an application
- more fine grained control than seccomp
- installed in most systems
- AppArmor profiles are stored under
/etc/apparmor.d/
Example AppArmor Profile
#include <tunables/global>
profile k8s-apparmor-example-deny-write flags=(attach_disconnected) {
#include <abstractions/base>
file,
# Deny all file writes.
deny /** w,
}Check if AppArmor is running
systemctl status apparmor- is AppArmor module enabled?
cat /sys/module/apparmor/parameters/enabled - is AppArmor profile loaded into kernel?
cat /sys/kernel/security/apparmor/profiles - use
aa-statusto check what profiles are loaded
AppArmor profiles load modes
| Mode | Description |
|---|---|
| enforce | enforce and monitor on any app that fits the profile |
| complain | log as events |
| unconfined | any task allowed, no logging |
AppArmor in Kubernetes
- support added in v 1.4, but still in beta
- to load profile from default location use
apparmor_parser -q /etc/apparmor.d/{profile_name}
[!TIP] to secure a pod an annotation in this format
container.apparmor.security.beta.kubernetes.io/<container_name>: localhost/profile_name OR runtime/default OR unconfined
Use Case
AppArmor can be used to for example restrict access to a folder inside pod/container.
Linux Capabilities
-
Capabilities are added and removed per container
[!TIP] To check what capabilities are needed for any give command run
getcap /<path>/<command>or to check capabililties used by a running process rungetpcaps PID
Containers Isolation
gVisor
[!NOTE] Install gVisor
Kata Containers
[!NOTE] this requires nested virtualization (in case of running workloads on VMs) and can degrade performance. Some cloud providers do not support nested virtualization.
Containers isolation in Kubernetes
- run a container with kata container runtime:
docker run --runtime kata -d nginx - run a container with gVisor runtime:
docker run --runtime runsc -d nginx
- Create runtime object
- use
runtimeClassNameon pod definition level to use the runtime
deck
By Piotr
deck
- 502