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.
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 184.108.40.206/20 220.127.116.11/22 18.104.22.168/22 22.214.171.124/22 126.96.36.199/18 188.8.131.52/18 184.108.40.206/20 220.127.116.11/20 18.104.22.168/22 22.214.171.124/17 126.96.36.199/15 188.8.131.52/13 184.108.40.206/22 220.127.116.11/13 18.104.22.168/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.