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 ofcloud.jsonbut 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.jsonto 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.). Carriesserviceandscope(region) per prefix. - Use
goog.jsonto also catch non-cloud Google traffic (Gmail, YouTube, Google Workspace, Search, Ads, Maps, etc.). It carries noserviceorscope-- 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.jsonmatch for a Compute Engine prefix will out-rank the broadergoog.jsonumbrella.
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
| Option | Description | Default | Required |
|---|---|---|---|
| url | The 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.json | yes |
| interval | How 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 |
| timeout | Per-request timeout. | 60s | no |
| transform | jq 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.