GCP / Guide 4
VPC firewall rules and policies
How firewall rules decide, the default network, targeting by service account, firewall policies, risky rules, and checking what's allowed.
Google Cloud filters traffic to and from VMs with Cloud Next Generation Firewall (Cloud NGFW): classic VPC firewall rules on each network, and firewall policies that can apply across a whole organisation, folder or set of networks. Most exposure problems come from the default network's rules or one rule that allows SSH or RDP from 0.0.0.0/0 to every VM.
How VPC firewall rules decide
- Rules belong to a VPC network, not a subnet or a VM, and apply to the VMs they target (below). There's no separate per-subnet firewall.
- Priority decides. 0 is the highest and 65535 the lowest; new rules default to 1000. The highest-priority matching rule wins. At equal priority, deny beats allow.
- Rules are stateful. Replies to allowed connections are allowed automatically.
- Every network has two implied rules at priority 65535 that you can't see or delete: deny all ingress and allow all egress. Override them with your own rules at a lower number.
- Some traffic is always allowed: to and from the metadata server (
169.254.169.254), and a few platform flows. You can't block them. - Rules can be disabled without deleting them, which is useful while troubleshooting and dangerous when forgotten.
The default network
Unless an organisation policy prevents it (compute.skipDefaultNetworkCreation), every new project gets a network called default, with a subnet in every region and four permissive rules:
| Rule | Allows | From |
|---|---|---|
default-allow-internal | All TCP, UDP and ICMP | 10.128.0.0/9 (the network itself) |
default-allow-ssh | TCP 22 | 0.0.0.0/0 |
default-allow-rdp | TCP 3389 | 0.0.0.0/0 |
default-allow-icmp | ICMP | 0.0.0.0/0 |
Any VM with a public IP in that network has SSH and RDP open to the internet from the moment it starts. Delete the default network in every project (or at least those three internet rules), use custom-mode VPCs you design yourself, and set the organisation policy so new projects don't get one.
Target with service accounts or tags
A rule applies to the VMs it targets. Three ways to target, best last:
| Target | How it works | Watch out for |
|---|---|---|
| All instances | Every VM in the network | An "allow from internet" rule with no target opens every VM |
| Network tags | Plain strings on the VM, such as web | Anyone who can edit the VM can add the tag and get the access |
| Service accounts | The VM's attached service account | Changing it requires stopping the VM and permission to use the account: much harder to abuse |
| Secure tags (firewall policies only) | IAM-controlled Resource Manager tags bound to VMs | Only people granted tagUser can attach them |
Service accounts and secure tags are the Google Cloud equivalent of Azure's application security groups and AWS's security-group references: rules say "the web tier can reach the app tier on 8080", and scaling the tier needs no rule changes.
# Web tier reachable on 443 from the load balancer and health checks only
gcloud compute firewall-rules create allow-lb-to-web-443 --network=vpc-notes-test --direction=INGRESS `
--action=ALLOW --rules=tcp:443 --priority=1000 `
--source-ranges=35.191.0.0/16,130.211.0.0/22 `
--target-service-accounts=sa-web@prj-notes-test.iam.gserviceaccount.com `
--description="Google front ends and health checks to the web tier (CHG-1042)"
# App tier reachable on 8080 from the web tier only
gcloud compute firewall-rules create allow-web-to-app-8080 --network=vpc-notes-test --direction=INGRESS `
--action=ALLOW --rules=tcp:8080 `
--source-service-accounts=sa-web@prj-notes-test.iam.gserviceaccount.com `
--target-service-accounts=sa-app@prj-notes-test.iam.gserviceaccount.com
# Turn on logging for a rule (needed for Firewall Insights and troubleshooting)
gcloud compute firewall-rules update allow-web-to-app-8080 --enable-logging
35.191.0.0/16 and 130.211.0.0/22 are Google's load balancer and health check ranges: allow them to the backends of any Google Cloud load balancer, or health checks fail.
Firewall policies
VPC firewall rules are managed network by network. Firewall policies group rules and apply them more widely:
- Hierarchical firewall policies, attached to the organisation or a folder, apply to every network below. Use them for rules that must hold everywhere: block known-bad ranges, always allow the IAP and health-check ranges, deny RDP and SSH from the internet. A rule can
goto_nextto let the level below decide. - Global and regional network firewall policies attach to one or more VPC networks and support secure tags, FQDN and geolocation objects, and threat intelligence lists (with the Standard tier).
The default evaluation order for a VM is: hierarchical policies (organisation, then folders), then VPC firewall rules, then global and regional network firewall policies, then the implied rules. A network can be switched to evaluate network firewall policies before VPC firewall rules, which is the usual choice when migrating.
| Cloud NGFW tier | Adds |
|---|---|
| Essentials (no extra charge) | Rules on IP ranges, ports and protocols; VPC firewall rules; firewall policies with secure tags |
| Standard | FQDN objects, geolocation, Google threat intelligence lists |
| Enterprise | Intrusion prevention (IPS), TLS inspection, URL filtering |
Rules that cause trouble
Get-GcpFirewallReport.ps1 looks for these across every project:
- SSH (22) or RDP (3389) open to
0.0.0.0/0, starting with thedefaultnetwork's rules. Use IAP TCP forwarding instead: allow 22 and 3389 from35.235.240.0/20only (Guide 5). - Database and remote-management ports open to the internet: 1433, 3306, 5432, 6379, 27017, 5985/5986 and similar.
- Allow all protocols from anywhere. Usually added while troubleshooting.
- Internet rules with no target, which apply to every VM in the network, including ones created next year.
- Wide port ranges such as
0-65535or3000-4000, which quietly include 3389. - Disabled rules kept "just in case", and rules that no traffic has matched for months (Firewall Insights shows both).
Security Command Center's Security Health Analytics reports the same problems continuously (for example OPEN_SSH_PORT, OPEN_RDP_PORT and OPEN_FIREWALL).
A naming and priority convention
- Name rules
action-source-to-target-port, for exampleallow-web-to-app-8080, and put the reason or ticket in--description. - Use priority bands: 100–999 for explicit denies that must win, 1000–2999 for application allows, 3000–3999 for shared services (IAP, health checks, monitoring), and a deny-all ingress at 65000 so the intent is visible rather than implied.
- Deny egress to the internet for sensitive tiers with a low-priority egress deny, and allow only what they need (Private Google Access for Google APIs).
- Manage rules in Terraform, so a rule added by hand stands out in the next plan.
Check what is actually allowed
- Connectivity Tests (Network Intelligence Center) trace a packet between two endpoints through firewall rules and policies, routes and load balancers, and name what blocks it.
- Firewall Insights shows shadowed rules (never reached because a higher one matches first), overly permissive rules and rules with no hits.
- Firewall rules logging records each connection a rule allows or denies. Turn it on for internet-facing and deny rules.
- VPC Flow Logs sample traffic for a subnet (or a whole network), for troubleshooting and security investigations.
# Effective firewall rules and policies for one VM's network interface
gcloud compute instances network-interfaces get-effective-firewalls vm-notes-test-01 --zone=us-east1-b
# Would the internet reach this VM on 3389?
gcloud network-management connectivity-tests create rdp-from-internet `
--source-ip-address=203.0.113.10 --destination-instance=projects/prj-notes-test/zones/us-east1-b/instances/vm-notes-test-01 `
--destination-port=3389 --protocol=TCP
gcloud network-management connectivity-tests describe rdp-from-internet --format="value(reachabilityDetails.result)"