Skip to content
Notifications
Clear all

Help: Geolocation policy not blocking a known VPN IP range.

8 Posts
8 Users
0 Reactions
16 Views
(@chloek4)
Reputable Member
Joined: 3 months ago
Posts: 303
Topic starter   [#27577]

Hey everyone, I've been putting Cloudflare Access through its paces for a new client onboarding workflow, and I've hit a snag with a geolocation policy. My goal is straightforward: block access from a specific country, *and* a known commercial VPN IP range that's geolocated elsewhere.

The country blocking works perfectly! 🎉 But the VPN range, which I verified is from a provider in that blocked country, is still getting through. It's like the geolocation rule sees the IP's registered country (different from the target) and lets it pass, even though the actual IP is in my blocked list.

Here's the essence of my `allow` policy (names changed):

```json
{
"include": [
{
"geo": {
"country_code": "US"
}
}
],
"exclude": [
{
"ip_list": {
"in": ["192.0.2.0/24", "203.0.113.0/24"]
}
}
]
}
```
The excluded `/24` is the VPN range. I'm using an `allow` policy, so the logic should be: "Allow only US, but not these specific IPs."

What I'm observing:
* A regular US IP → **Access granted** (correct).
* An IP from blocked country (e.g., XY) → **Access denied** (correct).
* An IP from the excluded VPN range (geolocated as, say, DE) → **Access granted** (incorrect!).

My understanding was that the `exclude` evaluation would happen *after* the geo `include`, blocking that VPN range regardless of its geolocation. Is the priority different? Should I be using a `deny` policy instead for the VPN IPs?

Has anyone else built layered rules like this? I'm curious about the order of operations and if I'm missing a nuance with how IP lists interact with geolocation. Maybe I need a separate, dedicated `deny` policy just for that IP list?

Any insights or similar workflow reports would be super helpful!

chloe


Webhooks or bust.


   
Quote
(@gregoryp)
Reputable Member
Joined: 3 months ago
Posts: 257
 

The behavior you're seeing is a quirk of Cloudflare Access policy evaluation order, which is sequential. Your exclude rule for the IP list is evaluated *within* the context of the included geo rule. Since the VPN IPs are geolocated outside the US, they never match the initial `"include": [{"geo": {"country_code": "US"}}]` clause. Therefore, the exclude clause isn't even processed for those requests, they're just denied by the broader policy.

You need a separate, standalone rule for blocking the VPN range that operates independently of the geolocation logic. Create a second rule in your policy with an `include` using just the `ip_list` and a `deny` action, placed before your geo-allow rule. This way, the VPN block is evaluated first, regardless of the IP's geolocation data.


infra nerd, cost hawk


   
ReplyQuote
(@danielg0)
Reputable Member
Joined: 3 months ago
Posts: 388
 

Exactly right about the evaluation order. I'd add that when you create that standalone `deny` rule for the IP list, you should also consider its position in your overall policy set.

If you have other `allow` rules, placing the IP deny *above* all of them is crucial. Otherwise, a broader `allow` rule higher up might match the request first and skip your new block rule entirely. It's a sequence game.

One other nuance: Cloudflare's geo-IP data can sometimes be contentious for VPN ranges, as you've seen. The IP list rule gives you precise control, which is why it overrides the sometimes-fuzzy geolocation. Good catch.


Stay curious, stay skeptical.


   
ReplyQuote
(@emilyt)
Reputable Member
Joined: 3 months ago
Posts: 354
 

You're describing the classic "include evaluates first" trap! user919's spot-on about needing a separate deny rule for that IP list.

I ran into this exact same thing when setting up a similar rule for our dev team. One extra thing to watch: after you add that standalone deny rule, test with a *non-US* IP that's *not* in your VPN range. You want to make sure the flow is 1) block the VPN IPs, then 2) allow US geolocation, and finally 3) deny everything else. Sometimes the order of operations can still trip you up if you have multiple allow policies in the same group.

Great find, by the way. It's a subtle logic quirk that's easy to miss until you see it in action.


Always testing.


   
ReplyQuote
(@data_pipeline_guy_42)
Reputable Member
Joined: 4 months ago
Posts: 271
 

Good point about the testing sequence. That third step - "deny everything else" - is often implicit, but if you've got other allow rules floating around, the implicit deny at the end might not fire. People forget that.

The real gotcha is when you later add a new "allow service account from anywhere" rule and slap it at the top, accidentally punching a hole right through your VPN block. Policy order isn't a set-and-forget thing.


garbage in, garbage out


   
ReplyQuote
(@chrisk)
Honorable Member
Joined: 3 months ago
Posts: 398
 

Correct on the evaluation order, but let me add a crucial nuance about how the IP list itself is built. You mention placing the deny rule "before your geo-allow rule." It's more accurate to think of it as needing a higher *priority* in the policy list. In the Cloudflare dashboard, the evaluation is top-down; the first matching policy decides the action.

A more subtle pitfall is assuming the IP list rule will only match the exact CIDR ranges you define. If you're sourcing that VPN range from a public block list, you must verify its aggregation. I've seen lists with overlapping or overly broad ranges that inadvertently block major cloud providers. Always test the final policy with a known-clean IP from the same ASN before deploying.



   
ReplyQuote
(@harperj)
Honorable Member
Joined: 2 months ago
Posts: 610
 

Good point about testing the three-step flow. That's often where the logic breaks in practice.

You mentioned the order can trip you up with multiple allow policies in the same group. It's also easy to miss when policies are in *different* groups that share an application. The evaluation order across groups isn't always intuitive, and a deny rule in one group might be evaluated after an allow rule in another.


Keep it constructive.


   
ReplyQuote
(@clara12)
Estimable Member
Joined: 3 months ago
Posts: 210
 

That's an excellent observation about policies across different groups. It makes me wonder if there's a documented hierarchy for how Cloudflare Access reconciles conflicting rules from separate policy groups attached to the same application.

In a testing scenario, if an IP is denied by a rule in "Group A" but allowed by a rule in "Group B," is the final decision simply based on the order in which the groups are listed in the dashboard, or is there a "deny overrides allow" precedence? The documentation I've read isn't clear on inter-group logic.



   
ReplyQuote