> ## 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.

# Ensure The CNI In Use Supports Network Policies

### More Info:

Network Policies are only enforced when the clusters CNI plugin supports them. Enabling Network Policy in GKE updates the CNI to a policy-capable plugin.

### Risk Level

Medium

### Address

Security

### Compliance Standards

* CIS GKE

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Confirm GKE Network Policy feature status (per cluster)**
           * On any machine with `gcloud` and `kubectl` access, run:
             ```bash theme={null}
             gcloud container clusters list --project YOUR_PROJECT_ID
             gcloud container clusters describe YOUR_CLUSTER_NAME \
               --project YOUR_PROJECT_ID \
               --region YOUR_CLUSTER_REGION \
               --format="value(networkPolicy.enabled,networkPolicy.provider)"
             ```
           * If `networkPolicy.enabled` is `true` and a provider is shown (e.g. `CALICO`), the control plane is configured for Network Policy–capable CNI. If `false` or empty, Network Policy is not enabled.

        2. **Check that NetworkPolicy objects exist and are being used**
           * On any machine with `kubectl` access:
             ```bash theme={null}
             kubectl get networkpolicies --all-namespaces
             ```
           * If there are no `NetworkPolicy` objects but you expect network isolation, plan to create them; if there are many, note key namespaces/workloads that rely on them.

        3. **Validate that policies are enforced as expected (functional test)**
           * Create a temporary test namespace and pods:
             ```bash theme={null}
             kubectl create namespace netpol-test
             kubectl run allowed-client -n netpol-test --image=busybox --restart=Never \
               --command -- sleep 3600
             kubectl run test-server -n netpol-test --image=nginx --restart=Never
             kubectl expose pod test-server -n netpol-test --port=80
             ```
           * From `allowed-client`, verify it can reach the server before any policy:
             ```bash theme={null}
             kubectl exec -n netpol-test allowed-client -- wget -qO- http://test-server
             ```

        4. **Apply a restrictive NetworkPolicy and observe behavior**
           * Apply a policy that should block the above traffic:
             ```bash theme={null}
             cat << 'EOF' | kubectl apply -f -
             apiVersion: networking.k8s.io/v1
             kind: NetworkPolicy
             metadata:
               name: deny-all-ingress
               namespace: netpol-test
             spec:
               podSelector: {}
               policyTypes:
               - Ingress
             EOF
             ```
           * Test connectivity again; it should now fail:
             ```bash theme={null}
             kubectl exec -n netpol-test allowed-client -- wget -qO- http://test-server
             ```
           * If traffic still succeeds, your CNI is not enforcing NetworkPolicies (or another plugin/feature is overriding behavior).

        5. **If Network Policy is not enabled or not enforced, update cluster configuration**
           * Decide cluster-by-cluster whether you require NetworkPolicy enforcement. For clusters where you do:
             * Use GKE Console: Edit the cluster → enable “Network Policy” → save (this may trigger node pool recreation/rolling updates).
             * Or via CLI on any machine with `gcloud`:
               ```bash theme={null}
               gcloud container clusters update YOUR_CLUSTER_NAME \
                 --project YOUR_PROJECT_ID \
                 --region YOUR_CLUSTER_REGION \
                 --enable-network-policy
               ```
           * Plan maintenance windows as this can recreate nodes and briefly disrupt workloads.

        6. **Re-verify after changes**
           * After the update completes, repeat steps 1–4 to confirm:
             * `networkPolicy.enabled` is `true` with a supported provider.
             * The functional test shows traffic is allowed without policy and blocked with policy.
           * Clean up the test namespace when done:
             ```bash theme={null}
             kubectl delete namespace netpol-test
             ```
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1) List all NetworkPolicy objects in all namespaces
        # Run on: any machine with kubectl access
        kubectl get networkpolicy --all-namespaces -o wide
        ```

        Review points:

        * If you **expect** NetworkPolicies to be used and this returns **no resources found**, then NetworkPolicy is not being used; this may indicate a gap in your design, not in the CNI itself.

        ```bash theme={null}
        # 2) Inspect a sample NetworkPolicy (replace with a real name/namespace)
        kubectl get networkpolicy -n default -o yaml
        kubectl describe networkpolicy -n default <networkpolicy-name>
        ```

        Review points:

        * Ensure policies target pods that actually exist (selectors match current pod labels).
        * Check `kubectl describe` for any events or warnings suggesting policies are not applied as expected.

        ```bash theme={null}
        # 3) Confirm NetworkPolicy is recognized as an API resource
        kubectl api-resources | grep -i networkpolicy
        ```

        Expected:

        * You should see an entry like:
          * `networkpolicies networking.k8s.io/v1 true NetworkPolicy`
        * If there is **no line** for `networkpolicies`, the cluster is misconfigured or very old; NetworkPolicy cannot work regardless of CNI.

        ```bash theme={null}
        # 4) Verify GKE cluster Network Policy feature status (GKE only)
        # Run from: any machine with gcloud + kubectl configured and same project
        gcloud container clusters list \
          --format="table(name,location,networkPolicy.networkPolicyConfig.disabled,networkConfig.datapathProvider)"

        # For a specific cluster (replace with actual cluster name and location)
        gcloud container clusters describe <cluster-name> \
          --zone <zone> \
          --format="flattened(networkPolicy,networkConfig.datapathProvider)"
        ```

        Review points:

        * For `gcloud container clusters list`, look at:
          * `networkPolicy.networkPolicyConfig.disabled`
            * `false` → Network Policy is **enabled** at the GKE control-plane level.
            * `true` or empty → Network Policy is **not enabled**; even if NetworkPolicy objects exist, they will not be enforced by the CNI.
        * `networkConfig.datapathProvider`:
          * `ADVANCED_DATAPATH` or an equivalent policy-capable provider is expected when Network Policy is enabled.
          * If Network Policy is disabled and you rely on it for isolation, this is a **problem**.

        ```bash theme={null}
        # 5) (Optional) Simple runtime check using a temporary test pod
        # Create two test pods with labels (in a non-critical namespace)
        kubectl create ns netpol-test
        kubectl run client --image=busybox -n netpol-test --restart=Never --command -- sleep 3600
        kubectl run server --image=busybox -n netpol-test --restart=Never --command -- sh -c "nc -lk -p 80" 

        # Wait until both are Running, then:
        kubectl get pods -n netpol-test -o wide
        ```

        ```bash theme={null}
        # 6) Apply a restrictive NetworkPolicy and test connectivity
        cat <<'EOF' | kubectl apply -n netpol-test -f -
        apiVersion: networking.k8s.io/v1
        kind: NetworkPolicy
        metadata:
          name: deny-all-egress
        spec:
          podSelector:
            matchLabels: {}
          policyTypes:
          - Egress
        EOF

        # From client pod: attempt to connect to server and to the internet
        kubectl exec -n netpol-test client -- sh -c "nc -vz server 80 || echo 'connect to server failed'"
        kubectl exec -n netpol-test client -- sh -c "wget -qO- http://example.com || echo 'connect to internet failed'"
        ```

        Review points:

        * If NetworkPolicy is **supported and enforced**, you should see:
          * Connections that were previously succeeding now **failing** after the policy is applied, consistent with the policy rules.
        * If connections **continue to succeed** despite a clearly restrictive policy, that strongly suggests:
          * The CNI in use is **not** enforcing NetworkPolicies, or
          * Network Policy is not enabled at the GKE cluster level.

        ```bash theme={null}
        # 7) Cleanup of test namespace when finished
        kubectl delete ns netpol-test
        ```

        Finding interpretation:

        * **Problem indicated when**:
          * GKE cluster Network Policy is **disabled**, yet you rely on NetworkPolicies for pod isolation, or
          * Runtime tests show NetworkPolicies have **no effect** on traffic, despite being created and recognized by the API.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        # Purpose: Report whether the cluster's CNI and nodes support Kubernetes NetworkPolicies.
        # Run on: any machine with kubectl access and 'kubectl' configured for the target cluster.

        set -euo pipefail

        echo "=== 1) Detect cluster type (looking for GKE) ==="
        kubectl config current-context || {
          echo "ERROR: No current kubectl context" >&2
          exit 1
        }

        CONTEXT="$(kubectl config current-context)"
        echo "Current context: ${CONTEXT}"

        # Heuristic: GKE contexts typically look like gke_PROJECT_ZONE_CLUSTER
        if [[ "${CONTEXT}" == gke_* ]]; then
          echo "Cluster appears to be GKE (context name starts with 'gke_')."
        else
          echo "Cluster does not look like a standard GKE context."
          echo "This CISGKE control is intended for GKE, but results below may still be informative."
        fi
        echo

        echo "=== 2) Inspect CNI-related DaemonSets in kube-system ==="
        kubectl -n kube-system get ds \
          -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,IMAGES:.spec.template.spec.containers[*].image' \
          | sed '1!{/cni\|calico\|weave\|cilium\|flannel\|canal/!d}'

        echo
        echo "Details for suspected CNI DaemonSets (kube-system) ==="
        for ds in $(kubectl -n kube-system get ds -o name | sed -n '/cni\|calico\|weave\|cilium\|flannel\|canal/p'); do
          echo "--- ${ds} ---"
          kubectl -n kube-system get "${ds}" -o yaml | awk '
            /kind: DaemonSet/ {print "# DaemonSet metadata:"}
            /name: / && /DaemonSet/ {print "  " $0}
            /image: / {print "  " $0}
          ' || true
        done
        echo

        echo "=== 3) Show CNI configuration files on each node (via hostPath mounts) ==="
        echo "Looking for known CNI config directories mounted into pods in kube-system..."
        kubectl -n kube-system get pods -o wide

        echo
        echo "Pods in kube-system with hostPath mounts under /etc/cni or /opt/cni: "
        kubectl -n kube-system get pods -o json \
          | jq -r '
              .items[]
              | {name: .metadata.name, ns: .metadata.namespace, volumes: .spec.volumes}
              | select(.volumes != null)
              | . as $pod
              | $pod.volumes[]
              | select(.hostPath != null)
              | select(.hostPath.path | test("^/etc/cni|^/opt/cni"))
              | "Pod: \($pod.ns)/\($pod.name)  hostPath: \(.hostPath.path)"
            '

        echo
        echo "NOTE: The above shows where CNI configs live on nodes (via hostPath mounts)."
        echo "You must manually log into nodes to inspect exact CNI config if needed."
        echo

        echo "=== 4) Check if any NetworkPolicy objects exist in the cluster ==="
        kubectl get networkpolicy --all-namespaces || true
        echo
        echo "Interpretation:"
        echo "- If you have NO NetworkPolicy objects, this control is low-risk right now,"
        echo "  but you still must ensure the CNI supports NetworkPolicy BEFORE creating any."
        echo

        echo "=== 5) Check for typical GKE Network Policy signals ==="
        echo "Checking for GKE-specific annotations/labels that often indicate Network Policy enablement..."
        echo

        echo "-- Cluster-wide hint from kube-system namespace (not authoritative) --"
        kubectl get ns kube-system -o yaml \
          | sed -n '/annotations:/,/labels:/p' || true
        echo

        echo "-- GKE-managed network policy controller (if present) --"
        kubectl -n kube-system get deploy \
          -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name' \
          | sed -n '/netpol\|network-policy\|calico\|cilium/p' || true
        echo

        echo "=== 6) Summary / what indicates a potential PROBLEM ==="
        cat <<'EOF'
        You must manually decide whether the CNI in use supports Kubernetes NetworkPolicy.
        Use the data above and the guidance below:

        POTENTIAL PROBLEM indicators:
        - The only visible CNI-related DaemonSets/images are known NON-policy CNIs (e.g. plain 'k8s.gcr.io/pause'
          does not count; common non-policy CNIs include plain 'flannel' without policy add-ons).
        - You see NetworkPolicy objects in the cluster (step 4 lists them), BUT:
          * There is no known policy-capable CNI DaemonSet (e.g. no Calico, Cilium, GKE Network Policy add-on),
            OR
          * You know from GKE console that "Network Policy" is DISABLED for this cluster.
        - On GKE specifically:
          * GKE console shows Network Policy is disabled for the cluster (you must check this manually),
            OR
          * Your CNI images look like the older non-policy CNI used by GKE before Network Policy was enabled.

        LIKELY OK indicators (but still require human confirmation):
        - On GKE:
          * GKE console shows Network Policy ENABLED for the cluster, AND
          * You see CNI/Network Policy components consistent with the enabled add-on.
        - On non-GKE clusters:
          * You clearly identify a CNI with documented NetworkPolicy support (e.g. Calico, Cilium, Weave Net
            with policy, Canal, etc.) from the DaemonSet/images and node CNI configs.

        Because this is a MANUAL control, there is no automated pass/fail:
        - Use this script to inventory:
          * Which CNI DaemonSets and images are present
          * Whether NetworkPolicy resources are being used
        - Then:
          * For GKE: verify in the GKE console/CLI that Network Policy is enabled for the cluster.
          * For other environments: consult the CNI plugin's official documentation to confirm it
            supports Kubernetes NetworkPolicy semantics.

        If you discover:
        - NetworkPolicies in use AND a CNI that does NOT support them:
          -> This is a finding. You must plan a migration to a policy-capable CNI
             (on GKE, by enabling Network Policy for the cluster).
        EOF
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
