While I am not using Cloudflare anymore, I do still have a couple of the domains using this platform that are not production, so I was thinking to myself, as Cloudflare give you quite a lot of security controls and you also get a pretty good firewall/WAF on the basic plan - I thought I’d set myself a challenge.
The challenge, which in retrospect wasn’t that hard to do, was to only allow traffic to a domain name from only Cloudflare IP addresses, or more specifically the ZTNA address range.
I started with that will be simple. I can have an allow rule for the ranges that I want and a block rule for the ranges I don’t want, simple, if you navigate to Security > WAF
Then if you go to create a new rule then look for the actions you will notice there is a Block but not a Allow:
Unfortunately, not, I was thwarted at the moat with that idea as when you’re setting up WAF rules you do not get the option for allow but you do get the option for skip, skip is not block - which means I can use that to accomplish the mission.
Next, you need to consider how your rules are applied and in what order, as an example of this some devices will find a rule that matches and execute that rule only whereas other devices will evaluate all rules and apply the most restrictive, in the case of Cloudflare you can customise those options.
Add the Block rule for the domain
We need the block rule for the root domain this will only apply to "grizzlybear.me" the express required is below and the action is Block.
Expression : (http.host eq "grizzlybear.me")
Add the block rule for WWW extension
We need the block rule for the root domain this will only apply to "www.grizzlybear.me" the express required is below and the action is Block.
Expression : (http.host eq "www.grizzlybear.me")
Add the skip rule for Cloudflare network ranges (with customization)
This is the allow rule, but in this example if will use the Skip action to accomplish this however here will need to add all the Cloudflare IP addresses as this is where the connection will originate from as well, so lets stat with there:
The express for this will need to include all the IPv4 and IPv6 addresses as well and that looks like this in the expression filter:
(ip.src in {103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 104.16.0.0/12 108.162.192.0/18 131.0.72.0/22 141.101.64.0/18 162.158.0.0/15 172.64.0.0/13 173.245.48.0/20 188.114.96.0/20 190.93.240.0/20 197.234.240.0/22 198.41.128.0/17 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32 2405:8100::/32 2a06:98c0::/29 2c0f:f248::/32 2a09:bac5:3744:d2::/64})
We then need to ensure that we choose "Skip" and then select the option to skip "All matching custom rules" this will ignore the other two rules you have created and allow access.
WAF Rule Overview
If you have done that as per the guide it should look like this:
Test that non-ZTNA traffic is blocked
Now the theory goes if this works then you will not be able to access the website unless using the ZTNA agent which is restricted to authorised users only and the result, bingo......
Test that ZTNA traffic is allowed
Now we need to test that traffic via ZTNA is allowed otherwise this is all academic, so if I connect to that network and try the request again I should see the website- which again is a sucess.