Overview
Block malicious IPs at the Linux kernel level using ipset and iptables. Packets from known attackers are dropped before reaching any application — whether web server, mail server, database, or game server. A cron job pulls the latest threat data from the Blacklist API, bulk-loads it into an ipset, and atomically swaps it in with zero downtime.
Want this automated? SikkerGuard does everything on this page automatically — blocklist pull, ipset management, atomic swap, persistence, cron scheduling, auto-whitelisting, and attack reporting back to SikkerAPI. One Docker command, zero scripts.
Install SikkerGuard → Data flow
Cron triggers→Fetches blacklist→Splits IPv4/IPv6→ipset restore→Atomic swap→Kernel DROP
Installation
Download the update script, save your API key, and run it once to create the ipsets. The script handles fetching, IPv4/IPv6 splitting, bulk-loading via ipset restore, and atomic swap.
1Download the update script
$ sudo curl -o /usr/local/bin/sikkerapi-ipset-update \
"https://sikkerapi.com/iptables/sikkerapi-ipset-update.sh"
$ sudo chmod +x /usr/local/bin/sikkerapi-ipset-update
2Save your API key
$ echo "sk_free_..." | sudo tee /etc/sikkerapi.key
$ sudo chmod 600 /etc/sikkerapi.key
3Run initial update
$ sudo sikkerapi-ipset-update
SikkerAPI: blocklist updated (4832 IPv4, 167 IPv6)
iptables Rules
Add iptables and ip6tables rules that reference the ipsets. These only need to be added once — the update script refreshes the sets behind them atomically. The rules reference sets by name, so the swap is transparent.
Add DROP rules
# Block IPv4 attackers
$ sudo iptables -I INPUT -m set --match-set sikker4 src -j DROP
# Block IPv6 attackers
$ sudo ip6tables -I INPUT -m set --match-set sikker6 src -j DROP
Save rules for persistence
# Debian / Ubuntu
$ sudo netfilter-persistent save
# RHEL / CentOS / Rocky
$ sudo service iptables save
Atomic Swap
The naive approach — flushing a live ipset and re-adding IPs one by one — leaves a window where your server is unprotected. The script uses a swap-based strategy instead: create a temporary set, bulk-load all IPs into it, then atomically swap it with the live set in a single kernel operation. Zero downtime, no gap in protection.
What the script does internally
# 1. Create temp set and bulk-load via restore
ipset restore <<EOF
create sikker4_tmp hash:ip family inet hashsize 4096 maxelem 131072 -exist
flush sikker4_tmp
add sikker4_tmp 203.0.113.42
add sikker4_tmp 198.51.100.17
... (thousands more, single syscall)
EOF
# 2. Atomic swap — instant, no gap
ipset swap sikker4_tmp sikker4
# 3. Clean up temp set
ipset destroy sikker4_tmp
IPv6 Support
The blacklist returns both IPv4 and IPv6 addresses. The script automatically splits them into separate sets: sikker4 (IPv4, hash:ip family inet) and sikker6 (IPv6, hash:ip family inet6). Each needs its own iptables/ip6tables rule.
Disable IPv6 set (optional)
# Skip IPv6 set creation entirely
$ SIKKERAPI_IPV6=false sudo sikkerapi-ipset-update
# Or only fetch IPv4 from the API (saves quota)
$ SIKKERAPI_EXTRA="&ipVersion=4" sudo sikkerapi-ipset-update
Cron Schedule
Schedule the update script to run automatically. The script detects when the list hasn’t changed and skips the swap, so frequent runs are safe (but still cost quota). The blacklist is sorted by confidence score (highest first), then recency.
/etc/cron.d/sikkerapi
# Update SikkerAPI blocklist daily at 3 AM
0 3 * * * root /usr/local/bin/sikkerapi-ipset-update >> /var/log/sikkerapi-ipset.log 2>&1
Filtering Options
Control which IPs are included using environment variables. All Blacklist API filters are available via SIKKERAPI_EXTRA.
Script environment variables
SIKKERAPI_KEY/etc/sikkerapi.keyYour SikkerAPI key (sk_...). Falls back to key file.
SIKKERAPI_SCORE70Minimum confidence score (1–100).
SIKKERAPI_LIMIT5000Maximum IPs to fetch.
SIKKERAPI_SET_NAMEsikkeripset name prefix (creates {name}4 and {name}6).
SIKKERAPI_EXTRA—Extra API parameters (e.g. &protocols=ssh).
SIKKERAPI_IPV6trueEnable IPv6 set creation (true/false).
Filter examples
# Only SSH attackers, score 80+
$ SIKKERAPI_SCORE=80 SIKKERAPI_EXTRA="&protocols=ssh" \
sudo sikkerapi-ipset-update
# Only block IPs from specific countries
$ SIKKERAPI_EXTRA="&onlyCountries=CN,RU" \
sudo sikkerapi-ipset-update
# Exclude your own country
$ SIKKERAPI_EXTRA="&exceptCountries=US,CA" \
sudo sikkerapi-ipset-update
# High severity only
$ SIKKERAPI_EXTRA="&minSeverity=high" \
sudo sikkerapi-ipset-update
Confidence score guidance
90+Very high confidence. Safe for hard-blocking in most environments.
70–89High confidence. Good default. Review logs periodically.
50–69Moderate confidence. Consider logging instead of dropping.
Persistence Across Reboots
ipsets live in kernel memory and are lost on reboot. The script automatically saves sets to disk after each update. To restore at boot, install the appropriate persistence package for your distro. Important: ipsets must be restored before iptables rules, otherwise iptables will fail because the referenced sets don’t exist yet.
Debian / Ubuntu
# Install ipset-persistent (auto-restores before iptables at boot)
$ sudo apt install ipset-persistent
# Save current sets
$ sudo ipset save > /etc/ipset.d/sikkerapi.conf
RHEL / CentOS / Rocky — systemd unit
# Save sets
$ sudo ipset save > /etc/ipset.conf
# Create /etc/systemd/system/ipset-restore.service
[Unit]
Description=Restore ipset rules
Before=iptables.service
[Service]
Type=oneshot
ExecStart=/usr/sbin/ipset restore -f /etc/ipset.conf
[Install]
WantedBy=multi-user.target
$ sudo systemctl enable ipset-restore
Rate Limits
The blacklist endpoint has its own daily quota, separate from lookup quotas. One daily pull fits all tiers. Check response headers to monitor usage.
Daily quotas by tier
Free10,000 blocklist IPs/day. Create free key Paid tiersHigher limits. See pricing for details. Check remaining quota
$ curl -sI \
-H "Authorization: Bearer sk_..." \
"https://api.sikkerapi.com/v1/key/blacklist?plaintext=true&limit=1" \
| grep -i x-blacklist
X-Blacklist-Limit: 10000
X-Blacklist-Used: 5000
X-Blacklist-Remaining: 5000
Verification
After running the script and adding iptables rules, verify that the sets are populated and packets are being dropped.
1Check ipset contents
$ sudo ipset list sikker4 -t
Name: sikker4
Type: hash:ip
Header: family inet hashsize 4096 maxelem 131072
Size in memory: 198432
Number of entries: 4832
2Verify iptables rules
$ sudo iptables -L INPUT -n --line-numbers | head -5
Chain INPUT (policy ACCEPT)
num target prot source destination
1 DROP all 0.0.0.0/0 0.0.0.0/0 match-set sikker4 src
3Test a specific IP
$ sudo ipset test sikker4 203.0.113.42
203.0.113.42 is in set sikker4.
4View drop statistics
$ sudo iptables -L INPUT -v -n | grep sikker
1234 56K DROP all -- * * 0.0.0.0/0 0.0.0.0/0 match-set sikker4 src
Troubleshooting
Common issues and how to resolve them. Run the update script manually first to isolate API vs. system issues.
Common issues
Empty ipset (0 entries)verify key starts with sk_ and is enabled ipset: command not foundapt install ipset or yum install ipset
Permission deniedscript must run as root (ipset/iptables need kernel access)
Sets lost after rebootinstall ipset-persistent or create a systemd unit iptables rule not matchingverify set name: sikker4 for IPv4, sikker6 for IPv6
429 — Quota exceededupgrade tier or reduce refresh frequency Script Reference
The update script at /usr/local/bin/sikkerapi-ipset-update handles the full pipeline: fetch the plaintext blacklist, split IPv4/IPv6, bulk-load via ipset restore, atomic swap, and persistence. Handles 429 (quota exceeded) gracefully by keeping existing sets. All configuration via environment variables.
/usr/local/bin/sikkerapi-ipset-update (excerpt)
#!/usr/bin/env bash
# SikkerAPI ipset/iptables Blocklist Updater
set -euo pipefail
# Fetch blacklist in plaintext
curl -sf -H "Authorization: Bearer $API_KEY" \
"$API_URL?plaintext=true&scoreMinimum=$SCORE&limit=$LIMIT"
# Split IPv4 and IPv6
grep -v ':' $BLOCKLIST > $V4_LIST
grep ':' $BLOCKLIST > $V6_LIST
# Bulk-load into temp set (single syscall)
ipset restore < $RESTORE_CMD
# Atomic swap (zero downtime)
ipset swap sikker4_tmp sikker4
ipset destroy sikker4_tmp
# Auto-persist to /etc/ipset.d/ or /etc/ipset.conf
Get started — Kernel-level IP blocking in under 10 minutes, or skip the manual setup entirely with
SikkerGuard — one Docker command handles blocklist management, ipset updates, persistence, and
attack reporting automatically. The blocklist is powered by first-party honeypot data across 16 protocols with
confidence scoring. For application-level blocking, see
Nginx. For two-way integrations with reporting, see
Fail2Ban or
CSF.
Create free API key →