Blocklists – Integration Guide Step-by-step instructions for firewalls, servers and reverse proxies. The Linux scripts and the nginx and CrowdSec examples were tested with the live lists.
| List (ID) | Content | False positives | Recommended for |
|---|---|---|---|
spamhaus_drop | Hijacked and criminal networks (Spamhaus DROP) | very low | everyone, inbound and outbound |
firehole_l1 | FireHOL Level 1: DROP, Feodo, bogons and more | low | routers and servers (good default) |
blocklistde_all | Attackers reported to blocklist.de in the last 48 hours (SSH, mail, web) | medium | servers reachable from the Internet |
dshield1 | DShield: top 20 attacking /24 networks | low | in addition to one of the lists above |
tor_exit, tor_all | Tor exit nodes / all Tor relays | by design | only if you want to lock out Tor users |
feodo | Botnet command and control servers (abuse.ch Feodo Tracker) | very low | outbound, so infected devices cannot reach their servers |
et_compromised | Known compromised hosts (Emerging Threats) | low | in addition to one of the lists above |
all | The lists above combined | medium | contains the Tor lists – Tor users are blocked too |
all_notor | The lists above combined, without Tor | medium | servers that should block attackers but not Tor users |
Not part of all: | |||
cins_army, ipsum_l3 | Large reputation lists: CINS Army, IPsum (on at least 3 blocklists) | medium | servers that see a lot of scanning |
doh_servers | Public DNS over HTTPS servers | by design | outbound only (LAN rule with destination = list), so devices use your own DNS |
cloudflare, aws, gcp | Networks of Cloudflare, Amazon AWS and Google Cloud | by design | cloudflare as an allow list for servers behind Cloudflare; aws/gcp to block data centers |
v64 Blocklist (Honeypot64), not part of all – live state with list token: | |||
v64 | Attackers reported by several independent Honeypot64 sensors (logins, exploits, scans), without research scanners | new | servers reachable from the Internet, in addition to one of the lists above |
v64_ssh, v64_web, v64_mail, v64_rdp, v64_scanner | Parts of v64 by attack: SSH/Telnet, web, mail logins, RDP, port scanners | new | in front of the matching service only |
v64_research | Research scanners (Shodan, Censys and others), not part of v64 | by design | only if you want to hide from these scanners |
Every list is available in three variants; replace <id> with the ID from the table:
https://ipv64.net/blocklists/ipv64_blocklist_<id>.txthttps://ipv64.net/blocklists/ipv64_blocklist_v4_<id>.txthttps://ipv64.net/blocklists/ipv64_blocklist_v6_<id>.txthttps://ipv64.net/blocklists/v64_mikrotik_v4_<id>.rsc and …_v6_<id>.rscFormat: one address or network (CIDR) per line, no comments. The lists are regenerated several times a day. Please fetch them at most every 30 minutes; every 1 to 6 hours is enough. Country and continent lists are on the list page. For scripts: index.json lists every list with count, last update, source, license and file names.
Live state of the v64 Blocklist (list token)
The addresses above deliver the v64 lists as a daily state (up to 24 hours old), free for everyone. The live state is updated every 30 minutes and is available for contributors (one of your Honeypot64 sensors reported in the last 7 days) and for all plans except Standard. Create your list token while logged in under Honeypot64 › List token and use this address:
https://ipv64.net/blocklists/live/<token>/ipv64_blocklist_v4_v64.txt v64, v64_ssh …, also v4/v6 and MikroTik .rsc).X-IPv64-List: daily); an unknown or deleted token gets HTTP 404.For current Debian, Ubuntu, Fedora, Proxmox and most routers on Linux. The script loads IPv4 and IPv6 into a separate table inet ipv64 and replaces it atomically. It does not touch your other rules. If a download fails, the old list stays active. Traffic forwarded to Docker containers or NATed hosts is filtered too.
Install (as root):
apt install -y nftables curl
curl -fsSo /usr/local/sbin/ipv64-blocklist-nft.sh https://ipv64.net/blocklists/tools/ipv64-blocklist-nft.sh
chmod +x /usr/local/sbin/ipv64-blocklist-nft.sh
/usr/local/sbin/ipv64-blocklist-nft.sh firehole_l1 Update every 4 hours and after a reboot (cron):
cat > /etc/cron.d/ipv64-blocklist <<'EOF'
17 */4 * * * root /usr/local/sbin/ipv64-blocklist-nft.sh firehole_l1 >/dev/null
@reboot root sleep 30 && /usr/local/sbin/ipv64-blocklist-nft.sh firehole_l1 >/dev/null
EOF Check and remove:
nft list chain inet ipv64 input # counters show dropped packets
nft delete table inet ipv64 # remove the blocklist completely #!/bin/sh
# IPv64.net blocklist for nftables (IPv4 + IPv6) - https://ipv64.net/v64_blocklist_integration_guide
# Usage: ipv64-blocklist-nft.sh [list] (default: firehole_l1, see https://ipv64.net/v64_blocklists)
# Run as root. Replaces table "inet ipv64" atomically; on a failed download the old sets stay active.
set -eu
LIST="${1:-firehole_l1}"
BASE="https://ipv64.net/blocklists"
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
for v in 4 6; do
curl -fsS --max-time 120 -o "$TMP/raw$v" "$BASE/ipv64_blocklist_v${v}_${LIST}.txt"
# only keep lines that look like an address or network
grep -E '^[0-9A-Fa-f:.]+(/[0-9]{1,3})?$' "$TMP/raw$v" > "$TMP/v$v" || true
done
if [ ! -s "$TMP/v4" ] && [ ! -s "$TMP/v6" ]; then
echo "ipv64-blocklist: download empty, keeping the active sets" >&2
exit 1
fi
elements() { # file -> "elements = { a, b, ... }" (nothing for an empty file)
[ -s "$1" ] || return 0
printf '\t\telements = { '
paste -sd, "$1" | sed 's/,/, /g'
printf ' }\n'
}
{
echo "table inet ipv64"
echo "delete table inet ipv64"
echo "table inet ipv64 {"
printf '\tset bl4 {\n\t\ttype ipv4_addr\n\t\tflags interval\n\t\tauto-merge\n'
elements "$TMP/v4"
printf '\t}\n\tset bl6 {\n\t\ttype ipv6_addr\n\t\tflags interval\n\t\tauto-merge\n'
elements "$TMP/v6"
printf '\t}\n'
# drop traffic FROM listed networks to this host and to forwarded/NATed hosts (routers, Docker)
printf '\tchain input {\n\t\ttype filter hook input priority -10; policy accept;\n\t\tip saddr @bl4 counter drop\n\t\tip6 saddr @bl6 counter drop\n\t}\n'
printf '\tchain forward {\n\t\ttype filter hook forward priority -10; policy accept;\n\t\tip saddr @bl4 counter drop\n\t\tip6 saddr @bl6 counter drop\n\t}\n'
echo "}"
} > "$TMP/ipv64.nft"
nft -f "$TMP/ipv64.nft"
echo "ipv64-blocklist: $LIST loaded ($(wc -l < "$TMP/v4") IPv4, $(wc -l < "$TMP/v6") IPv6 entries)"
For systems that still use iptables. The script fills one set each for IPv4 and IPv6 via ipset restore, swaps it in and adds the DROP rules only once (INPUT, FORWARD and, if present, Docker's DOCKER-USER chain).
apt install -y ipset iptables curl
curl -fsSo /usr/local/sbin/ipv64-blocklist-ipset.sh https://ipv64.net/blocklists/tools/ipv64-blocklist-ipset.sh
chmod +x /usr/local/sbin/ipv64-blocklist-ipset.sh
/usr/local/sbin/ipv64-blocklist-ipset.sh firehole_l1
echo '17 */4 * * * root /usr/local/sbin/ipv64-blocklist-ipset.sh firehole_l1 >/dev/null' > /etc/cron.d/ipv64-blocklist
echo '@reboot root sleep 30 && /usr/local/sbin/ipv64-blocklist-ipset.sh firehole_l1 >/dev/null' >> /etc/cron.d/ipv64-blocklist The @reboot line restores sets and rules after a restart, so ipset-persistent is not needed. Docker restarts its chains when the daemon restarts; run the script again afterwards.
#!/bin/sh
# IPv64.net blocklist for iptables + ipset (IPv4 + IPv6) - https://ipv64.net/v64_blocklist_integration_guide
# Usage: ipv64-blocklist-ipset.sh [list] (default: firehole_l1, see https://ipv64.net/v64_blocklists)
# Run as root. Loads the list into a new set and swaps it in; on a failed download the old set stays active.
set -eu
LIST="${1:-firehole_l1}"
BASE="https://ipv64.net/blocklists"
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
for v in 4 6; do
fam=inet; ipt=iptables
[ "$v" = 6 ] && { fam=inet6; ipt=ip6tables; }
set="ipv64-v$v"; new="ipv64-v$v-new"
curl -fsS --max-time 120 -o "$TMP/raw" "$BASE/ipv64_blocklist_v${v}_${LIST}.txt"
grep -E '^[0-9A-Fa-f:.]+(/[0-9]{1,3})?$' "$TMP/raw" > "$TMP/list" || true
n=$(wc -l < "$TMP/list")
if [ "$n" -eq 0 ] && [ "$v" = 4 ]; then
echo "ipv64-blocklist: IPv4 download empty, keeping the active set" >&2
exit 1
fi
ipset create -exist "$set" hash:net family "$fam" maxelem 1048576
ipset destroy "$new" 2>/dev/null || true
{ echo "create $new hash:net family $fam maxelem 1048576"; sed "s/^/add $new /" "$TMP/list"; } | ipset restore -exist
ipset swap "$new" "$set"
ipset destroy "$new"
# rules only once: -C checks whether the rule exists already
for chain in INPUT FORWARD; do
$ipt -C "$chain" -m set --match-set "$set" src -j DROP 2>/dev/null || $ipt -I "$chain" -m set --match-set "$set" src -j DROP
done
# Docker publishes ports through DOCKER-USER, not INPUT
if $ipt -nL DOCKER-USER >/dev/null 2>&1; then
$ipt -C DOCKER-USER -m set --match-set "$set" src -j DROP 2>/dev/null || $ipt -I DOCKER-USER -m set --match-set "$set" src -j DROP
fi
echo "ipv64-blocklist: $set ($LIST) loaded with $n entries"
done
IPv64_firehol, URL https://ipv64.net/blocklists/ipv64_blocklist_firehole_l1.txt, update frequency 1 day. Save and Apply Changes.IPv64_firehol, Destination any. Save and apply.Large lists (countries) may exceed Firewall Maximum Table Entries under System › Advanced › Firewall & NAT; raise the value if the alias stays empty. Diagnostics › Tables shows the loaded entries. pfSense checks URL tables once per day, so the live state of the v64 lists brings no advantage here.
IPv64_firehol, refresh frequency 0 days 4 hours, content https://ipv64.net/blocklists/ipv64_blocklist_firehole_l1.txt. Save and Apply.IPv64_firehol, Destination any. Save, drag the rule to the top and apply.Firewall › Diagnostics › Aliases shows the loaded entries and the last update.
These firewalls load a plain text list from a URL themselves. Steps follow the vendor documentation (PAN-OS 11.1, FortiOS 7.6, Sophos Firewall 21.5). The examples use the v64 Blocklist; every other list works the same way. For the live state enter the address with your list token. Set the update interval to 30 minutes or more – FortiGate refreshes every 5 minutes by default.
Palo Alto Networks (PAN-OS): External Dynamic List
IPv64_v64, Type IP List, Source https://ipv64.net/blocklists/ipv64_blocklist_v64.txt, optionally a Certificate Profile with the CA of the ipv64.net certificate (server authentication), Check for updates Hourly. OK.PAN-OS accepts IPv4 and IPv6 addresses, ranges and networks. All IP lists together may hold 50,000 addresses on most models (150,000 on PA-3200, PA-5200 and PA-7000); see List Capacities under Objects › External Dynamic Lists. If the server cannot be reached, the firewall keeps the last list.
Fortinet FortiGate (FortiOS): IP address feed
IPv64_v64, URL of external resource https://ipv64.net/blocklists/ipv64_blocklist_v64.txt, Refresh Rate 60 minutes. OK.The same on the CLI, plus a local-in policy that also protects the FortiGate itself (VPN, admin access); use a free policy number:
config system external-resource
edit "IPv64_v64"
set type address
set resource "https://ipv64.net/blocklists/ipv64_blocklist_v64.txt"
set refresh-rate 60
set server-identity-check full
next
end
config firewall local-in-policy
edit 100
set intf "any"
set srcaddr "IPv64_v64"
set dstaddr "all"
set service "ALL"
set schedule "always"
next
end FortiOS accepts IPv4 and IPv6 addresses, ranges and networks, one per line. server-identity-check checks the server certificate (default none).
Sophos Firewall: Third-party threat feeds
IPv64_v64, Action Block, Indicator type IPv4 address, External URL https://ipv64.net/blocklists/ipv64_blocklist_v4_v64.txt, Authorization No authentication, Validate server certificate on, Polling interval 1 hour (or 30 minutes). Save.Requires the license for third-party threat feeds (Xstream Protection). According to Sophos, these feeds take single IPv4 addresses only, no IPv6, ranges or networks. The ipv64.net lists contain networks and write single addresses as /32; whether Sophos accepts these entries has not been tested. XGS 87, 88 and 107 offer only 24 hours, 7 days or 30 days as polling interval.
ipv64.net provides ready-made import files. Each file first removes its own old entries and then adds the current ones to the address list IPv64-<id>. The following script downloads the file, imports it and is run by the scheduler every 6 hours. Paste it into the terminal (Winbox › New Terminal):
/system script add name=ipv64-blocklist policy=read,write,test source={
:foreach v in={"v4";"v6"} do={
:local f ("ipv64-" . $v . ".rsc")
/tool fetch url=("https://ipv64.net/blocklists/v64_mikrotik_" . $v . "_firehole_l1.rsc") dst-path=$f
:delay 2s
/import file-name=$f
/file remove $f
}
}
/system scheduler add name=ipv64-blocklist interval=6h start-time=startup on-event="/system script run ipv64-blocklist"
/system script run ipv64-blocklist
/ip firewall raw add chain=prerouting src-address-list=IPv64-firehole_l1 action=drop comment="IPv64 blocklist"
/ipv6 firewall raw add chain=prerouting src-address-list=IPv64-firehole_l1 action=drop comment="IPv64 blocklist" The raw rules drop the traffic before connection tracking, for the router and the LAN. Move them to the top of the raw table if you have other raw rules. The import of large lists takes a few seconds. /ip firewall address-list print count-only where list=IPv64-firehole_l1 shows the number of entries. For the live state of the v64 Blocklist use the URL ("https://ipv64.net/blocklists/live/<token>/v64_mikrotik_" . $v . "_v64.rsc"), the list name IPv64-v64 and interval=30m.
For a web server or reverse proxy without firewall access. The geo module checks networks efficiently, even with tens of thousands of entries. Blocked clients get HTTP 403.
1. Fetch the list as a geo file (cron, e.g. every 4 hours):
curl -fsS https://ipv64.net/blocklists/ipv64_blocklist_blocklistde_all.txt \
| awk '/^[0-9A-Fa-f:.]+(\/[0-9]+)?$/ {print $1" 1;"}' > /etc/nginx/ipv64-geo.conf.new \
&& [ -s /etc/nginx/ipv64-geo.conf.new ] && mv /etc/nginx/ipv64-geo.conf.new /etc/nginx/ipv64-geo.conf \
&& nginx -t -q && systemctl reload nginx 2. Use it in nginx.conf:
http {
geo $ipv64_blocked { default 0; include /etc/nginx/ipv64-geo.conf; }
server {
# ...
if ($ipv64_blocked) { return 403; }
}
} Behind Cloudflare or another proxy, configure real_ip_header first, otherwise nginx sees the proxy address.
Import the list as decisions; all your bouncers (firewall, nginx, Traefik …) apply it. The decisions expire after 6 hours, so import again every 4 hours via cron:
curl -fsSo /tmp/ipv64.txt https://ipv64.net/blocklists/ipv64_blocklist_firehole_l1.txt \
&& cscli decisions import -i /tmp/ipv64.txt --format values --duration 6h --reason ipv64-blocklist The Node64 container uses the IPv64 blocklists in its reverse proxy CDN64 with one click: CDN64 › Access › Blocklists. It refreshes them every 30 minutes and lets you define exceptions. With your list token stored there, it loads the v64 lists live.
ipv64.net combines and cleans public lists: it converts everything to networks, removes duplicates, contained networks and reserved ranges. The entries themselves come from these projects:
If one of your addresses is listed by mistake, ask the source project to remove it; the change reaches the IPv64 lists with the next update. For the v64 lists, request the removal in the IP lookup. The lists are free to use; please respect the terms of the source projects and do not use them as the only protection.