From 3cfbb5aa3cb2e1e2e3bd58361fc8cbea3f869bf8 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 30 May 2026 22:22:52 +0200 Subject: [PATCH] ops: cloudflare-only origin firewall + weekly refresh timer --- scripts/cf-firewall.sh | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 scripts/cf-firewall.sh diff --git a/scripts/cf-firewall.sh b/scripts/cf-firewall.sh new file mode 100644 index 0000000..d8a03f7 --- /dev/null +++ b/scripts/cf-firewall.sh @@ -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')"