How can I control ips that can enter a sub directory?


#1

Hi Guys, quick question… How can I control ips that can enter a sub directory?


#2

You could use a firewall rule like this

(http.request.uri.path contains "/ghost" and not ip.src in {192.0.2.1 192.0.2.2})

This will only allow those IP addresses to access that subdirectory.


#3

You should add Block though as the directive. Because just like this isn’t really blocking, you missed the last row of the screenshot.


#4

You are quite right. Still, just a minor clarification for the OP. That rule will also block access to any other resource with /ghost in its name (/my-non-ghosty-directory/not-spooky-at-all/just-kidding/ghost-ghostier-ghostiest.jpg). This is due to the operators available to the starter plan and can only be properly addressed via workers, which are in turn a paid feature.


#5

Thank you, that worked.


#6

@sandro Not sure if I’m missing something on your comment, but it seems that with the free plan you can use the operator “equals” (eq) or “is in” (in) for that rule.


#7

Neither would - reasonably - work I am afraid if you want to target a directory with unknown content. You’d need a business plan with regular expressions.


#8

Not really, you can do a contains https://www.example.com/ghost, that would work.


#9

Good point, though that requires http.request.full_uri (instead of http.request.uri.path) and a fully qualified URL, meaning combinations of hosts and schemes are not possible.


#10

True, but it would still be a max size of 4 KiB, you could combine many similar rules. You could also combine reducing a bit the amount of matching, keeping in only the hostname.


#11

True, something of that sort should work

(http.request.full_uri contains "http://example.com/ghost" or
http.request.full_uri contains "https://example.com/ghost" or
http.request.full_uri contains "http://www.example.com/ghost" or
http.request.full_uri contains "https://www.example.com/ghost")
and not ip.src in {192.0.2.1 192.0.2.2}

Though I still prefer (http.request.uri.path matches "^/ghost") over that expression orgy :slight_smile:

I slightly edited my “definite” answer from earlier.


#12

Yeah, you could remove a bunch of those if you do redirects to HTTPS and to a canonical version in case the size grows too much.


#13

I certainly was missing something! I didn’t know until today that the field URI Path in a Firewall Rule would not be a match for anything but the path given. I always thought that URI Path would evaluate whether the path was a match for the given value and block/allow accordingly.

This brings to question the usefulness of this field. The help from Cloudflare Support gives the following example:

http.request.uri.path	String	/articles/index	The path of the request

and further down on the page:

English C-like String IP Address Number
eq == http.request.uri.path eq “/articles/2008/” ip.src eq 93.184.216.0 cf.threat_score eq 10
ne != http.request.uri.path ne “/articles/2010/” ip.src ne 93.184.216.0 cf.threat_score ne 60
lt < http.request.uri.path lt “/articles/2009/” cf.threat_score lt 10
le <= http.request.uri.path le “/articles/2008/” cf.threat_score le 20
gt > http.request.uri.path gt “/articles/2006/” cf.threat_score gt 25
ge >= http.request.uri.path ge “/articles/2007/” cf.threat_score ge 60
contains http.request.uri.path contains “/articles/”
matches ~ http.request.uri.path ~ “^/articles/200[7-8]/$”

So what they mean with all these examples (excepting the “matches”) is that we could use this field to apply a certain action to visitors who come for the specific directory /articles/2007/" or whatever and not to any hits to its pages??? Really? What’s the usefulness of that?

Access Policies, BTW, would be the appropriate method for restricting access in this situation. You would need to have two rules only, one for naked domain, one for www. (If you don’t force the redirect as suggested by @matteo). I always thought that Firewall Rules would interpret “path” the same way Access Policies do, by doing a match against the path, and only the path part of the URI and act accordingly.

Here’s how a single Access Rule for this example URL with path as “ghost” is applied:

http://encantarse.com/ghost/
https://encantarse.com/ghost/
http://encantarse.com/notghost/
http://encantarse.com/notghost/ghost/
http://encantarse.com/ghost-is-not-unix.html

(I intentionally did not create a second policy to protect www)


#14

It does, it does. But it depends on the operator you are using. If you are using equals it will search for an exact match. That works for many cases but not if you want to cover a directory path. contains can be used here but as that will be a substring match it will also match root directories other than the presumably configured. What it would need is a startsWith operator, which does not exist yet. On a business plan one can “work around” with regular expressions.

Do you mean Cloudflare access rules? Not sure what exactly you mean, but they shouldnt work in this context at all as they do not evaluate request parameters but only information related to the client IP address.


#15

I mean Cloudflare > Dashboard > Access > Create Access Policies.

You can create a single rule that applies to the given path and have it bypass your IP address or range:

You won’t be blocked if you navigate to:
https://encantarse.com

But will if you try
https://encantarse.com/ghost/

But won’t if you go to
https://encantarse.com/ghost-is-not-linux.html
or
https://encantarse.com/notghost/ghost/