• Bash
    • cfips.sh

      Get list of Cloudflare IPs to allow / allow only in Nginx. Run like once a day.


#!/usr/bin/env bash
##
# Generate nginx snippets allowing only Cloudflare IP ranges.
# Idea: https://www.frankindev.com/2020/11/18/allow-cloudflare-only-in-nginx/
##

set -euo pipefail

SNIPPETS_DIR="/etc/nginx/snippets"
ALLOW_CONF="${SNIPPETS_DIR}/allow-cloudflare.conf"
ALLOW_ONLY_CONF="${SNIPPETS_DIR}/allow-cloudflare-only.conf"

cf_ips() {
  echo "# https://www.cloudflare.com/ips"

  local type
  for type in v4 v6; do
    echo "# IP${type}"
    curl -fsS "https://www.cloudflare.com/ips-${type}" \
      | sed 's|^|allow |; s|$|;|'
    echo
  done

  echo "# Generated at $(LC_ALL=C date)"
}

main() {
  echo "Fetching IP list from Cloudflare.."
  local ips
  ips=$(cf_ips)

  # Sanity check: make sure we actually got some allow rules
  if ! grep -q '^allow ' <<<"$ips"; then
    echo "Error: no IP ranges fetched from Cloudflare" >&2
    exit 1
  fi

  printf '%s\n' "$ips" > "$ALLOW_CONF"
  {
    printf '%s\n' "$ips"
    echo "deny all; # deny all remaining ips"
  } > "$ALLOW_ONLY_CONF"
  echo "Done."

  echo "Validating nginx config.."
  nginx -t

  echo "Reloading nginx.."
  systemctl reload nginx
  echo "Done."
}

main "$@"