Kubernetes Security Best Practices Cheat Sheet
This guide is based on the OWASP’s page OWASP Kubernetes Top Ten Vulnerabilities.
It aims to sum up the best practices for security management. For more information / details, you can check the following links:
Insecure Workload Configuration
Don’t run as root
apiVersion: v1
kind: Pod
metadata:
name: root-user
spec:
containers:
...
securityContext:
#root user:
runAsUser: 0
#non-root user:
runAsUser: 5554
Set filesystems as read-only
apiVersion: v1
kind: Pod
metadata:
name: read-only-fs
spec:
containers:
securityContext:
#read-only fs explicitly defined
readOnlyRootFilesystem: true
Disallow privileged containers
apiVersion: v1
kind: Pod
metadata:
name: privileged-pod
spec:
containers:
...
securityContext:
#priviliged
privileged: true
#non-privileged
privileged: false
Supply Chain Vulnerabilities
Image Integrity
When systems of record do not exist regarding the contents of a container image it is possible that an unexpected container may run in a cluster. Use Software Bill of Materials (SBOM) and image signing.
Image Composition
Use minimal OS package and dependencies. Run a vulnerability scanner on the images.
Overly Permissive Role-Based Access Control (RBAC)
- Reduce direct cluster access by end users when possible
- Don’t use Service Account Tokens outside of the cluster
- Avoid automatically mounting the default service account token
- Audit RBAC included with installed third-party components
- Deploy centralized polices to detect and block risky RBAC permissions
- Utilize RoleBindings to limit scope of permissions to particular namespaces vs. cluster-wide RBAC policies
Policy Enforcement
Reject workload that
- haven’t been scanned for vulnerabilities
- use a base image that’s not explicitly allowed
- don’t include an approved SBOM
- originated from untrusted registries
- … and any other policy that apply governance, compliance, and security requirements
# Allowed repos
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sAllowedRepos
metadata:
name: allowed-repos
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
namespaces:
- "sbx"
- "prd"
parameters:
repos:
- "open-policy-agent"
- "ubuntu"
Inadequate Logging
Kubernetes Audit Logs
Records actions taken by the API (anomalous or unwanted API calls, especially any authorization failures)
Kubernetes Events
Kubernetes resource state changes and errors, such as exceeded resource quota or pending pods, as well as any informational messages
Application & Container Logs
Applications running inside of Kubernetes (easiest method for capturing these logs is to ensure the output is written to standard output stdout and standard error stderr streams)
Operating System Logs
Logs from programs such as systemd
Cloud Provider Logs
Check with the provider what logs can be provided
Network Logs
If working with traditional proxy or ingress components such as nginx or apache, use the standard out stdout and standard error stderr pattern
Monitoring
The monitoring must be robust and should not only capture relevant security events, but also be centralized in a way that is queryable, long term, and maintains integrity.
Broken Authentication
- Avoid using certificates for end user authentication (the API has no way to revoke certificates)
- Do not code your own authentication system
- Enforce MFA when possible
- Don’t use Service Account tokens from outside of the cluster
- Authenticate users and external services using short-lived tokens
Network Segmentation
The Kubernetes networking is flat by default
Native Controls (Multi-Cluster)
One way to truly enforce network isolation within Kubernetes is to utilize separate clusters when appropriate. This adds complexity when working with tightly coupled microservices but is a viable option when separating different tenants based on risk.
Native Controls (NetworkPolicies)
Network policies are built into Kubernetes itself and behave like firewall rules. They control how pods communicate. Without network policies, any pod can talk to any other pod. Network Policies should be defined as to limit pod communication to only defined assets while denying everything that isn’t explicitly configured.
# network policy prevents backend egress between pods running the “default” namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-backend-egress
namespace: default
spec:
podSelector:
matchLabels:
tier: backend
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
tier: backend
Service Mesh
There are a number of different service mesh projects available for different use cases including Istio, Linkerd, and Hashicorp Consul
CNI Plugins
Container Network Interface (CNI) is an open source specification that is used to configure access to networking resources. CNI is a software-defined mechanism for allowing or disallowing network access within Kubernetes and has a wide variety of supported plugins. When choosing a CNI, it is most important to understand the feature-set that you are seeking from a security perspective and the resource overhead and maintenance related to using the plugin.
Secrets Management
- Encrypt secrets at rest (encrypt etcd, encrypt backup, consider full disk encryption if possible)
- Address Security Misconfigurations (least privilege for users)
- Ensure Logging and Auditing is in place
Misconfigured Cluster Components
Examples
--anonymous-auth=false
--authorization-mode=Webhook
- Regular CIS Benchmark scans and audits focused on component misconfigurations
- Strong culture of Infrastructure-as-Code can also help
Vulnerable Components
- Set up a vulnerability scanner for all the components of Kubernetes
- Minimize the use of third party components, if possible