Allowing only CloudFlare traffic to web server

September 19th, 2018
471 words · 3 minutes read · 0 Comments

The other day I had a somewhat panicked client come to me, worried by threats of DDoS attacks by some rogue user.
In order to reduce the attack vector in case said bad actor made good on their threats, I thought it might not be a terrible idea to disallow all HTTP(S) traffic that doesn’t come from CloudFlare. The client already utilises them for caching and load balancing, and their website claims that they are there to help in such situations.

Conveniently enough, there is a list of CloudFlare’s IP address ranges available online, along with text-only versions.

Combining these lists with a little bit of bash foo, I came up with the following (less than perfect) script, which is currently set to run as a cron task every now and then.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#!/bin/bash
#
# Only allow HTTP(s) access from CloudFlare
#

# Ensure cron task has a sensible PATH
PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'

# Add trusted IPv4 addresses here, one per line
# Could do something similar for IPv6 if any of us had one
TRUSTED_IPV4="
X.X.X.X/32
"
# Create a new chain called ‘cfX_http’.
iptables -N cf4_http
ip6tables -N cf6_http

iptables -F cf4_http
ip6tables -F cf6_http

# Add *our* trusted IPv4 addresses
for x in $TRUSTED_IPV4; do
iptables -A cf4_http --src $x -j ACCEPT
done

# Add the CloudFlare IPv4 Addresses
for x in $(curl https://www.cloudflare.com/ips-v4); do
iptables -A cf4_http --src $x -j ACCEPT
done

# Add the CloudFlare IPv6 Addresses
for x in $(curl https://www.cloudflare.com/ips-v6); do
ip6tables -A cf6_http --src $x -j ACCEPT
done

# Drop connections from any other IP address
iptables -A cf4_http -j DROP
ip6tables -A cf6_http -j DROP

# Use chain ‘cfX_http’ for packets coming to cfX_http ports
iptables -I INPUT -m tcp -p tcp --dport 80 -j cf4_http
ip6tables -I INPUT -m tcp -p tcp --dport 80 -j cf6_http
iptables -I INPUT -m tcp -p tcp --dport 443 -j cf4_http
ip6tables -I INPUT -m tcp -p tcp --dport 443 -j cf6_http

# Persist rules (ie, saved on reboot)
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6

Before getting excited and running this on your own machine, keep in mind it was developed and run on a Debian 8 (Jessie) machine that already has the iptables and iptables-persistent packages installed.

Caveat Empdor: Keep in mind that should either of those text files are un-downloadable things will get weird/broken, and your sites potentially not accessible.


Posted in: Tech

Leave a comment