#!/usr/bin/env bash set -euo pipefail FEED_URL="${FEED_URL:-https://magicplus-design.serveirc.com/share/untrustedIP}" SET_NAME="${SET_NAME:-ipsum_untrusted}" TMP_SET="${SET_NAME}_tmp_$$" IPTABLES_CHAIN="${IPTABLES_CHAIN:-INPUT}" IPTABLES_ACTION="${IPTABLES_ACTION:-DROP}" if [[ "${EUID}" -ne 0 ]]; then echo "Please run as root, for example: sudo bash $0" >&2 exit 1 fi for cmd in curl ipset iptables; do if ! command -v "$cmd" >/dev/null 2>&1; then echo "Missing required command: $cmd" >&2 exit 1 fi done cleanup() { ipset destroy "$TMP_SET" 2>/dev/null || true } trap cleanup EXIT feed_file="$(mktemp)" trap 'rm -f "$feed_file"; cleanup' EXIT curl -fsSL "$FEED_URL" -o "$feed_file" ipset create "$TMP_SET" hash:ip family inet hashsize 4096 maxelem 200000 -exist count=0 while IFS= read -r line; do ip="${line%%#*}" ip="$(printf '%s' "$ip" | tr -d '[:space:]')" [[ -z "$ip" ]] && continue if [[ "$ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then if ipset add "$TMP_SET" "$ip" -exist 2>/dev/null; then count=$((count + 1)) fi fi done < "$feed_file" if [[ "$count" -eq 0 ]]; then echo "No valid IPv4 entries were found in the feed." >&2 exit 1 fi if ipset list "$SET_NAME" >/dev/null 2>&1; then ipset swap "$TMP_SET" "$SET_NAME" ipset destroy "$TMP_SET" else ipset rename "$TMP_SET" "$SET_NAME" fi trap - EXIT rm -f "$feed_file" if ! iptables -C "$IPTABLES_CHAIN" -m set --match-set "$SET_NAME" src -j "$IPTABLES_ACTION" >/dev/null 2>&1; then iptables -I "$IPTABLES_CHAIN" 1 -m set --match-set "$SET_NAME" src -j "$IPTABLES_ACTION" fi echo "Done. Applied $count IPs to ipset '$SET_NAME' and ensured iptables $IPTABLES_CHAIN $IPTABLES_ACTION rule."