Skip to main content

Minimize Admission Of Containers Sharing The Host Network

More Info:

Sharing the host network namespace exposes node network interfaces and bypasses network policies. Enforce policies that restrict admission of hostNetwork containers.

Risk Level

High

Address

Security

Compliance Standards

  • CIS OKE

Triage and Remediation

Remediation

Manual Steps
  1. Identify all pods using hostNetwork across the cluster

    • Run on: any machine with kubectl access
    • Command:
      kubectl get pods --all-namespaces -o jsonpath='{range .items[?(@.spec.hostNetwork==true)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}'
    • Review: Determine which are platform/infra components (e.g., CNI, DNS, ingress) vs. user workloads; list user workloads that use hostNetwork.
  2. Review existing admission controls / policies per namespace

    • Run on: any machine with kubectl access
    • Commands:
      kubectl get validatingwebhookconfigurations.admissionregistration.k8s.io -o wide
      kubectl get mutatingwebhookconfigurations.admissionregistration.k8s.io -o wide
      kubectl get limitranges,resourcequotas,networkpolicies,configmaps -A
    • Review: For each user-workload namespace, check if there is any admission controller (e.g., OPA Gatekeeper, Kyverno, custom webhooks) or policy that explicitly restricts spec.hostNetwork: true. Note which namespaces lack such protection.
  3. Determine business/operational need for each hostNetwork pod

    • For each user-workload pod from step 1, review deployment manifests and owners:
      kubectl get pod -n <NAMESPACE> <POD_NAME> -o yaml
    • Decide with application owners whether hostNetwork is truly necessary (e.g., low-latency network access, node-local ports). Document which workloads can drop hostNetwork and which must retain it.
  4. Plan and apply namespace-level admission policies to restrict hostNetwork

    • Choose or confirm your admission mechanism (e.g., Kyverno, OPA Gatekeeper, custom webhook).
    • For each user-workload namespace that should disallow hostNetwork, create/update a policy that:
      • Denies new pods (and controllers: Deployments, DaemonSets, etc.) with spec.hostNetwork: true, except for explicitly allowed labels/namespaces.
    • Apply policy manifests from any machine with kubectl access:
      kubectl apply -f <POLICY_MANIFEST>.yaml
    • Ensure policies are scoped per-namespace as required by your governance.
  5. Refactor or reconfigure existing workloads to stop using hostNetwork where possible

    • For each pod that does not strictly require hostNetwork:
      • Update the workload manifest (Deployment/StatefulSet/DaemonSet/etc.) to remove or set hostNetwork: false.
    • Apply the updated manifest from any machine with kubectl access:
      kubectl apply -f <UPDATED_WORKLOAD>.yaml
    • Coordinate with application teams and schedule changes to avoid disruption; be aware that networking behavior (ports, policies, source IPs) will change.
  6. Verify effectiveness of policies and remaining hostNetwork usage

    • Confirm that new hostNetwork pods are blocked in protected namespaces (expect admission denial):
      kubectl run test-hostnet --image=busybox --restart=Never \
      --overrides='{"apiVersion":"v1","kind":"Pod","spec":{"hostNetwork":true,"containers":[{"name":"c","image":"busybox","command":["sleep","3600"]}]}}' \
      -n <PROTECTED_NAMESPACE>
    • Re-run the audit query to ensure only justified workloads use hostNetwork:
      kubectl get pods --all-namespaces -o jsonpath='{range .items[?(@.spec.hostNetwork==true)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}'
    • Confirm that any remaining hostNetwork pods are documented, approved exceptions and that corresponding namespaces still have admission policies in place.
Using kubectl

Using kubectl

1. List pods that request hostNetwork

Run on: any machine with kubectl access.

kubectl get pods -A -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,HOSTNETWORK:.spec.hostNetwork' \
--no-headers | grep -E 'true$' || echo "No pods with hostNetwork=true found"

Problem indication: Any line returned (namespace/name with HOSTNETWORK = true) is using the host network and must be reviewed for necessity and risk.

To see details for a specific pod:

kubectl get pod <pod-name> -n <namespace> -o yaml

Review .spec.hostNetwork: true and the pod’s purpose.


2. Discover whether pod security controls exist

a. Pod Security admission labels on namespaces (if using built-in PSA)

kubectl get ns --show-labels

Problem indication: Namespaces with user workloads that lack any pod-security.kubernetes.io/* labels, or are labeled with an overly-permissive level (e.g., privileged) likely do not restrict hostNetwork.

Check a specific namespace:

kubectl get ns <namespace> -o yaml

Inspect metadata.labels for pod-security.kubernetes.io/enforce (or audit/warn). Levels restricted/baseline are stricter; privileged means essentially unrestricted.


b. PodSecurityPolicy (legacy clusters only)

Check if PSP is enabled and list existing policies:

kubectl get psp

If PSPs exist, inspect them:

kubectl get psp <psp-name> -o yaml

Problem indication: Policies that apply to user workloads (via RBAC bindings) and allow hostNetwork: true without clear justification or scoping. In a PSP YAML, look at:

spec:
hostNetwork: true

This indicates the policy permits host networking.


c. Admission webhooks / OPA / Gatekeeper / Kyverno (if used)

List all Mutating/ValidatingWebhookConfigurations:

kubectl get mutatingwebhookconfigurations.admissionregistration.k8s.io
kubectl get validatingwebhookconfigurations.admissionregistration.k8s.io

Inspect each security-related webhook:

kubectl get validatingwebhookconfiguration <name> -o yaml
kubectl get mutatingwebhookconfiguration <name> -o yaml

Problem indication: No webhook configurations that reference policies about spec.hostNetwork, or policy engines (OPA Gatekeeper, Kyverno, etc.) installed without any constraints/policies targeting hostNetwork. You will need to review the webhook/policy definitions themselves (in the policy engine’s CRDs) to determine whether hostNetwork is restricted.


3. Verify after policy decisions

After you adjust policies (outside the scope of kubectl alone), re-run:

kubectl get pods -A -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,HOSTNETWORK:.spec.hostNetwork' \
--no-headers | grep -E 'true$' || echo "No pods with hostNetwork=true found"

If any HOSTNETWORK=true pods remain, they should be explicitly approved exceptions; otherwise, they indicate a remaining policy gap.

Automation
#!/usr/bin/env bash
set -euo pipefail

# This script must run on any machine with kubectl access and correct kubeconfig.
# It reports all Pods and workload templates that request hostNetwork=true.

echo "=== Pods currently using hostNetwork ==="
kubectl get pods -A -o json \
| jq -r '
.items[]
| select(.spec.hostNetwork == true)
| [
.metadata.namespace,
.metadata.name,
(.metadata.ownerReferences[0].kind // "Pod"),
(.metadata.ownerReferences[0].name // "-"),
(.spec.serviceAccountName // "default")
]
| @tsv' \
| awk 'BEGIN{OFS="\t"; print "NAMESPACE","POD","OWNER_KIND","OWNER_NAME","SERVICE_ACCOUNT"}1'

echo
echo "=== Workload templates allowing hostNetwork (may create hostNetwork pods in future) ==="
# Deployments
kubectl get deploy -A -o json \
| jq -r '
.items[]
| select(.spec.template.spec.hostNetwork == true)
| ["Deployment",
.metadata.namespace,
.metadata.name,
(.spec.template.spec.serviceAccountName // "default")
]
| @tsv' \
| awk 'BEGIN{OFS="\t"; print "KIND","NAMESPACE","NAME","SERVICE_ACCOUNT"}1'

# DaemonSets
kubectl get ds -A -o json \
| jq -r '
.items[]
| select(.spec.template.spec.hostNetwork == true)
| ["DaemonSet",
.metadata.namespace,
.metadata.name,
(.spec.template.spec.serviceAccountName // "default")
]
| @tsv' \
| awk 'BEGIN{OFS="\t"; print "KIND","NAMESPACE","NAME","SERVICE_ACCOUNT"}1'

# StatefulSets
kubectl get sts -A -o json \
| jq -r '
.items[]
| select(.spec.template.spec.hostNetwork == true)
| ["StatefulSet",
.metadata.namespace,
.metadata.name,
(.spec.template.spec.serviceAccountName // "default")
]
| @tsv' \
| awk 'BEGIN{OFS="\t"; print "KIND","NAMESPACE","NAME","SERVICE_ACCOUNT"}1'

echo
echo "=== Namespaces without any NetworkPolicy (weaker isolation for any hostNetwork use) ==="
kubectl get ns -o json \
| jq -r '
.items[].metadata.name' \
| while read -r ns; do
count=$(kubectl get networkpolicy -n "$ns" --no-headers 2>/dev/null | wc -l | tr -d ' ')
if [ "$count" -eq 0 ]; then
echo "$ns"
fi
done

echo
echo "=== Interpretation ==="
cat <<'EOF'
Any line shown above indicates a configuration to review:

- "Pods currently using hostNetwork":
Each listed pod is already running with hostNetwork=true and bypasses
normal namespace-level network isolation and most NetworkPolicy controls.

- "Workload templates allowing hostNetwork":
Any listed Deployment, DaemonSet, or StatefulSet will create pods with
hostNetwork=true. These should exist only where strictly necessary and
should be covered by explicit admission / policy exceptions.

- "Namespaces without any NetworkPolicy":
Host-networked workloads in these namespaces are of higher concern, since
there is no NetworkPolicy layer at all. Consider introducing policies and/or
restricting hostNetwork via admission controls in these namespaces.

Use this report to decide:
- Which existing hostNetwork uses are truly required.
- Where to add or tighten admission controls and NetworkPolicy.
EOF