1
0

iptables-restore.sh 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. #!/usr/bin/env bash
  2. # Pull the IRDB blocklist and atomic-replace an ipset.
  3. #
  4. # Usage (cron-friendly):
  5. # IRDB_URL=http://localhost:8081 IRDB_TOKEN=irdb_con_... \
  6. # IPSET_NAME=irdb-blocked examples/consumers/iptables-restore.sh
  7. #
  8. # Prerequisites:
  9. # - the ipset is referenced by an iptables rule, e.g.
  10. # iptables -I INPUT -m set --match-set irdb-blocked src -j DROP
  11. # - ipset and iptables-restore are installed
  12. # - the consumer's policy returns IPv4 entries (or a mixed set;
  13. # this script filters per family)
  14. #
  15. # Atomic-replace pattern: build a swap set in memory, swap, destroy
  16. # old. Even an in-flight rule keeps working through the swap.
  17. set -euo pipefail
  18. : "${IRDB_URL:?must be set}"
  19. : "${IRDB_TOKEN:?must be set}"
  20. IPSET_NAME="${IPSET_NAME:-irdb-blocked}"
  21. TYPE="${IPSET_TYPE:-hash:net}"
  22. TIMEOUT="${IRDB_TIMEOUT:-30}"
  23. LIST=$(curl -fsS --max-time "$TIMEOUT" \
  24. -H "Authorization: Bearer $IRDB_TOKEN" \
  25. -H "Accept: text/plain" \
  26. "$IRDB_URL/api/v1/blocklist")
  27. # Split into v4 / v6 — this script handles v4 only by default. Drop
  28. # v6 entries if your ipset is `hash:net` family inet; mirror this
  29. # script for inet6 if you need both.
  30. SWAP="${IPSET_NAME}-swap"
  31. # Re-create the swap set; ignore "Set cannot be created: set with the
  32. # same name already exists" since we destroy unconditionally below.
  33. ipset create "$SWAP" "$TYPE" -exist
  34. ipset flush "$SWAP"
  35. while IFS= read -r line; do
  36. [ -z "$line" ] && continue
  37. case "$line" in
  38. *:*) continue ;; # skip v6
  39. *) ipset add "$SWAP" "$line" -exist ;;
  40. esac
  41. done <<<"$LIST"
  42. # Make the existing target set if absent so the swap target is valid.
  43. ipset create "$IPSET_NAME" "$TYPE" -exist
  44. ipset swap "$SWAP" "$IPSET_NAME"
  45. ipset destroy "$SWAP"
  46. COUNT=$(ipset list -t "$IPSET_NAME" | awk -F': ' '/^Number of entries:/ {print $2}')
  47. echo "irdb-blocklist updated: $COUNT entries in $IPSET_NAME"