This check flags GCP firewall rules that expose Kibana (port 5601) to the public internet (0.0.0.0/0). An open Kibana endpoint hands attackers a window into your Elasticsearch data and often a foothold for full cluster takeover. Lock the source ranges to your VPC or VPN CIDRs and put Kibana behind an authenticating proxy.
Kibana is the visualization and management front end for Elasticsearch. It is incredibly useful for engineers, and incredibly useful for attackers when it sits on a public IP with no authentication. The vpc_openkibana check looks at your GCP firewall rules and raises a finding whenever a rule permits ingress to TCP port 5601 from a public source range.
This is one of those misconfigurations that looks harmless in a console but shows up almost immediately in internet-wide scans. Shodan and similar services index exposed Kibana instances constantly, so a publicly reachable dashboard is rarely undiscovered for long.
What this check detects
The check inspects every firewall rule in your GCP project and matches on two conditions at once:
- The rule allows ingress traffic on TCP port 5601, the default Kibana port.
- The
sourceRangesinclude a public CIDR, most commonly0.0.0.0/0but also any non-RFC1918 range that resolves to the open internet.
A rule like the one below would trigger the finding:
{
"name": "allow-kibana",
"network": "default",
"direction": "INGRESS",
"sourceRanges": ["0.0.0.0/0"],
"allowed": [
{ "IPProtocol": "tcp", "ports": ["5601"] }
]
}
Note: GCP firewall rules apply to instances by network tag or service account, not to specific IPs. A broad rule with 0.0.0.0/0 exposes every instance carrying the matching tag, so the blast radius is often larger than the person who created the rule expected.
Why it matters
Kibana is a control plane for your search data. When it is reachable from the internet, the consequences range from data theft to remote code execution depending on how the deployment is configured.
Direct data exposure
If Kibana is connected to an Elasticsearch cluster without authentication, anyone who loads the dashboard can browse, query, and export indices. For most organizations those indices contain application logs, customer records, audit trails, or PII. That is a reportable breach in many jurisdictions.
Cluster takeover and RCE
Kibana has a history of serious CVEs. The most famous, CVE-2019-7609, allowed an attacker to achieve remote code execution through the Timelion visualization feature on unpatched versions. Older Elasticsearch builds also shipped with scripting enabled by default, which has been used to pivot from a query interface to shell access on the underlying host.
Danger: An exposed Kibana that proxies to an unauthenticated Elasticsearch cluster is functionally an open database with a web UI. Treat any public 5601 finding as a potential active breach, not a theoretical risk.
Ransom and wipe campaigns
Automated attackers routinely scan for open Elasticsearch and Kibana, drop ransom notes into the indices, and delete the data. These campaigns are opportunistic and indiscriminate. You do not need to be a high-value target to get hit, you only need to be reachable.
How to fix it
The goal is simple: stop accepting Kibana traffic from the public internet. There are a few ways to get there depending on how your team works.
Step 1: Find the offending rule
gcloud compute firewall-rules list \
--format="table(name, network, sourceRanges.list(), allowed[].map().firewall_rule().list())" \
--filter="allowed.ports=5601"
This lists every rule touching port 5601 along with its source ranges so you can confirm which one is open.
Step 2: Restrict the source ranges
The cleanest fix is to replace 0.0.0.0/0 with the CIDR blocks that legitimately need access, such as your VPN, bastion subnet, or corporate egress IPs.
Warning: Updating a firewall rule takes effect immediately. If engineers are currently reaching Kibana over the public IP, they will lose access the moment you apply the change. Confirm an alternative path (VPN or bastion) works first to avoid an unexpected outage.
gcloud compute firewall-rules update allow-kibana \
--source-ranges="10.0.0.0/8,203.0.113.10/32"
Replace those ranges with your internal VPC CIDR and any specific office or VPN egress IPs.
Step 3: Delete the rule if Kibana should never be public
If the rule exists only because someone needed quick access once, remove it entirely and route through a bastion or the IAP-secured path described below.
Danger: Deleting a firewall rule is not reversible and may cut off legitimate traffic if the rule does more than expose Kibana. Inspect the full rule definition before running this command in production.
gcloud compute firewall-rules delete allow-kibana
Step 4: Put Kibana behind Identity-Aware Proxy (recommended)
Rather than relying on IP allowlists alone, front Kibana with an HTTPS load balancer and Google Cloud Identity-Aware Proxy (IAP). IAP enforces Google authentication and IAM-based authorization before any traffic reaches the instance, so even an internal user needs explicit permission.
At a high level you would:
- Place the Kibana instances in an unmanaged or managed instance group.
- Create an HTTPS load balancer with a backend service pointing at that group on port 5601.
- Enable IAP on the backend service and grant the
roles/iap.httpsResourceAccessorrole to the right users or groups. - Restrict the instance firewall so it only accepts traffic from the IAP and load balancer ranges (
35.235.240.0/20for IAP).
# Allow only IAP source range to reach Kibana instances
gcloud compute firewall-rules create allow-kibana-iap \
--direction=INGRESS \
--action=ALLOW \
--rules=tcp:5601 \
--source-ranges=35.235.240.0/20 \
--target-tags=kibana
Tip: Combine IAP with native Elasticsearch security (the free Basic tier now includes TLS and role-based access control). Defense in depth means a misconfigured proxy does not instantly equal an open cluster.
Fixing it as code
If you manage GCP with Terraform, codify the restriction so the open rule cannot drift back. A scoped firewall resource looks like this:
resource "google_compute_firewall" "kibana" {
name = "allow-kibana-internal"
network = google_compute_network.main.name
direction = "INGRESS"
allow {
protocol = "tcp"
ports = ["5601"]
}
# Internal VPC and IAP only, never 0.0.0.0/0
source_ranges = [
"10.0.0.0/8",
"35.235.240.0/20",
]
target_tags = ["kibana"]
}
Keeping the source ranges in version control means any future change to 0.0.0.0/0 shows up in a pull request where it can be caught in review.
How to prevent it from happening again
One-off remediation is fine, but the rule will reappear the next time someone needs fast access under deadline pressure. Build guardrails so the misconfiguration cannot ship.
Policy as code in CI
Use Open Policy Agent (OPA) with Conftest, or Checkov, to scan Terraform plans before they merge. A simple Conftest rule that blocks public access to sensitive ports:
package main
sensitive_ports := {"5601", "9200", "5432", "3389"}
deny[msg] {
rule := input.resource.google_compute_firewall[name]
rule.source_ranges[_] == "0.0.0.0/0"
port := rule.allow[_].ports[_]
sensitive_ports[port]
msg := sprintf("Firewall '%s' exposes port %s to the public internet", [name, port])
}
Wire that into your pipeline so a plan introducing a public 5601 rule fails the build.
Tip: Pair build-time policy with continuous detection. Lensix re-scans your live GCP environment so rules created manually through the console or gcloud, which never touch your IaC pipeline, still get caught.
Org policy constraints
At the organization level, consider the compute.vmExternalIpAccess constraint to limit which instances can have external IPs at all. If your Kibana hosts have no public IP, an accidental firewall rule has nothing to expose.
Best practices
- Never expose admin and data UIs publicly. Kibana, Grafana, Elasticsearch, and similar tools belong behind a VPN, bastion, or IAP.
- Default deny. Build firewall rules from a deny-all baseline and open only the specific ranges and ports you need.
- Use tags and service accounts, not broad rules. Scope each rule to the smallest set of instances so the blast radius stays small.
- Enable Elasticsearch security. Authentication and TLS are free in the Basic tier. Turn them on regardless of network controls.
- Patch promptly. Kibana RCE vulnerabilities are well documented and actively exploited. Keep your stack current.
- Audit continuously. Firewall configurations drift. Schedule recurring scans rather than relying on point-in-time review.
A public Kibana port is one of the highest-signal findings you can act on. It takes minutes to fix and closes off a path that attackers actively hunt for. Scope the source ranges, front it with IAP, and add a policy gate so it does not come back.

