Skip to main content

Enable VPC Flow Logs And Intranode Visibility

More Info:

Enable VPC Flow Logs and intranode visibility so network traffic to, from, and between nodes is recorded for monitoring and forensics. Without them, network-level activity is not observable.

Risk Level

Medium

Address

Security

Compliance Standards

  • CIS GKE

Triage and Remediation

Remediation

Manual Steps
  1. Identify cluster networking settings
    Run on any machine with gcloud configured:

    gcloud container clusters describe CLUSTER_NAME \
    --location LOCATION \
    --project PROJECT_ID \
    --format json | jq '.networkConfig'

    Review:

    • .enableIntraNodeVisibility (should be true to meet the intent of the control)
    • .network and .subnetwork (VPC and subnet used by the cluster)
  2. Check current VPC Flow Logs status for the cluster subnet
    From the previous output, note the subnetwork name (without quotes), then run:

    gcloud compute networks subnets describe SUBNET_NAME \
    --region REGION \
    --project PROJECT_ID \
    --format json | jq '.logConfig'

    Review whether:

    • enable is true (Flow Logs enabled)
    • Optional: aggregationInterval, flowSampling, and metadata match your logging/forensics requirements.
  3. Decide on enabling intranode visibility
    Based on your security and performance requirements, decide whether to enable intra-node visibility (may increase load on network and logging backends). If required by your policy, plan to enable it for the cluster.

  4. Decide on enabling VPC Flow Logs
    Based on compliance, logging cost, and retention policies, decide whether to enable logConfig.enable=true for the cluster subnet. If required, plan to enable Flow Logs with appropriate sampling/aggregation settings.

  5. Apply configuration changes (if required by your decision)
    a. Enable VPC Flow Logs on the cluster subnet (any machine with gcloud):

    gcloud compute networks subnets update SUBNET_NAME \
    --region REGION \
    --project PROJECT_ID \
    --enable-flow-logs

    (Optionally add flags like --logging-aggregation-interval, --logging-flow-sampling, --logging-metadata as per your logging design.)

    b. Enable intranode visibility on the cluster:

    gcloud container clusters update CLUSTER_NAME \
    --location LOCATION \
    --project PROJECT_ID \
    --enable-intra-node-visibility
  6. Verify that changes are effective
    a. Verify intranode visibility:

    gcloud container clusters describe CLUSTER_NAME \
    --location LOCATION \
    --project PROJECT_ID \
    --format json | jq '.networkConfig.enableIntraNodeVisibility'

    Confirm the value is true.

    b. Verify VPC Flow Logs:

    gcloud compute networks subnets describe SUBNET_NAME \
    --region REGION \
    --project PROJECT_ID \
    --format json | jq '.logConfig'

    Confirm enable is true and that other settings match your intended configuration.

Using kubectl

kubectl cannot enable VPC Flow Logs or intranode visibility because they are configured at the GCP network and GKE cluster level, not via Kubernetes API objects. Apply the remediation using the Google Cloud Console, gcloud CLI, or your IaC tooling as described in the Manual Steps section.

Automation
#!/usr/bin/env bash
#
# Check CIS GKE 5.6.1: VPC Flow Logs and Intra-node Visibility
# Requirements:
# - gcloud, jq installed
# - Application Default Credentials or gcloud auth set up
#
# Runs from: any machine with gcloud access

set -euo pipefail

# ---------- CONFIGURATION ----------
# Optional: restrict to specific project(s) or locations
PROJECT_FILTER=() # e.g. PROJECT_FILTER=(my-prod-project my-dev-project)
LOCATION_FILTER=() # e.g. LOCATION_FILTER=(us-central1 us-east1)

# ---------- FUNCTIONS ----------
list_projects() {
if ((${#PROJECT_FILTER[@]})); then
printf '%s\n' "${PROJECT_FILTER[@]}"
else
gcloud projects list --format='value(projectId)'
fi
}

list_clusters() {
local project="$1"
if ((${#LOCATION_FILTER[@]})); then
for loc in "${LOCATION_FILTER[@]}"; do
gcloud container clusters list \
--project "$project" \
--region "$loc" \
--format='value(name,location)'
gcloud container clusters list \
--project "$project" \
--zone "$loc" \
--format='value(name,location)'
done | sort -u
else
gcloud container clusters list \
--project "$project" \
--format='value(name,location)'
fi
}

# ---------- MAIN ----------
echo "project,cluster,location,network,subnetwork,intra_node_visibility_enabled,subnet_flow_logs_enabled"

for project in $(list_projects); do
while IFS=$'\t' read -r cluster location; do
[[ -z "$cluster" ]] && continue

desc_json=$(gcloud container clusters describe "$cluster" \
--location "$location" \
--project "$project" \
--format=json)

network=$(echo "$desc_json" | jq -r '.network')
subnetwork=$(echo "$desc_json" | jq -r '.subnetwork')
inv_enabled=$(echo "$desc_json" | jq -r '.networkConfig.enableIntraNodeVisibility // false')

# subnet names may be full URLs; extract last component
subnet_name="${subnetwork##*/}"
network_name="${network##*/}"

subnet_json=$(gcloud compute networks subnets describe "$subnet_name" \
--project "$project" \
--region "$(echo "$location" | sed 's/-[a-z]$//')" \
--format=json 2>/dev/null || echo '{}')

flow_logs=$(echo "$subnet_json" | jq -r '.enableFlowLogs // false')

echo "$project,$cluster,$location,$network_name,$subnet_name,$inv_enabled,$flow_logs"
done < <(list_clusters "$project" | sed 's/ \+/\t/')
done

Explanation of output indicating a problem:

  • Any row where intra_node_visibility_enabled is false means intra-node visibility is not enabled for that cluster.
  • Any row where subnet_flow_logs_enabled is false means VPC Flow Logs are not enabled on the subnetwork used by that cluster.

Clusters where either (or both) of these columns are false require manual review and potential remediation using the benchmark’s recommended gcloud commands.