Minimize Admission Containers Wishing Share Host Ipc
More Info:
Do not generally permit containers to be run with the hostIPC flag set to true.
Risk Level
Critical
Address
Security
Compliance Standards
- APRA CPS 234 (Australia)
- BSI C5 (Germany)
- Brazil LGPD
- CCPA / CPRA (California)
- CIS Critical Security Controls v8
- CIS EKS
- CMMC 2.0
- CSA Cloud Controls Matrix v4
- DPDPA
- Digital Operational Resilience Act (EU)
- Essential 8
- ISO/IEC 27017
- ISO/IEC 27018
- ISO/IEC 27701
- KSA PDPL
- MAS Technology Risk Management (Singapore)
- MITRE ATT&CK (Cloud)
- NIS2 Directive
- NIST SP 800-171
- NYDFS 23 NYCRR 500
- SWIFT Customer Security Controls Framework
- Sarbanes-Oxley IT General Controls
- UK NCSC Cyber Assessment Framework
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
Identify namespaces that currently admit
hostIPCpods- Run on: any machine with kubectl access
kubectl get pods --all-namespaces -o json \| jq -r '.items[] | select(.spec.hostIPC == true) | .metadata.namespace' \| sort -u -
For each affected namespace, create a baseline PodSecurity admission label set (example for
prod-apps)- Run on: any machine with kubectl access
kubectl label namespace prod-apps \pod-security.kubernetes.io/enforce=restricted \pod-security.kubernetes.io/enforce-version=latest \--overwrite -
Add a
LimitRangeto blockhostIPCin the namespace (example forprod-apps)- Run on: any machine with kubectl access
- Create a manifest file
limitrange-no-hostipc-prod-apps.yamlwith:apiVersion: v1kind: LimitRangemetadata:name: disallow-hostipcnamespace: prod-appsspec:limits:- type: Podmax:# This annotation-style pattern will be rejected by the API server# if hostIPC is set, due to restricted PodSecurity policy.# The object serves as a marker that hostIPC is not allowed.alpha.kubernetes.io/hostIPC: "false" - Apply it:
kubectl apply -f limitrange-no-hostipc-prod-apps.yaml
-
(If PodSecurity admission is not available) Define an admission control policy resource for the namespace (e.g., Kyverno)
- Run on: any machine with kubectl access
- Example Kyverno policy manifest
kyverno-disallow-hostipc-prod-apps.yaml:apiVersion: kyverno.io/v1kind: ClusterPolicymetadata:name: disallow-hostipc-prod-appsspec:validationFailureAction: Enforcerules:- name: disallow-hostipcmatch:any:- resources:kinds:- Podnamespaces:- prod-appsvalidate:message: "Use of hostIPC is not allowed."pattern:spec:hostIPC: "false" - Apply it:
kubectl apply -f kyverno-disallow-hostipc-prod-apps.yaml
-
Clean up or recreate existing pods that currently use
hostIPCin each namespace- Run on: any machine with kubectl access
kubectl get pods -n prod-apps -o json \| jq -r '.items[] | select(.spec.hostIPC == true) | .metadata.name' \| xargs -r kubectl delete pod -n prod-apps- Then update the corresponding Deployment/StatefulSet/Job manifests to remove
hostIPC: truefromspec.template.spec.
-
Verification (all namespaces)
- Run on: any machine with kubectl access
kubectl get pods --all-namespaces -o json \| jq -r 'if any(.items[]?; .spec.hostIPC == true) then "HOSTIPC_FOUND" else "NO_HOSTIPC" end'- Confirm the output is:
NO_HOSTIPC
Using kubectl
# 1) Create a baseline policy that denies hostIPC in all user namespaces
# Run on: any machine with kubectl access
cat << 'EOF' > deny-hostipc-psp.yaml
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: deny-hostipc
spec:
privileged: false
hostIPC: false
hostNetwork: false
hostPID: false
allowPrivilegeEscalation: false
requiredDropCapabilities:
- ALL
volumes:
- 'configMap'
- 'emptyDir'
- 'projected'
- 'secret'
- 'downwardAPI'
- 'persistentVolumeClaim'
runAsUser:
rule: 'MustRunAsNonRoot'
seLinux:
rule: 'RunAsAny'
fsGroup:
rule: 'MustRunAs'
ranges:
- min: 1
max: 65535
supplementalGroups:
rule: 'MustRunAs'
ranges:
- min: 1
max: 65535
EOF
kubectl apply -f deny-hostipc-psp.yaml
# 2) For each namespace with user workloads, bind the PSP and (optionally) add a label.
# Replace <namespace> with the actual namespace name. Repeat per namespace.
NAMESPACE=<namespace>
kubectl label namespace "${NAMESPACE}" \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/enforce-version=latest \
--overwrite
cat << EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: psp:deny-hostipc
namespace: ${NAMESPACE}
rules:
- apiGroups: ['policy']
resources: ['podsecuritypolicies']
resourceNames: ['deny-hostipc']
verbs: ['use']
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: use:psp:deny-hostipc
namespace: ${NAMESPACE}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: psp:deny-hostipc
subjects:
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:serviceaccounts:${NAMESPACE}
EOF
# 3) Verification: confirm no pods are admitted with hostIPC=true
# Run on: any machine with kubectl access
kubectl get pods --all-namespaces -o json | jq -r 'if any(.items[]?; .spec.hostIPC == true) then "HOSTIPC_FOUND" else "NO_HOSTIPC" end'
Automation
#!/usr/bin/env bash
set -euo pipefail
# Automation for: Minimize admission of containers wishing to share the host IPC namespace
# Scope: any machine with kubectl access to the cluster
# This script:
# - Creates/updates a Pod Security admission label on every non-system namespace
# to disallow hostIPC
# - Verifies no pods are using hostIPC
# REQUIREMENTS:
# - kubectl configured with cluster-admin permissions
# - jq installed
# CONFIGURATION:
# Policy: use Pod Security Admission label equivalent to baseline/restricted behavior
# which forbids hostIPC.
PSA_LEVEL="restricted"
PSA_MODE="enforce"
echo "Discovering namespaces..."
# Exclude Kubernetes/system namespaces; adjust the grep -Ev pattern if needed for your cluster.
NAMESPACES=$(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' \
| grep -Ev '^(kube-system|kube-public|kube-node-lease)$' || true)
if [ -z "${NAMESPACES}" ]; then
echo "No non-system namespaces found; nothing to label."
else
echo "Applying Pod Security labels to namespaces:"
echo "${NAMESPACES}"
while read -r ns; do
[ -z "$ns" ] && continue
echo " -> Patching namespace: ${ns}"
kubectl label namespace "${ns}" \
"pod-security.kubernetes.io/enforce=${PSA_LEVEL}" \
"pod-security.kubernetes.io/enforce-version=latest" \
--overwrite
done <<< "${NAMESPACES}"
fi
echo "Waiting briefly for admission changes to take effect..."
sleep 5
echo "Verifying that no pods are using hostIPC..."
RESULT=$(kubectl get pods --all-namespaces -o json \
| jq -r 'if any(.items[]?; .spec.hostIPC == true) then "HOSTIPC_FOUND" else "NO_HOSTIPC" end')
if [ "${RESULT}" = "NO_HOSTIPC" ]; then
echo "Verification PASSED: no pods with hostIPC=true detected."
exit 0
fi
echo "Verification WARNING: pods with hostIPC=true are still present."
echo "Details:"
kubectl get pods --all-namespaces -o json \
| jq -r '.items[] | select(.spec.hostIPC == true) | "\(.metadata.namespace) \(.metadata.name)"'
echo
echo "New hostIPC=true pods should now be blocked by admission; existing pods must be handled manually:"
echo " - Review and delete or re-deploy these pods without hostIPC"
echo " - Then re-run this script to confirm a clean state"
exit 1