> ## 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 Admission Of Containers HostPorts

### More Info:

Do not generally permit containers which require the use of HostPorts.

### Risk Level

Low

### Address

Security

### Compliance Standards

* CIS Kubernetes

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Identify all pods 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}{"\n"}{end}'
             ```
             For more detail:
             ```bash theme={null}
             kubectl get pods -A -o json | jq '.items[]
               | select(.spec.containers[].ports[]? | has("hostPort"))
               | {ns:.metadata.namespace,name:.metadata.name,ports:[.spec.containers[].ports[]?|select(has("hostPort"))]}'
             ```

        2. **Review business / technical necessity of each `hostPort` use**
           * For each pod found, inspect its spec and discuss with the owning team whether `hostPort` is strictly required (e.g., legacy daemon, node-local listener):
             ```bash theme={null}
             kubectl -n <NAMESPACE> get pod <POD_NAME> -o yaml
             ```
           * Classify each as: “Required and justified” or “Not required / can be redesigned”.

        3. **Design namespace-level policy for `hostPort`**
           * For namespaces where `hostPort` is not needed at all, plan a policy that **denies any `hostPort`**.
           * For namespaces where a few workloads must use `hostPort`, plan a policy that **only allows specific ports or labels** and denies all other `hostPort` use.
           * Decide which admission control mechanism you will use (e.g., built‑in `PodSecurity` admission with restricted profiles plus an external policy engine like Kyverno / Gatekeeper, or just the external policy engine).

        4. **Implement or update the admission policies for each namespace**
           * Example: label namespace to use a restrictive Pod Security level (if compatible with workloads):
             ```bash theme={null}
             kubectl label namespace <NAMESPACE> pod-security.kubernetes.io/enforce=restricted --overwrite
             ```
           * Then add or adjust your chosen policy engine’s rules (Kyverno/OPA Gatekeeper/etc.) so that, in the target namespaces, pods with any container `ports.hostPort` are denied, or only allowed per your design. (This step is policy‑engine specific and must be done by editing/creating its ClusterPolicy/Constraint manifests and applying them with `kubectl apply -f <FILE>.yaml`.)

        5. **Refactor workloads that should not use `hostPort`**
           * For each pod classified as “Not required / can be redesigned”, modify its Deployment/DaemonSet/Pod manifest to remove `hostPort` from all container ports and rely on Services, NodePorts, or Ingress instead:
             ```bash theme={null}
             kubectl -n <NAMESPACE> edit <KIND> <NAME>
             ```
           * Or update the manifest in version control and apply:
             ```bash theme={null}
             kubectl apply -f <UPDATED_MANIFEST>.yaml
             ```

        6. **Verify enforcement and residual usage**
           * Confirm policies are active (policy‑engine specific; e.g., list Kyverno policies):
             ```bash theme={null}
             kubectl get clusterpolicy,policy -A
             ```
           * Attempt to create a test pod with `hostPort` in a namespace where it should be denied and confirm it is rejected.
           * Re-run the evidence command to ensure only approved workloads (if any) still use `hostPort`:
             ```bash theme={null}
             kubectl get pods -A -o jsonpath='{range .items[?(@.spec.containers[*].ports[*].hostPort)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}'
             ```
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1) List all namespaces to scope your review
        # Run on: any machine with kubectl access
        kubectl get namespaces -o name
        ```

        Look for namespaces that contain user workloads (typically not `kube-system`, `kube-public`, `kube-node-lease`, or cloud-provider system namespaces) and review those first.

        ```bash theme={null}
        # 2) Find all Pods that currently use hostPort in all namespaces
        # Run on: any machine with kubectl access
        kubectl get pods -A -o jsonpath='{range .items[*]}{@.metadata.namespace}{" "}{@.metadata.name}{"\n"}{range @.spec.containers[*]}{range @.ports[*]}{..hostPort}{"\n"}{end}{end}{end}' | paste - - | grep -v ' $'
        ```

        Output format:\
        `<namespace> <pod-name> <hostPort-value>`

        Any line returned indicates a Pod with at least one container exposing a `hostPort`. You must manually decide if each such use is strictly necessary; widespread or unexplained `hostPort` use is a problem.

        ```bash theme={null}
        # 3) See full Pod specs using hostPort in a specific namespace
        # Replace NAMESPACE with a namespace you identified above
        kubectl get pods -n NAMESPACE -o yaml | grep -nA5 -B10 "hostPort:"
        ```

        Review each occurrence of `hostPort:` and determine:

        * Is the `hostPort` needed (e.g., node-local DaemonSet, legacy integration)?
        * Could a Service/LoadBalancer/NodePort or Ingress replace it?

        Multiple apps using the same `hostPort` on many nodes, or general-purpose workloads with `hostPort` but no clear justification, indicate a problem.

        ```bash theme={null}
        # 4) Identify PodSecurityPolicy or admission policies that already restrict hostPorts (if PSP is in use)
        kubectl get podsecuritypolicies.policy -o yaml | grep -nA10 "hostPorts"
        ```

        If `hostPorts` ranges are wide (e.g., `0-65535`) or absent (no restriction at all), this suggests insufficient restriction and is a problem; narrow, explicit ranges only for known use cases are safer.

        ```bash theme={null}
        # 5) Inspect Pod Security admission labels (if using Pod Security Standards)
        kubectl get ns --show-labels
        ```

        Look for labels like `pod-security.kubernetes.io/enforce=privileged` or missing `baseline`/`restricted` labels on user namespaces. While Pod Security Standards do not directly block `hostPort`, very permissive or unset labels suggest that no higher-level guardrails exist, increasing risk when `hostPort` is used.

        ```bash theme={null}
        # 6) For a specific namespace, list all workload manifests to review for hostPort
        kubectl get deploy,ds,sts,job,cronjob -n NAMESPACE -o yaml | grep -nA5 -B10 "hostPort:"
        ```

        Any `hostPort:` in workload specs for general application Pods (web apps, APIs, batch jobs, etc.) is suspect. Only tightly controlled daemon-like workloads with clear operational justification should use `hostPort`.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        set -euo pipefail

        # This script reports:
        # 1) All Pods using hostPort
        # 2) All workloads (Deployments/DaemonSets/StatefulSets/ReplicaSets/Jobs/CronJobs)
        #    that define hostPort in their Pod templates
        # 3) Namespaces that lack a policy to restrict hostPorts (basic Gatekeeper/PSA hints)

        TS="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
        echo "=== HostPort usage report (${TS}) ==="
        echo

        ###############################################################################
        # 1) LIVE PODS USING hostPort
        ###############################################################################
        echo "1) Pods currently running with hostPort set"
        echo "------------------------------------------"

        kubectl get pods --all-namespaces -o json \
          | jq -r '
            .items[]
            | {ns: .metadata.namespace, name: .metadata.name, spec: .spec}
            | .spec.containers + (.spec.initContainers // [])
            | map({
                ns:   input_filename? // "N/A",
                name: .name,
                hostPort: (.ports // [] | map(select(.hostPort != null)) | .[])
              })' 2>/dev/null >/dev/null && : || true

        # simpler, robust jq:
        kubectl get pods --all-namespaces -o json \
          | jq -r '
            .items[]
            | . as $pod
            | ($pod.spec.containers + ($pod.spec.initContainers // []))
            | map(
                .ports // []
                | map(select(.hostPort != null)
                  | {
                      namespace: $pod.metadata.namespace,
                      pod:       $pod.metadata.name,
                      container: .name? // "N/A",
                      hostPort:  .hostPort
                    }
                )
              )
            | add // empty
          ' | sort -u || true

        echo
        echo "If any lines are printed above, those Pods are using hostPort and should be reviewed:"
        echo "- Confirm business need for hostPort."
        echo "- Prefer Service types (NodePort/LoadBalancer) or Ingress instead of hostPort."
        echo

        ###############################################################################
        # 2) WORKLOAD TEMPLATES DEFINING hostPort
        ###############################################################################
        echo "2) Workloads whose Pod templates define hostPort"
        echo "-----------------------------------------------"

        # Helper function: scan a workload type
        scan_workload() {
          local kind="$1"
          kubectl get "${kind}" --all-namespaces -o json 2>/dev/null \
            | jq -r --arg KIND "${kind}" '
              .items[]
              | . as $w
              | ($w.spec.template.spec.containers + ($w.spec.template.spec.initContainers // []))
              | map(
                  .ports // []
                  | map(select(.hostPort != null)
                    | {
                        kind:      $KIND,
                        namespace: $w.metadata.namespace,
                        name:      $w.metadata.name,
                        container: .name? // "N/A",
                        hostPort:  .hostPort
                      }
                  )
                )
              | add // empty
            ' || true
        }

        for k in deployments.apps daemonsets.apps statefulsets.apps replicasets.apps jobs.batch cronjobs.batch; do
          scan_workload "$k"
        done | sort -u

        echo
        echo "Any workloads listed above have hostPort in their Pod spec templates."
        echo "These should be considered non-compliant unless there is a documented exception."
        echo

        ###############################################################################
        # 3) NAMESPACE-LEVEL POLICY HINTS
        ###############################################################################
        echo "3) Namespace-level policies related to hostPort / Pod Security"
        echo "-------------------------------------------------------------"

        echo "3.a) Namespaces with PodSecurity admission labels (baseline/restricted)"
        kubectl get ns --show-labels \
          | sed 's/,/\n    /g' \
          | awk 'NR==1 || /pod-security.kubernetes.io/'

        echo
        echo "Namespaces without pod-security.kubernetes.io labels likely rely on default cluster policy."
        echo "They may allow hostPorts unless restricted by another admission controller (e.g., Gatekeeper)."
        echo

        echo "3.b) Gatekeeper (if installed): Constraints that mention hostPort"
        if kubectl get crd constraints.gatekeeper.sh >/dev/null 2>&1; then
          kubectl get constraints.constraints.gatekeeper.sh --all-namespaces -o yaml 2>/dev/null \
            | grep -i -n 'hostPort' || echo "No Gatekeeper constraints mentioning hostPort found."
        else
          echo "Gatekeeper constraints CRD not detected; skipping Gatekeeper policy scan."
        fi

        echo
        echo "INTERPRETING POLICY OUTPUT:"
        echo "- Namespaces that run user workloads and have Pods/workloads using hostPort"
        echo "  but no evident PodSecurity labels or hostPort-related constraints are likely risky."
        echo "- Even with PodSecurity labels, you must verify that the policy level in use"
        echo "  actually disallows hostPort where it is not required."
        echo
        echo "Review the above data and decide, per namespace, which hostPort usages are justified."
        ```

        **How to run (any machine with kubectl access):**

        1. Save as `report-hostport-usage.sh`.
        2. Make executable:

        ```bash theme={null}
        chmod +x report-hostport-usage.sh
        ```

        3. Run:

        ```bash theme={null}
        ./report-hostport-usage.sh
        ```

        **Problem indicators in the output:**

        * Any Pods or workloads listed in sections 1 or 2 in namespaces where hostPort is not strictly required.
        * Namespaces with such usage but:
          * No PodSecurity admission labels, and
          * No Gatekeeper (or similar) constraints that restrict `spec.containers[].ports[].hostPort`.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://kubernetes.io/docs/concepts/security/pod-security-standards/](https://kubernetes.io/docs/concepts/security/pod-security-standards/)
