Skip to main content

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

Manual Steps
  1. Identify namespaces that currently admit hostIPC pods

    • 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
  2. 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
  3. Add a LimitRange to block hostIPC in the namespace (example for prod-apps)

    • Run on: any machine with kubectl access
    • Create a manifest file limitrange-no-hostipc-prod-apps.yaml with:
      apiVersion: v1
      kind: LimitRange
      metadata:
      name: disallow-hostipc
      namespace: prod-apps
      spec:
      limits:
      - type: Pod
      max:
      # 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
  4. (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/v1
      kind: ClusterPolicy
      metadata:
      name: disallow-hostipc-prod-apps
      spec:
      validationFailureAction: Enforce
      rules:
      - name: disallow-hostipc
      match:
      any:
      - resources:
      kinds:
      - Pod
      namespaces:
      - prod-apps
      validate:
      message: "Use of hostIPC is not allowed."
      pattern:
      spec:
      hostIPC: "false"
    • Apply it:
      kubectl apply -f kyverno-disallow-hostipc-prod-apps.yaml
  5. Clean up or recreate existing pods that currently use hostIPC in 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: true from spec.template.spec.
  6. 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

Additional Reading: