本指南演示如何配置 Kyverno,通过阻止可能导致容器突破隔离边界的高风险容器配置,来防止容器逃逸攻击。
容器逃逸防护涉及检测并阻止可能允许攻击者突破容器隔离、访问宿主机系统的危险容器配置。包括:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-privileged-containers
annotations:
policies.kyverno.io/title: Disallow Privileged Containers
policies.kyverno.io/category: Pod Security Standards (Baseline)
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/description: >-
Privileged mode disables most security mechanisms and must not be allowed.
spec:
validationFailureAction: Enforce
background: true
rules:
- name: privileged-containers
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
Privileged mode is disallowed. The fields spec.containers[*].securityContext.privileged,
spec.initContainers[*].securityContext.privileged, and spec.ephemeralContainers[*].securityContext.privileged
must be unset or set to false.
pattern:
spec:
=(ephemeralContainers):
- =(securityContext):
=(privileged): "false"
=(initContainers):
- =(securityContext):
=(privileged): "false"
containers:
- =(securityContext):
=(privileged): "false"
# 应用策略
kubectl apply -f disallow-privileged-containers.yaml
# 尝试创建特权容器(应失败)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: test-privileged
spec:
containers:
- name: nginx
image: nginx
securityContext:
privileged: true
EOF
# 尝试创建普通容器(应成功)
kubectl run test-normal --image=nginx
# 清理资源
kubectl delete pod test-privileged test-normal --ignore-not-found
防止容器访问宿主机命名空间:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-host-namespaces
annotations:
policies.kyverno.io/title: Disallow Host Namespaces
policies.kyverno.io/category: Pod Security Standards (Baseline)
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/description: >-
Host namespaces (Process ID namespace, Inter-Process Communication namespace, and
network namespace) allow access to shared information and can be used to elevate
privileges. Pods should not be allowed access to host namespaces.
spec:
validationFailureAction: Enforce
background: true
rules:
- name: host-namespaces
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
Sharing the host namespaces is disallowed. The fields spec.hostNetwork,
spec.hostIPC, and spec.hostPID must be unset or set to false.
pattern:
spec:
=(hostPID): "false"
=(hostIPC): "false"
=(hostNetwork): "false"
阻止容器挂载宿主机文件系统路径:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-host-path
annotations:
policies.kyverno.io/title: Disallow Host Path
policies.kyverno.io/category: Pod Security Standards (Baseline)
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod,Volume
policies.kyverno.io/description: >-
HostPath volumes let Pods use host directories and volumes in containers.
Using host resources can be used to access shared data or escalate privileges
and should not be allowed.
spec:
validationFailureAction: Enforce
background: true
rules:
- name: host-path
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
HostPath volumes are forbidden. The field spec.volumes[*].hostPath must be unset.
pattern:
spec:
=(volumes):
- X(hostPath): "null"
防止容器绑定宿主机网络端口:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-host-ports
annotations:
policies.kyverno.io/title: Disallow Host Ports
policies.kyverno.io/category: Pod Security Standards (Baseline)
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/description: >-
Access to host ports allows potential snooping of network traffic and should not be
allowed, or at minimum restricted to a known list.
spec:
validationFailureAction: Enforce
background: true
rules:
- name: host-ports-none
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
Use of host ports is disallowed. The fields spec.containers[*].ports[*].hostPort,
spec.initContainers[*].ports[*].hostPort, and spec.ephemeralContainers[*].ports[*].hostPort
must either be unset or set to 0.
pattern:
spec:
=(ephemeralContainers):
- =(ports):
- =(hostPort): 0
=(initContainers):
- =(ports):
- =(hostPort): 0
containers:
- =(ports):
- =(hostPort): 0
阻止容器添加危险的 Linux 能力:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-capabilities-strict
annotations:
policies.kyverno.io/title: Disallow Capabilities (Strict)
policies.kyverno.io/category: Pod Security Standards (Restricted)
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/description: >-
Adding capabilities other than `NET_BIND_SERVICE` is disallowed. In addition,
all containers must explicitly drop `ALL` capabilities.
spec:
validationFailureAction: Enforce
background: true
rules:
- name: require-drop-all
match:
any:
- resources:
kinds:
- Pod
preconditions:
all:
- key: "{{ request.operation || 'BACKGROUND' }}"
operator: NotEquals
value: DELETE
validate:
message: >-
Containers must drop `ALL` capabilities.
foreach:
- list: request.object.spec.[ephemeralContainers, initContainers, containers][]
deny:
conditions:
all:
- key: ALL
operator: AnyNotIn
value: "{{ element.securityContext.capabilities.drop || `[]` }}"
- name: adding-capabilities
match:
any:
- resources:
kinds:
- Pod
preconditions:
all:
- key: "{{ request.operation || 'BACKGROUND' }}"
operator: NotEquals
value: DELETE
validate:
message: >-
Any capabilities added other than NET_BIND_SERVICE are disallowed.
foreach:
- list: request.object.spec.[ephemeralContainers, initContainers, containers][]
deny:
conditions:
any:
- key: "{{ element.securityContext.capabilities.add || `[]` }}"
operator: AnyNotIn
value:
- NET_BIND_SERVICE
确保容器以非 root 用户身份运行:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-run-as-nonroot
annotations:
policies.kyverno.io/title: Require Run As Non-Root User
policies.kyverno.io/category: Pod Security Standards (Restricted)
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/description: >-
Containers must run as a non-root user. This policy ensures runAsNonRoot is set to true.
spec:
validationFailureAction: Enforce
background: true
rules:
- name: run-as-non-root
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
Running as root is not allowed. Either the field spec.securityContext.runAsNonRoot
must be set to true, or the field spec.containers[*].securityContext.runAsNonRoot
must be set to true.
anyPattern:
- spec:
securityContext:
runAsNonRoot: "true"
- spec:
containers:
- securityContext:
runAsNonRoot: "true"
针对不同环境设置不同的安全级别:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: environment-container-security
spec:
validationFailureAction: Enforce
background: true
rules:
# 生产环境:严格安全
- name: production-strict-security
match:
any:
- resources:
kinds:
- Pod
namespaces:
- production
- prod-*
validate:
message: "Production environments require strict container security"
pattern:
spec:
=(hostPID): "false"
=(hostIPC): "false"
=(hostNetwork): "false"
securityContext:
runAsNonRoot: "true"
containers:
- securityContext:
privileged: "false"
runAsNonRoot: "true"
capabilities:
drop:
- ALL
# 开发环境:更宽松但仍安全
- name: development-basic-security
match:
any:
- resources:
kinds:
- Pod
namespaces:
- development
- dev-*
- staging
validate:
message: "Development environments require basic container security"
pattern:
spec:
=(hostPID): "false"
=(hostIPC): "false"
containers:
- securityContext:
=(privileged): "false"
允许特定工作负载的受控例外:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: workload-specific-security
spec:
validationFailureAction: Enforce
background: true
rules:
- name: system-workloads-exception
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- kyverno
- resources:
kinds:
- Pod
names:
- "monitoring-*"
- "logging-*"
validate:
message: "Container security policies apply to application workloads"
pattern:
spec:
=(hostNetwork): "false"
containers:
- securityContext:
=(privileged): "false"
# 此操作应被阻止
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: test-privileged
spec:
containers:
- name: test
image: nginx
securityContext:
privileged: true
EOF
# 此操作应被阻止
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: test-host-network
spec:
hostNetwork: true
containers:
- name: test
image: nginx
EOF
# 此操作应被阻止
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: test-hostpath
spec:
containers:
- name: test
image: nginx
volumeMounts:
- name: host-vol
mountPath: /host
volumes:
- name: host-vol
hostPath:
path: /
EOF
# 此操作应被允许
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: test-secure
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
containers:
- name: test
image: nginx
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
EOF
spec:
validationFailureAction: Audit # 先以警告形式提示,不阻止
exclude:
any:
- resources:
namespaces:
- kube-system
- kyverno
- kube-public