Minimize The Admission Of Containers Sharing The Host IPC
More Info:​
Containers sharing the host IPC namespace can access inter-process communication resources of the node. Restrict admission of hostIPC containers via namespace policies.
Risk Level​
High
Address​
Security
Compliance Standards​
- CIS EKS
Triage and Remediation​
- Remediation
Remediation​
Manual Steps
-
Identify pods using
hostIPC(informational).
Run on any machine with kubectl access:kubectl get pods --all-namespaces -o json \| jq -r '.items[] | select(.spec.hostIPC == true) | "\(.metadata.namespace) \(.metadata.name)"' -
Review and plan to change offending workloads.
For each listed pod, identify the owning workload (Deployment/StatefulSet/Job, etc.):# Example for one namespacekubectl get pods -n NAMESPACE PODNAME -o json \| jq -r '.metadata.ownerReferences[]? | "\(.kind)/\(.name)"'Decide whether
hostIPCis truly required. If absolutely required, document the exception and plan a Pod Security (or PSP/replacement) policy that narrowly permits it only where needed. -
Remove
hostIPC: truefrom workload manifests.
For each offending workload, edit the manifest and delete thehostIPC: trueline underspec.template.spec(or underspecfor naked Pods). Example usingkubectl edit(on any machine with kubectl access):# Deployment examplekubectl edit deployment -n NAMESPACE DEPLOYMENT_NAMEIn the editor, remove:
spec:template:spec:hostIPC: trueSave and exit. Repeat for StatefulSets, Jobs, DaemonSets, and any standalone Pods.
-
Apply restrictive Pod Security (or equivalent) policy at the namespace level.
For Kubernetes 1.25+ using Pod Security admission, label each namespace with at leastrestricted(which forbidshostIPC: trueby default):kubectl label namespace NAMESPACE \pod-security.kubernetes.io/enforce=restricted \pod-security.kubernetes.io/enforce-version=latest --overwriteRepeat for every namespace that hosts user workloads.
-
Recreate or roll pods so changes take effect.
For controller-managed workloads (Deployments/StatefulSets/DaemonSets), trigger a rollout:kubectl rollout restart deployment -n NAMESPACE DEPLOYMENT_NAMEkubectl rollout restart statefulset -n NAMESPACE STATEFULSET_NAMEkubectl rollout restart daemonset -n NAMESPACE DAEMONSET_NAMEFor any remaining naked Pods that specified
hostIPC: true, delete and recreate them from the updated manifests:kubectl delete pod -n NAMESPACE PODNAMEkubectl apply -f /absolute/path/to/updated-pod-manifest.yaml -
Verify no pods use
hostIPC.
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'Ensure the output is:
NO_HOSTIPC
Using kubectl
On any machine with kubectl access:
- Create a restrictive
PodSecurityadmission label (for clusters using Pod Security Admission)
kubectl label namespace default pod-security.kubernetes.io/enforce=restricted --overwrite
kubectl label namespace default pod-security.kubernetes.io/enforce-version=latest --overwrite
Apply similar labels to every namespace that runs user workloads, replacing default:
kubectl get ns
# For each relevant namespace, e.g.:
kubectl label namespace my-apps pod-security.kubernetes.io/enforce=restricted --overwrite
kubectl label namespace my-apps pod-security.kubernetes.io/enforce-version=latest --overwrite
- (Alternative/Additional) Apply a
PodSecurityPolicy-style restriction via Gatekeeper/PSP replacement
If you use Gatekeeper or a similar admission controller, apply a policy that disallowshostIPC: truein pods. Example GatekeeperConstraintTemplateandConstraint(save asdeny-hostipc.yamland apply):
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8sdenyhostipc
spec:
crd:
spec:
names:
kind: K8sDenyHostIPC
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8sdenyhostipc
violation[{"msg": msg}] {
input.review.kind.kind == "Pod"
input.review.object.spec.hostIPC == true
msg := "Pods must not set spec.hostIPC=true"
}
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sDenyHostIPC
metadata:
name: deny-hostipc
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
namespaces:
- "*"
Apply:
kubectl apply -f deny-hostipc.yaml
- Verification (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
# This script:
# - Creates a PodSecurity "restricted" level default policy in every user namespace
# - Ensures hostIPC is disallowed for new pods (and pod templates) in those namespaces
# - Verifies no pods are currently using hostIPC
#
# Run from: any machine with kubectl access and a current-context pointing at the cluster.
# -------------------------
# Configurable allowlist
# -------------------------
# Namespaces to skip (typically system/control-plane namespaces).
SKIP_NAMESPACES=(
"kube-system"
"kube-public"
"kube-node-lease"
"default" # remove from this list if you run user workloads here
"local-path-storage"
"kube-monitoring"
"calico-system"
"tigera-operator"
"istio-system"
"cert-manager"
)
# Convert skip list to a regex for grep -wF -x
skip_ns_regex="$(printf '%s\n' "${SKIP_NAMESPACES[@]}" | sed 's/[.[\*^$]/\\&/g' | paste -sd'|' -)"
echo "Discovering namespaces..."
all_ns="$(kubectl get ns -o jsonpath='{.items[*].metadata.name}')"
user_ns=()
for ns in $all_ns; do
if [[ -n "$skip_ns_regex" ]] && [[ "$ns" =~ ^($skip_ns_regex)$ ]]; then
echo "Skipping namespace (allowlisted): $ns"
continue
fi
user_ns+=("$ns")
done
if [[ ${#user_ns[@]} -eq 0 ]]; then
echo "No user namespaces discovered after applying skip list."
fi
# -------------------------
# Apply Pod Security Standards labels
# -------------------------
# This uses the built-in PodSecurity admission (PSA) labels to enforce "restricted",
# which forbids hostIPC for new pods in these namespaces.
#
# If you are already using PodSecurity labels, this will idempotently set them to
# enforce=restricted, audit=restricted, warn=restricted.
for ns in "${user_ns[@]}"; do
echo "Configuring PodSecurity 'restricted' policy in namespace: $ns"
# Set or update labels idempotently
kubectl label namespace "$ns" \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/enforce-version=latest \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/audit-version=latest \
pod-security.kubernetes.io/warn=restricted \
pod-security.kubernetes.io/warn-version=latest \
--overwrite
done
# -------------------------
# Optional: Add an explicit validating admission policy for hostIPC
# (Kubernetes v1.30+ with ValidatingAdmissionPolicy + Binding enabled)
# -------------------------
# This further guarantees hostIPC cannot be set even if PSA is loosened later.
# Safe to re-run (create-or-replace semantics).
if kubectl api-resources | grep -q "^validatingadmissionpolicies"; then
echo "ValidatingAdmissionPolicy API detected - creating hostIPC deny policy."
cat <<'EOF' | kubectl apply -f -
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: deny-hostipc
spec:
paramKind: {}
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE","UPDATE"]
resources: ["pods"]
validations:
- expression: "!(object.spec.hostIPC == true)"
message: "Pods must not set spec.hostIPC: true"
reason: Forbidden
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: deny-hostipc-binding
spec:
policyName: deny-hostipc
validationActions: ["Deny"]
EOF
else
echo "ValidatingAdmissionPolicy API not available; relying on PodSecurity labels only."
fi
# -------------------------
# Verification
# -------------------------
echo "Verifying no pods are currently 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_HOSTIPC"
exit 0
else
echo "Verification failed: HOSTIPC_FOUND"
echo "There are existing pods using hostIPC. They were not modified by this script."
echo "List of offending pods:"
kubectl get pods --all-namespaces -o json \
| jq -r '.items[] | select(.spec.hostIPC == true) | [.metadata.namespace, .metadata.name] | @tsv'
exit 1
fi