Last active
February 24, 2021 08:14
-
-
Save AndrewJDR/47ea02e7d5b4665d705e to your computer and use it in GitHub Desktop.
Cloudflare whitelist iptables update cron script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Based on a template iptables config file, create a new | |
# iptables file that includes whitelist rules for CloudFlare's | |
# servers to connect to our HTTP and HTTPS ports. This is useful | |
# if you want to really lock down your web server so that it only | |
# communicates with cloudflare's servers, not with the general public. | |
# It works like this: | |
# * Get an up-to-date list of CloudFlare's server IPs | |
# * Read in config template from /etc/sysconfig/iptables.template | |
# * Output an iptables configuration file /etc/sysconfig/iptables | |
# ( $CFRULES from the template file becomes the CloudFlare whitelist rules in the output.) | |
# * Restart iptables to load the new firewall rules -- only does this if the rules got updated. | |
## | |
# Make sure you have: | |
# * An /etc/sysconfig/iptables.template file containing all your iptables rules. | |
# It should look very similar to /etc/sysconfig/iptables, so I suggest | |
# "cp /etc/sysconfig/iptables /etc/sysconfig/iptables.template" as a first step. | |
# * A line containing only $CFRULES somewhere in your iptables.template file | |
# * Either ":INPUT DROP [0:0]" at the top of your iptables.template, | |
# or some rule below $CFRULES that blocks all input traffic to your ports 80/443. | |
# Note this REPLACES your /etc/sysconfig/iptables file. | |
# Again, before running the script, you should probably just | |
# "cp /etc/sysconfig/iptables /etc/sysconfig/iptables.template", then drop a $CFRULES line in there. | |
IPT_TEMP=/tmp/iptables.new | |
CFRULES="" | |
IPS=$(curl --max-time 10 --silent -S https://www.cloudflare.com/ips-v4) | |
if [ "$?" = "0" ]; then | |
for line in $IPS; do | |
line=$(echo "$line" | tr -c --delete "[:digit:]./") | |
CFRULES+="-A INPUT -p tcp -m multiport --dports 80,443 -s $line -j ACCEPT | |
" | |
done | |
eval "cat <<< \"$(</etc/sysconfig/iptables.template)\"" > $IPT_TEMP | |
diff -q $IPT_TEMP /etc/sysconfig/iptables | |
if [ -s $IPT_TEMP -a "$?" = "1" ]; then | |
mv -f $IPT_TEMP /etc/sysconfig/iptables | |
/etc/init.d/iptables restart | |
else | |
rm -f $IPT_TEMP | |
fi | |
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# An example iptables.template file. You'll probably want to tweak this. | |
*filter | |
:INPUT DROP [0:0] | |
:FORWARD DROP [0:0] | |
:OUTPUT ACCEPT [0:0] | |
# Pings | |
-A INPUT -j ACCEPT -p icmp --icmp-type destination-unreachable | |
-A INPUT -j ACCEPT -p icmp --icmp-type source-quench | |
-A INPUT -j ACCEPT -p icmp --icmp-type time-exceeded | |
-A INPUT -j ACCEPT -p icmp --icmp-type echo-request | |
# SSH | |
-A INPUT -j ACCEPT -p tcp --dport 22 | |
# Loopback | |
-A INPUT -i lo -j ACCEPT | |
# Stateful | |
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT | |
# Whitelist Cloudflare IPs | |
$CFRULES | |
# All other input traffic gets dropped, per the default policy rules at the top. | |
COMMIT |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Tested on a CentOS/RHEL server.