Added on Jul 12th, 2015 and marked as cloudflare cronjob nginx

Recently I’ve explained how to display the real IP address of a visitor when you’re using CloudFlare. In this follow up, I will explain how you can use a script to keep the list of CloudFlare IP addresses in your nginx config up to date.

Download this Bash script and save it on your server (I like to use /opt/scripts/ for things like this).

Some things to note about the script:

cloudflare-update-ip-ranges.shDownload
#!/bin/bash
# Location of the nginx config file that contains the CloudFlare IP addresses.
CF_NGINX_CONFIG="/etc/nginx/cloudflare"
# The URLs with the actual IP addresses used by CloudFlare.
CF_URL_IP4="https://www.cloudflare.com/ips-v4"
CF_URL_IP6="https://www.cloudflare.com/ips-v6"
# Temporary files.
CF_TEMP_IP4="/tmp/cloudflare-ips-v4.txt"
CF_TEMP_IP6="/tmp/cloudflare-ips-v6.txt"
# Download the files.
if [ -f /usr/bin/curl ];
then
curl --silent --output $CF_TEMP_IP4 $CF_URL_IP4
curl --silent --output $CF_TEMP_IP6 $CF_URL_IP6
elif [ -f /usr/bin/wget ];
then
wget --quiet --output-document=$CF_TEMP_IP4 --no-check-certificate $CF_URL_IP4
wget --quiet --output-document=$CF_TEMP_IP6 --no-check-certificate $CF_URL_IP6
else
echo "Unable to download CloudFlare files."
exit 1
fi
# Generate the new config file.
echo "# CloudFlare IP Ranges" > $CF_NGINX_CONFIG
echo "# Generated at $(date) by $0" >> $CF_NGINX_CONFIG
echo "" >> $CF_NGINX_CONFIG
echo "# - IPv4 ($CF_URL_IP4)" >> $CF_NGINX_CONFIG
awk '{ print "set_real_ip_from " $0 ";" }' $CF_TEMP_IP4 >> $CF_NGINX_CONFIG
echo "" >> $CF_NGINX_CONFIG
echo "# - IPv6 ($CF_URL_IP6)" >> $CF_NGINX_CONFIG
awk '{ print "set_real_ip_from " $0 ";" }' $CF_TEMP_IP6 >> $CF_NGINX_CONFIG
echo "" >> $CF_NGINX_CONFIG
echo "real_ip_header CF-Connecting-IP;" >> $CF_NGINX_CONFIG
echo "" >> $CF_NGINX_CONFIG
# Remove the temporary files.
rm $CF_TEMP_IP4 $CF_TEMP_IP6
# Reload the nginx config.
service nginx reload

I use the script in a cronjob to regularly check for updates. In order to do so, we first have to set the permissions correctly:

chmod 700 /opt/scripts/cloudflare-update-ip-ranges.sh

This will make the script executable for the user (root in my case since it needs to reload the nginx config), but for no one else.

Then add it to the user’s crontab:

crontab -e

by adding the following lines:

# Update CloudFlare IP Ranges (every Sunday at 04:00)
0      4       *       *       sun     /opt/scripts/cloudflare-update-ip-ranges.sh > /dev/null 2>&1

The list of IP addresses probably won’t change that often, so checking just once a week should be okay.