Skip to main content

GCP IP Ranges

Plugin: netflow-plugin Module: gcp-ip-ranges

Overview

Annotate network flows with Google ownership, service, and scope labels from Google public IP ranges. Google publishes its public IP ranges as two static JSON files served from gstatic.com. Wire one of them as a network_source and the netflow plugin fetches it periodically, transforms each prefix entry through your jq filter, and merges the resulting CIDR-keyed records into the network-attributes trie. Flows whose source or destination IP falls inside a Google-owned prefix are then labeled with *_NET_TENANT, *_NET_REGION, *_NET_ROLE, etc. according to the labels your transform emits.

Two upstream files exist and they are NOT interchangeable:

  • https://www.gstatic.com/ipranges/cloud.json -- the prefixes used by Google Cloud (Compute Engine, GKE, Cloud Run, Cloud Functions, Cloud SQL, and the rest of Google Cloud Platform). This is what you almost always want for cloud-traffic attribution.
  • https://www.gstatic.com/ipranges/goog.json -- the broader Google IP space, including consumer-facing properties (Search, Gmail, YouTube, Google Workspace, Maps, Ads, etc.). It is a strict superset of cloud.json but carries no service or region metadata -- only the bare CIDRs.

For the cross-cutting network-identity behavior (merge order with GeoIP and static config, jq output contract, TLS rules, single-page fetch, failure / backoff handling), see Network Identity.

Periodic HTTPS GET against the chosen gstatic.com URL. The body is parsed as JSON and the configured transform (a jaq jq-equivalent expression) runs over the parsed value. Each output object is merged into the network-attributes trie keyed on its prefix field; remaining fields (name, role, site, region, country, state, city, tenant, asn, asn_name) populate the corresponding *_NET_* flow-record columns when a flow's IP matches the prefix.

The upstream files are static JSON snapshots, not pageable APIs -- one fetch per cycle is the whole dataset. Each contains a syncToken and a creationTime you can inspect to see when Google last regenerated them. The plugin fetches the full document on each refresh cycle.

This integration is only supported on the following platforms:

  • Linux

This integration supports multiple instances configured side-by-side.

Default Behavior

Auto-Detection

Disabled by default. Add an entry under enrichment.network_sources to enable.

Limits

One full GCP prefix document is fetched per refresh. Resource use scales with the number of GCP prefixes selected by your transform and the refresh interval.

Performance Impact

One short HTTPS GET per interval, plus a jq pass over the response. cloud.json is on the order of ~1000 prefix entries and the trie merge is bounded by that count; runtime cost is negligible against typical flow ingest. goog.json is similar in size.

Setup

Prerequisites

Outbound HTTPS to gstatic.com

The agent host must be able to reach https://www.gstatic.com/ipranges/cloud.json (or goog.json). The files are public CDN-served static JSON; no Google Cloud project, no service account, no API key, and no IAM permission is required.

Pick the right file for your use case

  • Use cloud.json to attribute traffic to/from Google Cloud Platform services (Compute Engine VMs, GKE, Cloud Run, Cloud Functions, Cloud SQL, BigQuery API, Pub/Sub, GCS endpoints, etc.). Carries service and scope (region) per prefix.
  • Use goog.json to also catch non-cloud Google traffic (Gmail, YouTube, Google Workspace, Search, Ads, Maps, etc.). It carries no service or scope -- you only get "this is Google" attribution.
  • Configure both as separate sources if you want both attributions and a deterministic merge order between them. Within network-identity, more- specific prefixes win at lookup time, so a cloud.json match for a Compute Engine prefix will out-rank the broader goog.json umbrella.

Configuration

Options

Add a named entry under enrichment.network_sources. The entry name is cosmetic (used in logs and metrics); the labels that end up in flow records come from the fields your transform emits.

Config options
OptionDescriptionDefaultRequired
urlThe Google IP-ranges JSON URL. Use cloud.json for GCP services or goog.json for the broader Google IP space.https://www.gstatic.com/ipranges/cloud.jsonyes
intervalHow often to refetch. Google does not publish a fixed cadence; their documentation states the lists are "published and updated frequently". Daily is plenty for most deployments and avoids hammering the CDN.60s (loop floor)no
timeoutPer-request timeout.60sno
transformjq expression that converts each entry in prefixes[] into an object with a prefix field (CIDR string) plus any of the optional label fields (name, role, site, region, country, state, city, tenant, asn, asn_name). Required..yes

via File

The configuration file name for this integration is netflow.yaml.

You can edit the configuration file using the edit-config script from the Netdata config directory.

cd /etc/netdata 2>/dev/null || cd /opt/netdata/etc/netdata
sudo ./edit-config netflow.yaml
Examples
GCP cloud.json -- tag Google Cloud prefixes by region

Tags every flow whose IP matches a Google Cloud prefix with *_NET_TENANT="gcp", *_NET_ROLE="google-cloud", and *_NET_REGION set to the GCP scope (us-central1, europe-west1, global, etc.). Both ipv4Prefix and ipv6Prefix entries are covered by the // (slash-or) fallback.

enrichment:
network_sources:
gcp:
url: "https://www.gstatic.com/ipranges/cloud.json"
interval: 24h
timeout: 60s
transform: |
.prefixes[] | {
prefix: (.ipv4Prefix // .ipv6Prefix),
tenant: "gcp",
role: "google-cloud",
region: .scope
}

GCP cloud.json -- IPv4 only

Same as above but skips the IPv6 prefixes (some operators only need IPv4 attribution and prefer to keep the trie smaller).

Config
enrichment:
network_sources:
gcp-v4:
url: "https://www.gstatic.com/ipranges/cloud.json"
interval: 24h
transform: |
.prefixes[]
| select(.ipv4Prefix)
| {
prefix: .ipv4Prefix,
tenant: "gcp",
role: "google-cloud",
region: .scope
}

Tag a single GCP region

Narrow the source to one region (here us-central1) so you can build dashboards that distinguish that region from the rest of GCP.

Config
enrichment:
network_sources:
gcp-us-central1:
url: "https://www.gstatic.com/ipranges/cloud.json"
interval: 24h
transform: |
.prefixes[]
| select(.scope == "us-central1")
| {
prefix: (.ipv4Prefix // .ipv6Prefix),
tenant: "gcp",
role: "google-cloud",
region: "us-central1",
site: "us-central1"
}

Broader Google IP space (goog.json)

Use goog.json to also attribute traffic to non-Cloud Google services (Gmail, YouTube, Workspace, Search, Ads, Maps). The file has no service or scope fields, so only tenant / role are set. Configure this alongside cloud.json if you want both -- the more specific GCP prefixes from cloud.json will still win at lookup time.

Config
enrichment:
network_sources:
google-all:
url: "https://www.gstatic.com/ipranges/goog.json"
interval: 24h
transform: |
.prefixes[] | {
prefix: (.ipv4Prefix // .ipv6Prefix),
tenant: "google",
role: "google"
}

cloud.json vs goog.json -- pick the right one

cloud.json is the Google Cloud Platform list (Compute Engine, GKE, Cloud Run, Cloud SQL, BigQuery, GCS, etc.) and carries service plus scope (region) per entry. goog.json is the broader Google list (consumer products: Gmail, YouTube, Workspace, Search, Ads, Maps) and carries only the bare CIDRs -- no service, no scope, no region. Using goog.json as if it were cloud.json will give you "this is Google" attribution but no per-region or per-service breakdown. Most operators want cloud.json; some configure both as separate sources.

No per-service breakdown from cloud.json

Today every entry in cloud.json reports service: "Google Cloud" -- the file does not split prefixes by individual GCP service (Compute Engine vs GKE vs Cloud Run, etc.). Region (scope) is the dimension you can actually pivot on. Per-service attribution requires a different data source.

Empty result from the transform is treated as failure

If the jq expression yields zero objects (for example, an over-narrow select() that no entry passes), the source backs off as if the fetch had errored. Check the journal for network-sources warnings and verify your filter against a saved copy of cloud.json.

TLS verification cannot be disabled

tls.skip_verify: true (and tls.verify: false) are rejected by validation. gstatic.com is publicly trusted so this is rarely an issue for GCP; if you front the URL through an internal proxy with a private CA, supply it via tls.ca_file.

Update cadence is not contractual

Google states the lists are "published and updated frequently" but does not guarantee a fixed cadence. The syncToken and creationTime keys at the top of each file let you check when Google last regenerated it. Daily polling is a safe default; sub-hourly is unnecessary.


Do you have any feedback for this page? If so, you can open a new issue on our netdata/learn repository.