Minimize The Admission Of Containers Sharing The Host
More Info:
Containers sharing the host network namespace can access node-level network interfaces and bypass network controls. Restrict admission of hostNetwork containers via namespace policies.
Risk Level
High
Address
Security
Compliance Standards
- CIS EKS
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
Identify pods currently using
hostNetwork(any machine with kubectl access):kubectl get pods --all-namespaces -o json \| jq -r '.items[] | select(.spec.hostNetwork == true) | "\(.metadata.namespace) \(.metadata.name)"' -
For each affected namespace that should host only user workloads, create or update a
BaselinePod Security admission policy that disallowshostNetwork(any machine with kubectl access). Example for namespacemy-namespace:kubectl label namespace my-namespace pod-security.kubernetes.io/enforce=baseline --overwritekubectl label namespace my-namespace pod-security.kubernetes.io/enforce-version=latest --overwriteIf you need finer control (e.g., allow for specific system workloads), instead create a custom admission policy (ValidatingAdmissionPolicy/PolicyBinding, Gatekeeper, or Kyverno) that rejects pods with
spec.hostNetwork: trueexcept for explicitly allowed service accounts. -
Review exceptions before tightening policies (any machine with kubectl access):
kubectl get pods -A -o wide \| awk 'NR==1 || $0 ~ /hostNetwork=true/ {print}'For any pod that legitimately requires
hostNetwork(e.g., CNI components), ensure it runs in a dedicated “system” namespace with an explicit exception in your admission policy, or is excluded by your policy’s namespace/label selectors. -
Update workload manifests to remove
hostNetwork: truewhere not strictly required (any machine with kubectl access). For each affected pod/deployment:# Example: edit a deployment to remove hostNetworkkubectl -n my-namespace edit deploy my-appIn the editor, remove or set:
spec:template:spec:hostNetwork: false -
Redeploy any workloads that previously relied on
hostNetworkonly after confirming they function correctly behind normal Kubernetes networking and network policies (any machine with kubectl access). Use your CI/CD or:kubectl -n my-namespace rollout restart deploy my-app -
Verification (any machine with kubectl access):
kubectl get pods --all-namespaces -o json \| jq -r 'if any(.items[]?; .spec.hostNetwork == true) then "HOSTNETWORK_FOUND" else "NO_HOSTNETWORK" end'Confirm the output is:
NO_HOSTNETWORK
Using kubectl
# 1) Create a baseline policy that denies hostNetwork by default
# Run on: any machine with kubectl access
cat << 'EOF' > deny-hostnetwork-admission.yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: deny-hostnetwork
annotations:
policies.kyverno.io/title: Deny Host Network
policies.kyverno.io/category: Security
policies.kyverno.io/description: >-
Block creation of Pods that set spec.hostNetwork=true.
spec:
validationFailureAction: Enforce
background: true
rules:
- name: deny-hostnetwork
match:
any:
- resources:
kinds:
- Pod
namespaces:
- "*"
exclude:
any:
- resources:
namespaces:
- kube-system
- kube-public
- kube-node-lease
validate:
message: "Use of hostNetwork is not allowed in this namespace."
pattern:
spec:
=(hostNetwork): "false"
EOF
kubectl apply -f deny-hostnetwork-admission.yaml
Note: The above uses Kyverno as an example admission controller. If Kyverno (or a similar admission controller) is not installed, install and configure one first; kubectl alone cannot enforce admission without such a controller.
# 2) (Optional) Namespace-specific policy allowing exceptions if needed
# Replace <namespace-with-user-workloads> with an actual namespace name
cat << 'EOF' > deny-hostnetwork-namespace.yaml
apiVersion: kyverno.io/v1
kind: Policy
metadata:
name: deny-hostnetwork
namespace: <namespace-with-user-workloads>
spec:
validationFailureAction: Enforce
background: true
rules:
- name: deny-hostnetwork-in-namespace
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Use of hostNetwork is not allowed in this namespace."
pattern:
spec:
=(hostNetwork): "false"
EOF
# Apply for a specific namespace:
kubectl apply -f deny-hostnetwork-namespace.yaml
# 3) Clean up any existing hostNetwork pods in user namespaces if appropriate
# Review first:
kubectl get pods --all-namespaces -o json \
| jq -r '.items[] | select(.spec.hostNetwork == true) | "\(.metadata.namespace) \(.metadata.name)"'
# After deciding which user workloads should be changed, edit or patch each Pod/Deployment/etc.
# Example for a Deployment in a user namespace:
kubectl -n <user-namespace> edit deployment <deployment-name>
# and manually remove or set:
# hostNetwork: false
# under spec.template.spec
# 4) Verification (same logic as the audit)
# Run on: any machine with kubectl access
kubectl get pods --all-namespaces -o json \
| jq -r 'if any(.items[]?; .spec.hostNetwork == true) then "HOSTNETWORK_FOUND" else "NO_HOSTNETWORK" end'
Automation
#!/usr/bin/env bash
set -euo pipefail
# Purpose:
# - For every non-system namespace, ensure a policy exists that denies pods
# using hostNetwork.
# - Uses a Kyverno ClusterPolicy; idempotent and safe to re-run.
#
# Prerequisites:
# - Run on any machine with kubectl access and sufficient RBAC to create
# cluster-wide policies (ClusterPolicy).
# 1) Check access
kubectl auth can-i create clusterpolicies.kyverno.io >/dev/null 2>&1 || {
echo "ERROR: This script requires permission to create Kyverno ClusterPolicies." >&2
exit 1
}
# 2) Ensure Kyverno is installed (simple presence check)
if ! kubectl get ns kyverno >/dev/null 2>&1; then
echo "ERROR: Namespace 'kyverno' not found. Install Kyverno admission controller first." >&2
exit 1
fi
# 3) Apply a ClusterPolicy that denies hostNetwork pods in all non-system namespaces
# This single policy satisfies the requirement "Add policies to each namespace
# in the cluster which has user workloads to restrict the admission of hostNetwork containers."
cat <<'EOF' | kubectl apply -f -
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: deny-hostnetwork-pods
annotations:
policies.kyverno.io/title: Deny hostNetwork Pods
policies.kyverno.io/category: Security
policies.kyverno.io/severity: high
policies.kyverno.io/description: >
Deny Pods that request hostNetwork in all non-system namespaces.
spec:
validationFailureAction: Enforce
background: true
rules:
- name: deny-hostnetwork
match:
any:
- resources:
kinds:
- Pod
namespaces:
- "*"
exclude:
any:
- resources:
namespaces:
- kube-system
- kube-public
- kube-node-lease
- kyverno
# Add any other infrastructure or system namespaces here if needed
validate:
message: "Use of hostNetwork is not allowed in this namespace."
pattern:
spec:
hostNetwork: "false"
EOF
echo "ClusterPolicy 'deny-hostnetwork-pods' applied."
# 4) Verification
echo "Verifying policy existence..."
if ! kubectl get clusterpolicy deny-hostnetwork-pods -o yaml >/dev/null 2>&1; then
echo "ERROR: ClusterPolicy 'deny-hostnetwork-pods' not found after apply." >&2
exit 1
fi
echo "Verifying that new hostNetwork pods are rejected in a test namespace..."
# Create a temporary test namespace (non-system)
TEST_NS="hostnetwork-deny-test"
kubectl get ns "${TEST_NS}" >/dev/null 2>&1 || kubectl create ns "${TEST_NS}" >/dev/null
# Try to create a pod with hostNetwork: true (should be denied)
set +e
kubectl -n "${TEST_NS}" apply -f - <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: test-hostnetwork-denied
spec:
hostNetwork: true
containers:
- name: pause
image: registry.k8s.io/pause:3.9
EOF
APPLY_RC=$?
set -e
if [ "${APPLY_RC}" -eq 0 ]; then
echo "ERROR: Test pod with hostNetwork was admitted; policy is not effective." >&2
# Clean up in case it was actually created
kubectl -n "${TEST_NS}" delete pod test-hostnetwork-denied --ignore-not-found >/dev/null 2>&1 || true
exit 1
fi
echo "Policy enforcement verified: hostNetwork pod creation was rejected."
# 5) Final cluster-wide check for existing hostNetwork pods (informational)
echo "Current cluster state (existing pods may still use hostNetwork until recreated):"
kubectl get pods --all-namespaces -o json \
| jq -r 'if any(.items[]?; .spec.hostNetwork == true) then "HOSTNETWORK_FOUND" else "NO_HOSTNETWORK" end'