iptables / nftables
Block blacklisted IPs at the kernel firewall level using iptables with ipset or nftables sets for maximum performance.
5 min setup
Kernel-level
O(1) lookup
Overview
For raw iptables or nftables users (no CSF or UFW), you can use ipset (iptables) or nftables sets to efficiently block thousands of IPs with O(1) hash-based lookups. This is the fastest method for blocking blacklisted IPs.
Method 1: iptables + ipset
Install ipset if not already present:
sudo apt install -y ipset # Debian/Ubuntu
sudo dnf install -y ipset # CentOS/RHEL
Create the blocking script:
/usr/local/bin/ipwhois-iptables.sh
#!/bin/bash
# Block IPWhois Blacklist IPs via ipset + iptables
# Cron: 0 */6 * * *
SET="ipwhois_bl"
TMPSET="${SET}_tmp"
API="https://bl.ipwhois.net/api/browse?format=plaintext&min_confidence=80"
# Create temporary set with new IPs
ipset create "$TMPSET" hash:ip hashsize 4096 maxelem 65536 2>/dev/null || ipset flush "$TMPSET"
# Populate the temporary set
curl -s "$API" | while read -r ip; do
[ -n "$ip" ] && ipset add "$TMPSET" "$ip" 2>/dev/null
done
# Swap the sets atomically (no gap in protection)
ipset create "$SET" hash:ip hashsize 4096 maxelem 65536 2>/dev/null
ipset swap "$TMPSET" "$SET"
ipset destroy "$TMPSET"
# Ensure iptables rule exists
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 "$(date) - ipset $SET updated with $(ipset list $SET | grep -c '^[0-9]') IPs" | \
logger -t ipwhois-bl
sudo chmod +x /usr/local/bin/ipwhois-iptables.sh
echo "0 */6 * * * root /usr/local/bin/ipwhois-iptables.sh" | sudo tee /etc/cron.d/ipwhois-iptables
Method 2: nftables Sets
For modern systems using nftables (Debian 12+, Ubuntu 24.04+):
/usr/local/bin/ipwhois-nftables.sh
#!/bin/bash
# Block IPWhois Blacklist IPs via nftables
# Cron: 0 */6 * * *
TABLE="ipwhois"
SET="blacklist"
API="https://bl.ipwhois.net/api/browse?format=plaintext&min_confidence=80"
# Create table and set if they don't exist
nft add table inet "$TABLE" 2>/dev/null
nft add set inet "$TABLE" "$SET" '{ type ipv4_addr; flags timeout; }' 2>/dev/null
nft add chain inet "$TABLE" input '{ type filter hook input priority -10; policy accept; }' 2>/dev/null
nft add rule inet "$TABLE" input ip saddr @"$SET" drop 2>/dev/null
# Flush and reload the set
nft flush set inet "$TABLE" "$SET"
ELEMENTS=""
while read -r ip; do
[ -n "$ip" ] && ELEMENTS="$ELEMENTS $ip timeout 24h,"
done < <(curl -s "$API")
if [ -n "$ELEMENTS" ]; then
nft add element inet "$TABLE" "$SET" "{ $ELEMENTS }"
fi
echo "$(date) - nftables set updated" | logger -t ipwhois-bl
Testing
# Run manually
sudo /usr/local/bin/ipwhois-iptables.sh
# Verify the ipset
sudo ipset list ipwhois_bl | head -20
# Verify the iptables rule
sudo iptables -L INPUT -n | head -5
# For nftables
sudo nft list set inet ipwhois blacklist
Troubleshooting
- ipset not found: Install with
apt install ipsetordnf install ipset. - Set full: Increase
maxelemin theipset createcommand. - Rules lost on reboot: Use
iptables-persistent(Debian/Ubuntu) or save withipset save > /etc/ipset.confand restore via systemd service. - nftables conflict with iptables: Do not mix iptables and nftables on the same system. Choose one method.
IPWhois Blacklist — Community-driven IP threat intelligence — ipwhois.net