Securing Your Origin Server by Automating UFW Rules for Cloudflare IPs

If you’re using Cloudflare to manage traffic to your origin server, you might want to restrict incoming traffic to only come from Cloudflare. This is crucial for protecting your origin server from potential unauthorized access. A handy tool that can aid in achieving this on an Ubuntu server is the UncomplicatedFirewall.

For those unfamiliar, UFW is a user-friendly front-end for managing iptables firewall rules on Ubuntu. If you’re new to UFW, Digital Ocean has a comprehensive tutorial to get you up to speed.

Cloudflare publishes a list of IPs they use. The script provided below will automate the process of downloading these IPs and setting up rules in UFW to allow traffic only from them on port 80.

Please note that UFW doesn’t allow tagging of rules, but we’ve added a comment cf” to each rule to help you identify those added by this script.

For the times when you want to delete these rules, the script has an inbuilt functionality to find and delete the rules with the cf” comment. To prevent accidental deletion, the script will ask you to type a randomly generated 8 character string for confirmation.

Here’s the script:

```bash
#!/bin/bash

add_rules() {
  curl https://www.cloudflare.com/ips-v4 -o ips-v4.txt

  # If you are running docker and it's talking back to the host, you might want
  # to add this as well. Otherwise, if no other IP address is allowed to talk to
  # port 80, then a docker process won't be able to talk either.
  #
  # sudo ufw allow in on docker0 comment "cf" # OPTIONAL

  while IFS= read -r ip; do
    echo "Adding $ip"
    sudo ufw allow from "$ip" to any port 80 proto tcp comment "cf"
  done < ips-v4.txt
}

delete_rules() {
  # Get a list of rules
  RULES=$(sudo ufw status numbered | grep "# cf")

  # Iterate over the rules backwards
  echo "$RULES" | tac | while IFS= read -r line; do
    # Get the rule number
    RULE_NUMBER=$(echo "$line" | awk -F"[" '{print $2}' | awk -F"]" '{print $1}')
    # Delete the rule
    echo "Deleting rule number $RULE_NUMBER"
    sudo ufw -f delete "$RULE_NUMBER"
  done
}

echo -n "Do you want to add or delete rules (add/delete)? "
read response

if [ "$response" = "add" ]; then
  echo "Adding rules..."
  add_rules

elif [ "$response" = "delete" ]; then
  random_word=$(tr -dc 'a-z' < /dev/urandom | head -c 8)

  echo "Enter the random word to confirm dropping UFW rules ($random_word): "
  read response

  if [ "$response" = "$random_word" ]; then
    echo "Deleting rules..."
    delete_rules
  else
    echo "Aborting ..."
  fi
fi

This script provides a simple, effective way to manage your UFW rules for Cloudflare traffic. As always, ensure to test any new scripts in a safe environment before deploying to your live systems — and do remember to modify it to your needs. Happy securing!



Date
May 22, 2023