#!/bin/bash # تدریسینو: IPهای شناخته‌شده‌ی مخرب را پیش از اولین تلاش روی همه‌ی پورت‌ها می‌بندد. # فهرست: FireHOL level1 (Spamhaus DROP/EDROP، DShield، Feodo، bogons)، روزی یک بار (tadrisino-blocklist.timer). # شبکه‌های داخلی، رنجِ IPِ شرکت و رنج‌های ArvanCloud (از snippetِ nginx) هرگز بسته نمی‌شوند. # اگر دانلود نشد، آخرین فهرستِ سالم (/var/lib/tadrisino-blocklist/list) دوباره بار می‌شود. set -euo pipefail URL=https://iplists.firehol.org/files/firehol_level1.netset DIR=/var/lib/tadrisino-blocklist; SET=tadrisino-block mkdir -p "$DIR" tmp=$(mktemp); trap 'rm -f "$tmp"' EXIT if curl -fsS -m 90 "$URL" -o "$tmp" && [ "$(grep -c '^[0-9]' "$tmp")" -gt 1000 ]; then python3 - "$tmp" "$DIR/list" <<'PY' import ipaddress, re, sys src, dst = sys.argv[1], sys.argv[2] keep = ['127.0.0.0/8','10.0.0.0/8','172.16.0.0/12','192.168.0.0/16','100.64.0.0/10','169.254.0.0/16','78.38.35.0/24'] try: keep += re.findall(r'^allow\s+([0-9./]+);', open('/etc/nginx/snippets/zareian-arvan-only.conf').read(), re.M) except OSError: pass keep = [ipaddress.ip_network(k) for k in keep if ':' not in k] out, dropped = [], 0 for line in open(src): line = line.strip() if not line or line[0] == '#': continue n = ipaddress.ip_network(line, strict=False) if any(n.overlaps(k) for k in keep): dropped += 1 continue out.append(str(n)) open(dst, 'w').write('\n'.join(out) + '\n') print(f'{len(out)} networks, {dropped} skipped (internal/company/Arvan)') PY else echo "download failed; reloading last good list" >&2 fi [ -s "$DIR/list" ] || { echo "no list available" >&2; exit 1; } ipset create "$SET" hash:net maxelem 262144 -exist ipset create "$SET-new" hash:net maxelem 262144 -exist ipset flush "$SET-new" sed "s/^/add $SET-new /" "$DIR/list" | ipset restore -exist ipset swap "$SET-new" "$SET"; ipset destroy "$SET-new" iptables -C INPUT -m set --match-set "$SET" src -j DROP 2>/dev/null || iptables -I INPUT 1 -m set --match-set "$SET" src -j DROP echo "loaded $(ipset list "$SET" -t | sed -n 's/^Number of entries: //p') entries into $SET"