Created
November 6, 2024 09:16
-
-
Save fulopattila122/c00cb21b8fa30b6dc2807cd16414902e to your computer and use it in GitHub Desktop.
Synchronize Cloudflare IP list from API with Linux Firewall (iptables)
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 | |
# Path to the IPs list | |
CF_IPS="/var/local/cloudflare_ips.json" | |
if [ -f $CF_IPS ]; then | |
OLDETAG=$(cat $CF_IPS| jq -r '.etag') | |
else | |
OLDETAG='XXXX' | |
fi | |
# Fetch latest Cloudflare IP list | |
APIRESULT=$(curl -s https://api.cloudflare.com/client/v4/ips) | |
if [[ $? -ne 0 || $(echo $APIRESULT | jq -r '.success') != "true" ]]; then | |
echo "There was an error fetching the Cloudflare IP lists" | |
echo $APIRESULT | jq -r '.errors' | |
exit 1 | |
fi | |
echo $APIRESULT | jq '.result' > $CF_IPS | |
ETAG=$(cat $CF_IPS| jq -r '.etag') | |
if [ $ETAG == $OLDETAG ]; then | |
echo "The Cloudflare IP range is unchanged. Firewall rules remain the same." | |
exit 0 | |
fi | |
# Load the current rules for comparison | |
FW_IPV4=$(iptables -L INPUT -v -n | grep tcp | grep dpt:80) | |
FW_IPV6=$(ip6tables -L INPUT -v -n | grep tcp | grep dpt:80) | |
CF_IPV4=$(echo $APIRESULT | jq -r '.result.ipv4_cidrs[]') | |
CF_IPV6=$(echo $APIRESULT | jq -r '.result.ipv6_cidrs[]') | |
# Apply the new rules if there are changes | |
if [ "$FW_IPV4" != "$CF_IPV4" ] || [ "$FW_IPV6" != "$CF_IPV6" ]; then | |
# Clear current rules on TCP 80 | |
# Remove existing rules for port 80 only | |
iptables -D INPUT -p tcp --dport 80 -j ACCEPT 2>/dev/null | |
iptables -D INPUT -p tcp --dport 80 -j DROP 2>/dev/null | |
ip6tables -D INPUT -p tcp --dport 80 -j ACCEPT 2>/dev/null | |
ip6tables -D INPUT -p tcp --dport 80 -j DROP 2>/dev/null | |
# Add Cloudflare IPs for IPv4 | |
for ip in $CF_IPV4; do | |
iptables -A INPUT -p tcp --dport 80 -s "$ip" -j ACCEPT | |
done | |
# Add Cloudflare IPs for IPv6 | |
for ip in $CF_IPV6; do | |
ip6tables -A INPUT -p tcp --dport 80 -s "$ip" -j ACCEPT | |
done | |
iptables -A INPUT -p tcp --dport 80 -j DROP | |
ip6tables -A INPUT -p tcp --dport 80 -j DROP | |
echo "Firewall updated with latest Cloudflare IPs." | |
else | |
echo "No changes in Cloudflare IPs. Firewall rules remain the same." | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I usually put this script in the
/usr/local/bin
folder. Afterwards, it can be added to the crontab so that it runs periodically.In the sample, it runs every 4 hours at XX:15 (00:15, 04:15, 08:15, etc.):