Cloudflare + Site Security

I am a big believer in Cloudflare for site security however many people out there activate Cloudflare for server security without thinking about their own infrastructure still leaving them open to attack so here is a simple, but effective guide on how to to secure things just a little more if you’re using Cloudflare.

For starters, all my guides are written with Debian GNU linux in mind. We’re also using UFW as the firewall. It doesn’t matter what web server you’re using.

So, Cloudflare publish all their IP ranges on their support page here: https://www.cloudflare.com/ips/ – as from this post the current IP ranges for both IPv4 and IPv6 are:

# File generated 11/04/2021
173.245.48.0/20
103.21.244.0/22
103.22.200.0/22
103.31.4.0/22
141.101.64.0/18
108.162.192.0/18
190.93.240.0/20
188.114.96.0/20
197.234.240.0/22
198.41.128.0/17
162.158.0.0/15
172.64.0.0/13
131.0.72.0/22
104.16.0.0/13
104.24.0.0/14
2400:cb00::/32
2606:4700::/32
2803:f800::/32
2405:b500::/32
2405:8100::/32
2a06:98c0::/29
2c0f:f248::/32

Right, since we know this we’re going to activate UFW and only allow traffic through Cloudflare. I’m going to assume you know how to pass traffic through Cloudflare + know how to manage DNS records. Also, ensure you have another way to access your server (either physically or another shell) just in case you somehow lock yourself out. I’d also recommend using Mosh for accessing your server.

First, lets set up a basic firewall – lets say your server is listening on HTTP (80) and HTTPS (443) as well as SSH (22) and MOSH.

sudo apt-get install ufw
sudo ufw allow ssh
sudo ufw allow mosh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Now you have a basic firewall going – you can check it by running sudo ufw status numbered in your terminal. You should see both IPv4 and IPv6 (if enabled) rules spit out. If you’ve got Cloudflare running on your site you can continue – ensure traffic is going via Cloudflare else the following will take your site offline.

Lets automate this – make a new directory called /opt/cloudflare-ufw/ and create a new file called cloudflare-ufw.sh:

#!/bin/sh

DIR="$(dirname $(readlink -f $0))"
cd $DIR
wget https://www.cloudflare.com/ips-v4 -O ips-v4.tmp
wget https://www.cloudflare.com/ips-v6 -O ips-v6.tmp
mv ips-v4.tmp ips-v4
mv ips-v6.tmp ips-v6

for cfip in `cat ips-v4`; do ufw allow from $cfip to any port http comment "Cloudflare IPv4 HTTP"; done
for cfip in `cat ips-v6`; do ufw allow from $cfip to any port http comment "Cloudflare IPv6 HTTP"; done
for cfip in `cat ips-v4`; do ufw allow from $cfip to any port https comment "Cloudflare IPv4 HTTPS"; done
for cfip in `cat ips-v6`; do ufw allow from $cfip to any port https comment "Cloudflare IPv6 HTTPS"; done

ufw reload > /dev/null

Make this executable with “chmod +x /opt/cloudflare-ufw/cloudflare-ufw.sh” and add it to your crontab (crontab -e):

0 0 * * * bash /opt/cloudflare-ufw/cloudflare-ufw.sh >/dev/null 2>&1

This will make the script run daily at midnight (Cloudflare don’t update their IP lists too often, and if they do they do send out an email).

Clear out your old “allow-all” rules above by running “sudo ufw delete allow 80/tcp && sudo ufw delete allow 443/tcp”

And if you got this far and you can access your website then you’ve further secured your server. Congrats!

Extra for iptables:

With Oracle Cloud you can’t really use UFW due to their use of iptables for management. Using UFW will break one of these VM’s – it isn’t worth it.

Save this in /opt/cloudflare-iptables.sh:

#!/bin/bash
sleep 15
for i in `curl https://www.cloudflare.com/ips-v4`; do iptables -I INPUT -p tcp -m multiport --dports http,https -s $i -j ACCEPT; done
for i in `curl https://www.cloudflare.com/ips-v6`; do ip6tables -I INPUT -p tcp -m multiport --dports http,https -s $i -j ACCEPT; done
iptables -A INPUT -p tcp -m multiport --dports http,https -j DROP
ip6tables -A INPUT -p tcp -m multiport --dports http,https -j DROP

chmod +x /opt/cloudflare-iptables.sh to make it executable.

Now, let’s use systemd to run it on startup (I didn’t want to mess with the Oracle Cloud rules / double-up rules) – add a new file /etc/systemd/system/webfirewall.service:

[Unit]
After=network.service

[Service]
ExecStart=/opt/cloudflare-iptables.sh

[Install]
WantedBy=default.target

Now, run systemctl daemon-reload and enable the service with systemctl enable webfirewall.service. On reboot, your Oracle Cloud server will grab updated IP address from Cloudflare and apply them to iptables automatically.

Leave a Reply

Your email address will not be published. Required fields are marked *