Why this matters
An open port is a rule that lets traffic reach a resource. On Google Cloud that usually means a VPC firewall rule that allows ingress from 0.0.0.0/0 or ::/0, a VM with an external IP, a load balancer forwarding rule, or a managed service set to public ingress. Each one is a path from the internet into your project.
Google Cloud VPC firewall rules are stateful and attach to a network. They can target all instances, a tag, or a service account. A rule that allows tcp:22 from anywhere on a network will let anyone reach SSH on every VM with that tag. The same logic applies to RDP, database ports, and admin consoles you expose yourself.
The goal is not to close everything. It is to make every open path intentional and owned. Use private access for admin work, put a load balancer or Identity-Aware Proxy in front of public apps, and keep a short list of ports that must face the internet. Then log the traffic so you can prove the change held.
Before you start
You need permission to read and change firewall rules, addresses, forwarding rules, and the services that publish endpoints. Common roles are Compute Security Admin for firewall rules and Compute Network Viewer for inventory. For Cloud Run you need run.admin or a custom role that can update services. For GKE you need cluster admin rights to change Services and Ingress.
Find out whether the project uses Shared VPC. In that setup the firewall rules live in the host project, not the service project. A change in the service project will not close the path. Ask the network owner for the host project ID and check the rules there.
Take a baseline before you edit. Export the firewall rule list, the external IP list, forwarding rules, Cloud Run services, and Cloud SQL instances. Enable VPC Flow Logs on subnets you care about and turn on firewall rules logging for rules you plan to change. Pick a low traffic window for removals. A closed port can break a deployment script, a monitoring probe, or a partner feed.
Decide the access model first. Admin access over IAP, private connectivity for databases, and public ingress only through a load balancer with Cloud Armor or an API gateway. Write that down so you can judge each rule against it.
How to do it
Work from the outside in. Start with rules that allow 0.0.0.0/0 or ::/0, then move to resources that have external addresses, then to managed services that publish endpoints. The steps below follow that order. Run them in a test project first if you can.
For each firewall rule, ask three questions. What does it target? Which source ranges and ports does it allow? Who owns the workload behind it? If you cannot answer all three, treat the rule as suspect. Replace broad rules with rules scoped to a service account or tag, and narrow the source to a known CIDR, a load balancer range, or an IAP range.
Do not stop at VPC firewall rules. A VM with an external IP and no firewall rule is still reachable if another rule allows the port, and a load balancer can publish a backend that has no external IP. Cloud Run, Cloud Functions, App Engine, and GKE each have their own ingress controls. Check them in the same pass.
Keep a rollback note for each change. The exact gcloud command, the old rule, and the service owner are enough. If a removal breaks a health check, you want to restore the rule before you start guessing.
- Inventory firewall rules and public addresses. Run gcloud compute firewall-rules list and filter for rules with source ranges 0.0.0.0/0 or ::/0. Then run gcloud compute addresses list and gcloud compute forwarding-rules list to find external IPs and load balancer front ends.
- Replace broad admin rules with IAP. Remove rules that allow tcp:22 or tcp:3389 from 0.0.0.0/0. Add a rule that allows the IAP TCP forwarding range 35.235.240.0/20 to the target tag or service account on those ports only. Connect with gcloud compute ssh --tunnel-through-iap or the equivalent RDP tunnel.
- Scope application rules to targets. For each public app port, create or edit a rule with a specific target service account, a narrow source range, and the exact port. Use priority to place the narrow rule above any broad rule, then disable the broad rule. Check that the broad rule is not still active through another network.
- Audit external IPs and load balancers. List static and ephemeral external addresses and map each one to a resource. For load balancers, check the forwarding rule, the target proxy, and the backend service. If a front end is not needed, delete the forwarding rule and release the address.
- Lock down serverless ingress. For Cloud Run, set ingress to internal or internal-and-cloud-load-balancing unless the service must be public. Require authentication unless it is a public site. For Cloud Functions, set ingress settings to internal-only or internal-and-gclb. For App Engine, review the firewall rules and the default rule.
- Restrict GKE Services and Ingress. Change Service type LoadBalancer to Internal using the networking.gke.io/load-balancer-type annotation, or use an internal Ingress class. Use private clusters and control plane authorized networks. Add NetworkPolicy only as a pod level control, not as a replacement for VPC firewall rules.
- Close public database endpoints. For Cloud SQL, remove authorized networks that use 0.0.0.0/0, then disable the public IP if private IP and the Cloud SQL Auth Proxy meet your needs. Check other managed databases for public endpoints and allow lists in the same way.
- Enable logging and alerts. Turn on firewall rules logging for the rules that remain public and VPC Flow Logs for the subnets. Create a log based alert for accepted connections from unexpected source ranges. Review the alert after a week and tune it.
How to check it worked
Run the inventory again and compare. You want a short list of rules with 0.0.0.0/0 or ::/0 and a reason for each one. Check that the rules you disabled are actually disabled, not just lower priority. A rule with priority 1000 that allows tcp:22 from anywhere still wins if no higher priority rule denies it.
Use Firewall Insights in Network Intelligence Center to find rules that are overly permissive, shadowed, or unused. It can show which rules have no hits over a period, which helps you remove leftovers. Firewall rules logging and VPC Flow Logs show accepted connections. Look for traffic from public source addresses to ports you thought were closed.
Test from outside the VPC. Use a machine on the internet or a different cloud network to try the port. Do not test from a VM inside the same VPC, because firewall rules may not apply the same way to internal traffic. For Cloud Run, request the service URL without credentials and confirm you get a 403 or 404, not the app.
Check the managed services one by one. Cloud SQL should show no public IP or a tight authorized network list. GKE Services should show internal load balancers. Load balancer forwarding rules should match the front ends you intend to keep. Record the date and the owner for the next review.
Mistakes to avoid
The common mistake is deleting a broad rule without knowing what depends on it. Target tags and service accounts drift. A rule that looks unused may serve a batch job that runs once a month. Check logs over a full billing cycle or ask the owner before you remove it.
Another mistake is leaving IPv6 open. A rule that allows ::/0 on tcp:22 is just as public as 0.0.0.0/0. Check both address families. Also check egress rules that allow all destinations, because a compromised VM can use them to reach command and control hosts or exfiltrate data.
Do not treat a private IP as proof of safety. A VM with only a private IP can still reach the internet through Cloud NAT, and a private GKE cluster can still expose a public Ingress if the Service type is LoadBalancer. Check the actual endpoint, not the address type.
Do not rely on Cloud Armor or an API gateway to fix an open port. They protect traffic that reaches them. A firewall rule that allows tcp:8080 from anywhere to a VM bypasses that path. Close the port and put the proxy in front. If you want an outside read before you start, the Cloud security review from Cloudverg is a fixed price engagement at $6,500 that runs 2 to 3 weeks and covers network exposure, identity, logging and encryption across up to five cloud accounts.
Frequently asked questions
Does Google Cloud block all ports by default?
Google Cloud VPC firewall rules can allow or deny traffic, and a new network has an implied deny ingress rule at the bottom. Traffic is blocked unless a rule allows it. The default VPC network, if present, includes rules such as default-allow-ssh and default-allow-rdp that you should review and remove or narrow.
What is the difference between an open port and a public endpoint on Google Cloud?
An open port is a firewall rule that permits traffic to a port. A public endpoint is an address or URL that the internet can reach, such as an external IP on a VM, a load balancer forwarding rule, or a Cloud Run URL with public ingress. A public endpoint can exist without an open port if the service handles requests itself, so check both.
Can I close SSH and RDP ports and still manage my VMs?
Yes. Use Identity-Aware Proxy TCP forwarding and allow only the IAP range 35.235.240.0/20 to the instances on port 22 or 3389. Grant the IAP role to the people who need access and use gcloud compute ssh --tunnel-through-iap or an RDP tunnel. Keep a break glass path that is audited and time limited.