Setting Up UFW to Only Allow HTTP and HTTPS from CloudFlare

If you have a public-facing Ubuntu web server and are using Cloudflare to protect your websites, configuring UFW to only allow connections from CloudFlare will protect your server against malicious requests that bypass DNS entries and go directly to your servers IP address. This decreases your attack surface and forces all traffic through the CloudFlare CDN. Please note: these directions assume that you do NOT already have UFW rules in place that allow inbound traffic to ports 80 or 443 and that you DO already have necessary admin rules in UFW such as 22/SSH.

Download the two Cloudflare IP address lists:

wget https://www.cloudflare.com/ips-v4 && wget https://www.cloudflare.com/ips-v6

Create a bash script with the following text:

#!/bin/bash
for i in $(cat $1); do
        ufw allow proto tcp from $i to any port 80,443 > /dev/null
done

Make your script executable and then run it against the two IP lists:

chmod +x ufw.sh
sudo ./ufw.sh  ips-v4
sudo ./ufw.sh ips-v6

Now dump out your UFW rules, do a quick sanity check and turn up the rules:

sudo ufw status numbered
sudo ufw enable

Finally, use netcat to confirm that your rules are working correctly:

nc -vz ip-address-of-my-webserver 80
nc -vz ip-address-of-my-webserver 443
nc -vz hostname-on-my-webserver-with-cloudflare-enabled 80
nc -vz hostname-on-my-webserver-with-cloudflare-enabled 443

The first two commands should fail as they are trying to connect directly to your webserver and the second two should succeed as they are routing traffic through CloudFlare. If your UFW rules start getting tangled up, you can always reset UFW to default with the following command. Just make sure you re-add your SSH rule before re-enabling UFW!

sudo ufw reset