ops: cloudflare-only origin firewall + weekly refresh timer

This commit is contained in:
Claude 2026-05-30 22:22:52 +02:00
parent 4dd0a5275f
commit 3cfbb5aa3c

28
scripts/cf-firewall.sh Normal file
View file

@ -0,0 +1,28 @@
#!/usr/bin/env bash
# Allow web ports (80/443) ONLY from Cloudflare IP ranges, so the origin
# is reachable only THROUGH the WAF. SSH (22) stays open. Idempotent —
# also used by a weekly systemd timer to track CF's IP list.
set -uo pipefail
v4=$(curl -fsSL https://www.cloudflare.com/ips-v4) || true
v6=$(curl -fsSL https://www.cloudflare.com/ips-v6) || true
if [ -z "${v4:-}" ] || [ -z "${v6:-}" ]; then
echo "ABORT: could not fetch Cloudflare IP ranges — no firewall changes made."
exit 1
fi
# Drop any broad web allows (keep OpenSSH / 22 untouched!)
ufw delete allow 80/tcp >/dev/null 2>&1 || true
ufw delete allow 443/tcp >/dev/null 2>&1 || true
ufw delete allow 443/udp >/dev/null 2>&1 || true
# Allow 80/443 only from Cloudflare
for ip in $v4 $v6; do
ufw allow from "$ip" to any port 80 proto tcp >/dev/null
ufw allow from "$ip" to any port 443 proto tcp >/dev/null
ufw allow from "$ip" to any port 443 proto udp >/dev/null
done
ufw reload >/dev/null
echo "CF ranges applied: $(echo "$v4 $v6" | wc -w) ranges"
echo "SSH(22) still allowed: $(ufw status | grep -c '22/tcp')"