> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Minimize The Admission Of Containers Which Use HostPorts

### More Info:

HostPorts bind container ports directly to the node, bypassing network policy and exposing services on the host. Restrict their use.

### Risk Level

Medium

### Address

Security

### Compliance Standards

* CIS Kubernetes

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Identify current workloads using `hostPort`**
           * Run on: any machine with `kubectl` access
           * Command:
             ```bash theme={null}
             kubectl get pods -A -o jsonpath='{range .items[?(@.spec.containers[*].ports[*].hostPort)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.nodeName}{"\n"}{end}'
             ```
           * Save/record this list as the baseline of current `hostPort` usage.

        2. **Review each identified pod’s necessity for `hostPort`**
           * For each `NAMESPACE`/`POD` from step 1:
             ```bash theme={null}
             kubectl get pod POD -n NAMESPACE -o yaml > POD-NAMESPACE.yaml
             ```
           * Manually inspect:
             * Which containers/ports use `hostPort` and on which nodes.
             * Whether they front internet-facing or sensitive services.
             * Whether equivalent access could be provided via ClusterIP/LoadBalancer/Ingress instead of `hostPort`.
           * Decide for each: “required (documented justification)” or “can be removed/avoided”.

        3. **Review and design Pod Security / admission policy per namespace**
           * For each namespace that runs user workloads (and especially those with unjustified `hostPort` use):
             * If using built-in Pod Security Admission, check labels:
               ```bash theme={null}
               kubectl get ns NAMESPACE --show-labels
               ```
               * Assess whether the effective Pod Security level (e.g., `baseline`, `restricted`) and any custom admission policies already limit `hostPort`.
             * If using another admission controller (e.g., Kyverno, OPA Gatekeeper), list policies that affect `hostPort` in that namespace using your policy tool (no generic `kubectl` command exists; follow your policy system’s CLI/docs).

        4. **Implement or tighten admission policy to restrict `hostPort`**
           * Decide per namespace:
             * Namespaces where `hostPort` should be **disallowed** except for cluster-operator-approved workloads.
             * Namespaces where `hostPort` is **temporarily allowed** but must be minimized.
           * Apply or update your admission policy mechanism accordingly (Pod Security Admission level, Kyverno/Gatekeeper rules, or other). Document any namespace-specific exceptions and which service accounts / labels are allowed to use `hostPort`.
           * This step is policy- and environment-specific; there is no single `kubectl` command that enforces it generically.

        5. **Refactor or remove non-essential `hostPort` usage**
           * For pods marked “can be removed/avoided” in step 2:
             * Update their Deployment/DaemonSet/StatefulSet/Pod manifests (in Git/IaC or via `kubectl edit` if appropriate) to remove `hostPort` fields and use Services/Ingress instead.
             * Reapply manifests using your standard deployment process, for example:
               ```bash theme={null}
               kubectl apply -f UPDATED-MANIFEST.yaml
               ```
           * Ensure any required firewall or ingress changes are made so functionality is preserved without `hostPort`.

        6. **Verify minimized `hostPort` usage and effective restriction**
           * Re-run the discovery from step 1:
             ```bash theme={null}
             kubectl get pods -A -o jsonpath='{range .items[?(@.spec.containers[*].ports[*].hostPort)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.nodeName}{"\n"}{end}'
             ```
           * Confirm that:
             * Only the few, explicitly justified workloads still appear.
             * Creating a test pod with `hostPort` in a restricted namespace is rejected by admission (use a small test manifest and `kubectl apply -f test-hostport.yaml` to confirm it is denied).
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1) List all pods that request hostPorts in all namespaces
        # Run on: any machine with kubectl access
        kubectl get pods --all-namespaces -o=jsonpath='{range .items[?(@.spec.containers[*].ports[*].hostPort)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}'
        ```

        **Problem indication:**\
        Any line of output means that pod uses at least one `hostPort`. Each such pod must be manually reviewed to decide if `hostPort` is justified.

        ***

        ```bash theme={null}
        # 2) Show details of pods using hostPorts so you can review them
        # Run on: any machine with kubectl access
        kubectl get pods --all-namespaces -o json \
          | jq '.items[]
            | select(.spec.containers[].ports[]? | has("hostPort"))
            | {
                namespace: .metadata.namespace,
                name: .metadata.name,
                nodeName: .spec.nodeName,
                containers: [.spec.containers[]
                  | {
                      name,
                      ports: [.ports[]? | select(has("hostPort"))]
                    }
                ]
              }'
        ```

        **Problem indication:**\
        Look for:

        * Unnecessary `hostPort` use (e.g., `80`, `443`, `22`, or wide port ranges) where a Service/Ingress/LoadBalancer would suffice.
        * `hostPort` on multi-tenant or shared nodes.\
          Any such cases are candidates for remediation.

        ***

        ```bash theme={null}
        # 3) List NetworkPolicies that attempt to control hostPorts (for context)
        # Note: NetworkPolicies do NOT govern hostPorts, but this shows current intent
        # Run on: any machine with kubectl access
        kubectl get networkpolicy --all-namespaces -o wide
        ```

        **Problem indication:**\
        If you see NetworkPolicies that appear to “lock down” traffic but many workloads use `hostPort`, be aware that those policies do not protect the host-bound ports. This is an architectural risk to review.

        ***

        ```bash theme={null}
        # 4) Discover namespaces with user workloads but no admission policies defined
        # (to identify where you may need to add policies restricting hostPorts)
        # Run on: any machine with kubectl access
        echo "Namespaces with pods:" && \
        kubectl get pods --all-namespaces --no-headers | awk '{print $1}' | sort -u

        echo
        echo "Namespaces with LimitRanges (resource policies, FYI):" && \
        kubectl get limitrange --all-namespaces --no-headers 2>/dev/null | awk '{print $1}' | sort -u

        echo
        echo "Namespaces with NetworkPolicies:" && \
        kubectl get networkpolicy --all-namespaces --no-headers 2>/dev/null | awk '{print $1}' | sort -u
        ```

        **Problem indication:**\
        Namespaces appearing in “Namespaces with pods” but lacking any security/admission-related policy (and that also contain pods using `hostPort` from step 1/2) should be prioritized for adding policy to restrict `hostPort` usage.

        ***

        ```bash theme={null}
        # 5) For a specific namespace, inspect all pod specs for hostPort usage
        # Replace NAMESPACE with the namespace you are reviewing.
        # Run on: any machine with kubectl access
        NAMESPACE=default
        kubectl get pods -n "$NAMESPACE" -o yaml \
          | yq '.items[]
            | select(.spec.containers[].ports[]? | has("hostPort"))
            | {
                name: .metadata.name,
                nodeName: .spec.nodeName,
                containers: [.spec.containers[]
                  | {
                      name,
                      ports: [.ports[]? | select(has("hostPort"))]
                    }
                ]
              }'
        ```

        **Problem indication:**\
        If a namespace is intended to be “locked down” or multi-tenant but this output shows many pods with `hostPort`, the risk is higher and manual remediation is recommended (redesign to use Services, adjust placement, or introduce admission policy).
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Report all Pods and workload templates that use hostPort across the cluster.
        # Run on any machine with kubectl access and current-context set to the target cluster.

        set -euo pipefail

        echo "=== HostPort usage report (live Pods) ==="
        kubectl get pods --all-namespaces -o json \
          | jq -r '
            .items[]
            | . as $pod
            | (
                .spec.containers[]?,
                .spec.initContainers[]?
              )
            | select(.ports != null)
            | .ports[]?
            | select(.hostPort != null and .hostPort != 0)
            | "\($pod.metadata.namespace)\t\($pod.metadata.name)\t\($pod.spec.nodeName // "N/A")\t\(.name // "N/A")\t\(.containerPorts // .containerPort // "N/A")\t\(.hostPort)"
          ' 2>/dev/null \
          | awk 'BEGIN { printf "NAMESPACE\tPOD\tNODE\tCONTAINER\tCONTAINER_PORT\tHOST_PORT\n" } 1'

        echo
        echo "=== HostPort usage report (workload specs: Deployments, DaemonSets, StatefulSets, Jobs, CronJobs, ReplicaSets, ReplicationControllers) ==="
        kubectl get deploy,ds,sts,job,cronjob,rs,rc --all-namespaces -o json \
          | jq -r '
            .items[]
            | . as $w
            | (
                .spec.template.spec.containers[]?,
                .spec.template.spec.initContainers[]?
              )
            | select(.ports != null)
            | .ports[]?
            | select(.hostPort != null and .hostPort != 0)
            | "\($w.kind)\t\($w.metadata.namespace)\t\($w.metadata.name)\t\(.name // "N/A")\t\(.containerPorts // .containerPort // "N/A")\t\(.hostPort)"
          ' 2>/dev/null \
          | awk 'BEGIN { printf "KIND\tNAMESPACE\tNAME\tCONTAINER\tCONTAINER_PORT\tHOST_PORT\n" } 1'

        echo
        echo "=== Summary: total objects using hostPort per namespace (live Pods) ==="
        kubectl get pods --all-namespaces -o json \
          | jq -r '
            .items[]
            | select(
                (
                  .spec.containers[]? | .ports[]? | (.hostPort // 0)
                ) != 0
                or
                (
                  .spec.initContainers[]? | .ports[]? | (.hostPort // 0)
                ) != 0
              )
            | .metadata.namespace
          ' \
          | sort | uniq -c | sort -nr \
          | awk 'BEGIN { printf "COUNT\tNAMESPACE\n" } { print }'
        ```

        **How to interpret the output**

        * Any line where `HOST_PORT` (for Pods or workloads) is a non-zero value indicates a **potential policy violation** that must be reviewed.
        * Pay particular attention to:
          * User/application namespaces (e.g., not `kube-system`, `kube-public`, `kube-node-lease`).
          * HostPorts exposed on broad or privileged workloads (e.g., internet-facing services, DaemonSets).
        * Namespaces with non-zero `COUNT` in the summary should have admission policies (e.g., Pod Security Admission or Admission Webhooks) evaluated or added to restrict or justify hostPort usage.

        This script only reports; creating or tightening admission policies must be done manually based on your risk posture and any legitimate need for hostPorts.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
