Geoblock access to specific URLs

How can I create a firewall rule, in the pro plan, geoblocking the access to URLs to a single country?

For my urls, the pattern ends in a list of IDs…so it would be like this http://some-stuff/1000

So I want to geoblock a list of ids, like 1000,1001,etc. Only those URLs to a single country. Is there a way to do this with cloudflare only?

Something like this should satisfy your requirements:

And then action: Block

But I’m not a regex expert, maybe someone can help with the URL matching?

2 Likes

If you are on a Free or Pro Plan, the MATCHES REGEX operator is not available to you. (annoyingly, it shows on the UI, but will return an error when you try to save it.).

In this case, you could use a list of URL with the IS IN operator, which obviously is not ideal since it requires constant maintenance – unless it’s a small, static website.

If IS IN {"/1000/" "/1001/"...} then...

If the IDs are preceded by a constant (eg, /ids/1000/ etc), you could also use the CONTAINS operator:

If CONTAINS /ids/ then...

Other than that, you could think of a solution where your origin appends a query string key-value pair in the desired situation, and then use the URI QUERY STRING selector.

2 Likes

Oh yeah, thanks for pointing this out.

2 Likes

This would not work for me… Because see this example.

A id of 1234, would match the id 12345, which is a different unrelated ID.

There are about ~700 IDs I want to geoblock, mostly static, so setting it up once is ok but I still don’t see how to avoid matching IDs out of my list without regex. :frowning:

Did you try adding the IDs one by one? You surely have a list of them, all you need is to generate a space-separated list of IDs, each padded with slashes and double quotes, and add the list to the Editor in the Firewall Rules app.

It should be something like

If URI Path IS IN {"/1000/" “/1001”…} AND
Country is XX
Then Block/Challenge etc.

3 Likes

It might have to be split into two rules:

Firewall Rules expressions have a 4KB limit. This is approximately 4,000 text characters. This limit applies whether you use the visual Expression Builder or edit your expression manually in the Expression Editor .

2 Likes

This is not working for me:

(http.request.uri.path in {"/55022" “/55023”} and not ip.geoip.country in {“US”})

WIth this rule, a non US IP can still hit the url http://something/someting/something/55022

If possible I’d like to catch everything after the ID too if they exists = /55022*

What I’m doing wrong??

The IS IN operator must include a list of the full path, not part of it. Your original message made me wrongly believe your URLs would be https://example.com/1000 and so on, but now you’ve added /something/something/.

Do these refer to constant path elements, or are they variable? If they are constant elements, you should add them to the expression. If they are variable, you need to use the CONTAINS operator and create a bunch of rules linked with the OR logic operator.

If
URI Path CONTAINS /1000 OR
URI Path CONTAINS /1001 OR…

Then group them using the Expression Editor to add the AND not ip.geoip.country part.

With the CONTAINS operator the rule should work just fine, with or without further elements after the ID number.

1 Like

The problem with contains:

Maybe a trailing slash will help define it.

At this point, it seems like all options have been presented and it’s up to the OP to experiment with what’s available.

1 Like

The issue with contain is also that I’d have have lots of OR, since it seems you can’t give multiple arguments to a single contain right?

Like you have to do this

(http.request.uri.path contains “/1”) or (http.request.uri.path contains “/2”)

Then I’d have to make so many rules because of the 4 KB limit… I think doing what I want is not feasible with cloudflare without the $200 plan…a shame because I’d buy the regex matching as a standalone feature

1 Like

This topic was automatically closed after 31 days. New replies are no longer allowed.