> ## 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 Containers With The Net Raw Capability

### More Info:

Do not generally permit containers with the potentially dangerous NET\_RAW capability.

### Risk Level

Medium

### Address

Security

### Compliance Standards

* APRA CPS 234 (Australia)
* BSI C5 (Germany)
* Brazil LGPD
* CCPA / CPRA (California)
* CIS Critical Security Controls v8
* CIS EKS
* CMMC 2.0
* CSA Cloud Controls Matrix v4
* DPDPA
* Digital Operational Resilience Act (EU)
* Essential 8
* ISO/IEC 27017
* ISO/IEC 27018
* ISO/IEC 27701
* KSA PDPL
* MAS Technology Risk Management (Singapore)
* MITRE ATT\&CK (Cloud)
* NIS2 Directive
* NIST SP 800-171
* NYDFS 23 NYCRR 500
* SWIFT Customer Security Controls Framework
* Sarbanes-Oxley IT General Controls
* UK NCSC Cyber Assessment Framework

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **List current workload security settings (PSPs, PSP replacements, and policies)**\
           Run on: any machine with kubectl access
           ```bash theme={null}
           # PodSecurityPolicy (if still in use)
           kubectl get podsecuritypolicies.policy

           # Pod Security Admission (PSA) labels on namespaces (for newer clusters)
           kubectl get ns --show-labels | grep -E 'pod-security\.kubernetes\.io/(enforce|audit|warn)='

           # Common admission controllers: Gatekeeper, Kyverno, custom webhooks
           kubectl get validatingwebhookconfigurations.admissionregistration.k8s.io
           kubectl get mutatingwebhookconfigurations.admissionregistration.k8s.io
           kubectl get cpol,pol,clustercpol  -A 2>/dev/null || true
           ```

        2. **Discover pods that currently have NET\_RAW capability**\
           Run on: any machine with kubectl access
           ```bash theme={null}
           kubectl get pods -A -o json \
             | jq -r '
               .items[]
               | .metadata as $m
               | (.spec.initContainers[]?, .spec.containers[]?) as $c
               | select(
                   ($c.securityContext.capabilities.add[]? // "") == "NET_RAW"
                   or
                   (($c.securityContext.capabilities.drop // []) | index("ALL") | not)
                 )
               | "\($m.namespace) \($m.name) \($c.name)"' | sort -u
           ```
           Review the output and identify which workloads:
           * explicitly add `NET_RAW`, or
           * fail to drop `NET_RAW` by not dropping `ALL` (and not dropping `NET_RAW` specifically).

        3. **Review pod and namespace security configuration for each affected workload**\
           For each `(namespace, pod, container)` from step 2:
           ```bash theme={null}
           # Show full pod spec
           kubectl get pod -n <NAMESPACE> <POD_NAME> -o yaml

           # Show namespace labels / PSA configuration
           kubectl get ns <NAMESPACE> -o yaml

           # If PSP is used, see which PSP applies (cluster-specific process; as a proxy list PSPs)
           kubectl describe pod -n <NAMESPACE> <POD_NAME> | sed -n '1,80p'
           ```
           Manually check:
           * `securityContext.capabilities.add` for `NET_RAW`
           * `securityContext.capabilities.drop` includes `ALL` or at least `NET_RAW`
           * Whether any namespace or policy enforces a required drop of `NET_RAW`/`ALL`.

        4. **Decide if each use of NET\_RAW is strictly necessary**\
           For each affected container, consult the owning team and application documentation to determine:
           * Is raw socket / packet crafting actually required (e.g., low-level networking, certain monitoring agents, specialized load balancers)?
           * If yes, can the function be achieved using higher‑level networking APIs or sidecar patterns instead?
           * If no, plan to remove `NET_RAW` by:
             * eliminating it from `securityContext.capabilities.add`, and/or
             * adding `NET_RAW` or `ALL` to `securityContext.capabilities.drop`.

        5. **Adjust policies/manifests to require dropping NET\_RAW (or ALL) where safe**\
           Based on step 4 decisions:
           * For namespace/workload manifests (Deployment/DaemonSet/Job/etc.), edit source manifests or Helm charts to:
             * Remove any `NET_RAW` from `securityContext.capabilities.add`.
             * Add:
               ```yaml theme={null}
               securityContext:
                 capabilities:
                   drop:
                     - ALL
               ```
               or at minimum:
               ```yaml theme={null}
               securityContext:
                 capabilities:
                   drop:
                     - NET_RAW
               ```
           * For cluster-wide admission controls (PSP if still used, or equivalent OPA/Gatekeeper/Kyverno policies), configure rules that:
             * Require `NET_RAW` to be dropped, or
             * Forbid adding `NET_RAW`, except for carefully scoped exceptions (namespaces/labels).

        6. **Verify that NET\_RAW is no longer generally admitted**\
           After redeploying updated workloads and/or policies, re-run:
           ```bash theme={null}
           kubectl get pods -A -o json \
             | jq -r '
               .items[]
               | .metadata as $m
               | (.spec.initContainers[]?, .spec.containers[]?) as $c
               | select(
                   ($c.securityContext.capabilities.add[]? // "") == "NET_RAW"
                   or
                   (($c.securityContext.capabilities.drop // []) | index("ALL") | not)
                 )
               | "\($m.namespace) \($m.name) \($c.name)"' | sort -u
           ```
           Confirm:
           * No general-purpose workloads appear in the list.
           * Any remaining entries are explicitly reviewed and documented as justified exceptions.
      </Accordion>

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

        Problem indication: None yet; this is just to scope the review.

        ***

        ```bash theme={null}
        # 2. List all PodSecurityPolicy objects (if the API is enabled)
        # Run on: any machine with kubectl access
        kubectl get podsecuritypolicy.policy -o yaml
        ```

        Problem indication:

        * PSPs missing `requiredDropCapabilities` completely.
        * PSPs with `requiredDropCapabilities` present but NOT including `NET_RAW` or `ALL`.

        You are looking for sections like:

        ```yaml theme={null}
        spec:
          requiredDropCapabilities:
            - NET_RAW
        ```

        or

        ```yaml theme={null}
        spec:
          requiredDropCapabilities:
            - ALL
        ```

        PSPs whose `requiredDropCapabilities` list does not contain `NET_RAW` or `ALL` may allow containers with `NET_RAW`.

        ***

        ```bash theme={null}
        # 3. For each namespace, list pods and see what capabilities they actually have
        # (this is evidence; enforcement is via PSP/PodSecurityPolicy-like controls)
        # Run on: any machine with kubectl access

        # Example: review all pods (can be large)
        kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{" "}{.metadata.name}{"\n"}{end}'

        # For a specific namespace (replace <namespace>):
        kubectl get pods -n <namespace> -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}'
        ```

        Then inspect individual pods:

        ```bash theme={null}
        # Show full pod spec including securityContext and capabilities
        # Run for any suspicious pod
        kubectl get pod <pod-name> -n <namespace> -o yaml
        ```

        Problem indication in pod YAML:

        * At pod-level `securityContext`:
          ```yaml theme={null}
          spec:
            securityContext:
              capabilities:
                add:
                  - NET_RAW
          ```
        * Or at container-level:
          ```yaml theme={null}
          spec:
            containers:
              - name: ...
                securityContext:
                  capabilities:
                    add:
                      - NET_RAW
          ```

        Any pod or container explicitly adding `NET_RAW` is a potential concern and requires human review to determine if it is justified.

        ***

        ```bash theme={null}
        # 4. Quickly search all pod specs for NET_RAW (evidence of usage)
        # Run on: any machine with kubectl access
        kubectl get pods -A -o yaml | grep -n "NET_RAW"
        ```

        Problem indication:

        * Any matches show pods or containers declaring `NET_RAW` in their capabilities.
        * Each occurrence should be reviewed to decide whether `NET_RAW` is truly required.

        ***

        ```bash theme={null}
        # 5. Check for namespace-level Pod Security (if applicable) that might allow NET_RAW
        # Run on: any machine with kubectl access
        kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{" "}{.metadata.labels}{"\n"}{end}'
        ```

        Problem indication:

        * Namespaces labeled with privileged or unrestricted policies (for example, `pod-security.kubernetes.io/enforce=privileged` or similar) can make it easier for workloads to use `NET_RAW` without restriction.
        * These namespaces require closer review of workloads using the checks above.

        ***

        Use these commands to collect evidence. Determining whether and where to forbid `NET_RAW` (e.g. via PodSecurityPolicy or other admission controls) requires human judgment based on application needs and acceptable risk.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        # Report pods/containers that can use NET_RAW capability (add or not dropped)

        set -euo pipefail

        # REQUIREMENTS:
        # - Run on any machine with kubectl access and correct KUBECONFIG
        # - kubectl 1.14+ with JSONPath support

        echo "=== Scanning all pods/containers for NET_RAW capability exposure ===" >&2

        # 1. List pods that explicitly ADD NET_RAW in securityContext.capabilities.add
        echo
        echo "== Pods with containers that explicitly ADD NET_RAW =="
        kubectl get pods --all-namespaces -o json \
          | jq -r '
            .items[]
            | {
                ns: .metadata.namespace,
                pod: .metadata.name,
                containers: (
                  (.spec.containers + (.spec.initContainers // []))
                  | map(
                      {
                        name: .name,
                        addCaps: (.securityContext.capabilities.add // [] | map(. // ""))
                      }
                    )
                )
              }
            | {
                ns,
                pod,
                containers: (
                  .containers
                  | map(select(.addCaps | index("NET_RAW")))
                )
              }
            | select(.containers | length > 0)
            | [
                "NAMESPACE=" + .ns,
                "POD=" + .pod,
                "CONTAINER(S)=" + (.containers | map(.name) | join(",")),
                "ADDED_CAPS=" + (.containers | map(.addCaps | join(",")) | join(" | "))
              ]
            | join(" | ")
          ' 2>/dev/null || {
            echo "ERROR: This script requires 'jq' on PATH." >&2
            exit 1
          }

        # 2. List pods where NET_RAW is NOT in drop list and there is some capability use
        #    This surfaces containers that might retain NET_RAW by omission
        echo
        echo "== Pods with capabilities configured but NET_RAW is NOT in drop list =="
        kubectl get pods --all-namespaces -o json \
          | jq -r '
            .items[]
            | {
                ns: .metadata.namespace,
                pod: .metadata.name,
                containers: (
                  (.spec.containers + (.spec.initContainers // []))
                  | map(
                      {
                        name: .name,
                        addCaps: (.securityContext.capabilities.add // [] | map(. // "")),
                        dropCaps: (.securityContext.capabilities.drop // [] | map(. // ""))
                      }
                    )
                )
              }
            | {
                ns,
                pod,
                containers: (
                  .containers
                  | map(
                      select(
                        # Only consider containers that touch capabilities at all
                        ((.addCaps | length) > 0 or (.dropCaps | length) > 0)
                        # AND do not explicitly drop NET_RAW nor ALL
                        and ((.dropCaps | index("NET_RAW")) | not)
                        and ((.dropCaps | index("ALL")) | not)
                      )
                  )
                )
              }
            | select(.containers | length > 0)
            | [
                "NAMESPACE=" + .ns,
                "POD=" + .pod,
                "CONTAINER(S)=" + (.containers | map(.name) | join(",")),
                "ADD_CAPS=" + (.containers | map(.addCaps | join(",")) | join(" | ")),
                "DROP_CAPS=" + (.containers | map(.dropCaps | join(",")) | join(" | "))
              ]
            | join(" | ")
          '

        # 3. (Optional) List any PodSecurityPolicies that DO NOT drop NET_RAW or ALL
        #    Only relevant if PSP is still enabled in your cluster
        echo
        echo "== PodSecurityPolicies that do NOT require dropping NET_RAW or ALL (if PSP is enabled) =="
        if kubectl get podsecuritypolicies.policy >/dev/null 2>&1; then
          kubectl get podsecuritypolicies.policy -o json \
            | jq -r '
              .items[]
              | {
                  name: .metadata.name,
                  drop: (.spec.requiredDropCapabilities // [] | map(. // ""))
                }
              | select(
                  # PSPs that do NOT include NET_RAW and do NOT include ALL
                  ((.drop | index("NET_RAW")) | not)
                  and ((.drop | index("ALL")) | not)
                )
              | "PSP=" + .name + " | requiredDropCapabilities=" + (.drop | join(","))
            '
        else
          echo "No PodSecurityPolicies found or PSP API disabled; skip PSP check." >&2
        fi

        echo
        echo "=== Interpretation ==="
        cat <<'EOF'
        - Any line under "Pods with containers that explicitly ADD NET_RAW" indicates a clear problem:
          those containers are explicitly granted the NET_RAW capability.

        - Any line under
          "Pods with capabilities configured but NET_RAW is NOT in drop list"
          is a potential problem:
          these containers manipulate capabilities but do not explicitly drop NET_RAW
          (or ALL), so you must review if their effective capabilities include NET_RAW.

        - Any PSP listed under
          "PodSecurityPolicies that do NOT require dropping NET_RAW or ALL"
          should be reviewed: benchmark guidance expects requiredDropCapabilities
          to include NET_RAW or ALL.

        This script does NOT automatically fix anything; use it to identify and review
        workloads and policies that might violate the requirement to drop NET_RAW.
        EOF
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

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