The ReportedIP blacklist is a community-driven list of malicious IP addresses, generated automatically
from real-world attack reports and available via API and GitHub. Use it to block known malicious IPs
in your firewall, web server, or application — it refreshes daily without manual review.
How the blacklist is generated
Every IP in the blacklist comes from community reports that hit our reputation engine. An IP is
included only when:
Its confidence score is ≥ 75 % (computed from report frequency,
source diversity, severity, and recency)
Its most recent report is at least 48 hours old (false-positive cool-down — entries only enter the export once the score has had time to recalibrate)
It is not on the whitelist (search engines, CDN providers, known-good
infrastructure are excluded)
The blacklist refreshes automatically — there is no manual editorial review. The whole pipeline
is open and transparent: you can verify any entry via
GET /reportedip/v2/check?ip=<ip>&verbose=true
to see the exact score breakdown.
GitHub Repository
The full blacklist is published as a public GitHub repository, pushed daily from the live API data.
The exported data itself is delayed by 48 hours (the false-positive cool-down described above).
You can clone it, use it in CI/CD pipelines, or integrate it into your infrastructure.
reportedip-blacklist/
├── blacklist-all.txt # All IPs, one per line
├── blacklist-all.json # All IPs with metadata
├── blacklist-all.csv # All IPs, CSV format
├── metadata.json # Export metadata (version, counts, timestamps)
├── lists/ # Thematic sub-lists
│ ├── spam.txt
│ ├── brute-force.txt
│ ├── cms-login.txt
│ ├── web-attacks.txt
│ ├── malware.txt
│ ├── ddos.txt
│ ├── fraud.txt
│ ├── infrastructure.txt
│ └── apt.txt
└── formats/ # Ready-to-include firewall snippets
├── nginx-deny.conf
├── apache-htaccess.txt
└── iptables.sh
File Formats
TXT Format
Plain text, one IP address per line. Lines starting with # are comments
containing metadata such as generation time and total count.
text
# ReportedIP Blacklist - All IPs
# https://reportedip.com
#
# Copyright (c) 2026 ReportedIP / Patrick Schlesinger
# Licensed under CC BY 4.0 - https://creativecommons.org/licenses/by/4.0/
#
# IMPORTANT: Data is delayed by 48 hours.
# For real-time threat intelligence via API, contact: 1@reportedip.com
#
# Generated: 2026-07-22
# Total IPs: 12847
#
1.2.3.4
5.6.7.8
9.10.11.12
JSON Format
A meta block (export version, counts, generation timestamp) followed by an
entries array. categories are numeric threat-category IDs — resolve
them against the threat-category catalogue
or GET /categories.
Comma-separated values with a header row. Easy to import into spreadsheets, databases, or SIEM tools.
categories holds semicolon-separated numeric category IDs.
Use the blacklist files to block malicious IPs at the firewall or web server level.
Below are integration examples for common tools.
Blocking at the network layer? The snippets here are starting points for a single
machine. For the production setup — one block set per service, hourly conditional sync,
atomic swap, IPv6, and cloud edge firewalls — follow
Network-Level Blocking.
Nginx
Generate a blocklist config and include it in your Nginx server block:
# /etc/nginx/sites-enabled/default
server {
include /etc/nginx/blocklist.conf;
# ... rest of your config
}
Apache (.htaccess)
apache
# .htaccess — Block reported IPs
<RequireAll>
Require all granted
Require not ip 1.2.3.4
Require not ip 5.6.7.8
Require not ip 9.10.11.12
</RequireAll>
iptables (via ipset)
Load the list into an ipset and match that set from a single rule. One rule per IP would mean
thousands of rules traversed for every packet; a set lookup stays constant no matter how large the
list gets.
bash
# Create the set and fill it in one pass (IPv4 entries only)
ipset create rip-block hash:ip family inet maxelem 65536 -exist
grep -E '^[0-9]+(\.[0-9]+){3}$' blacklist-all.txt \
| sed 's|^|add rip-block |' | ipset restore -exist
# One rule blocks the whole set
iptables -I INPUT -m set --match-set rip-block src -j DROP
IPv6 needs its own set (family inet6) and its own ip6tables rule —
see Network-Level Blocking for the full
script including nftables, per-service sets, and the hourly sync.
fail2ban
Create a custom jail that bans IPs from the ReportedIP blacklist:
fail2ban also works in the other direction: a ready-made action reports every ban on your server
to the community via POST /report. See the
fail2ban integration guide for the
action config and the jail-to-category mapping.
API Access
The /blacklist endpoint provides real-time access to the full blacklist with
filtering options. An API key with the threat-feed feature (Contributor tier and up) is required.
The endpoint is feature-gated and does not count against your daily check or
report quota — poll it as often as your caching strategy needs. See
Authentication & Rate Limits
for tiers and keys.
Parameter
Type
Description
format
string
Response format: json (default), txt, csv
source
string
Blacklist source: dynamic (default) — the community-driven, automatically scored blacklist. Other values are reserved for internal use
One or more threat category IDs, comma-separated (e.g. 22,18 for SSH plus generic brute-force). Full catalogue on the Threat Categories page or via GET /categories
limit
integer
Maximum number of IPs to return. Default: 10000 — keep the default; smaller values truncate the list
See the API Reference for full endpoint documentation,
response format, and additional parameters.
Service-specific blacklists
Combine the category filter with confidence=90 to build one block list per
exposed service. Each list only contains IPs that were reported for the matching attack type, so you
can apply it port-scoped — an IP on the web list never locks anyone out of SSH.
Web App Attack, SQL Injection, Web Spam, Bad Web Bot, Blog Spam, plus the dedicated WordPress block (31–58): login/XML-RPC/REST brute force, plugin, theme and core exploits, comment and registration spam, backdoors, scanning. Full value on the Network-Level Blocking page
# SSH attackers only, plain text for ipset/nftables
curl -H "X-Key: YOUR_API_KEY" \
"https://reportedip.com/wp-json/reportedip/v2/blacklist?confidence=90&format=txt&limit=50000&category=22,18"
Lists are regenerated server-side every 15 minutes. Hourly polling per list is plenty; send the
stored ETag back as If-None-Match and unchanged lists answer with
304 Not Modified. Tags are specific to the exact variant you request, so keep one stored
tag per list. Valid category IDs run from 1 to 58 — IDs 31–58 are the dedicated WordPress
block that the web list above includes. Full catalogue:
Threat Categories.
Auto-Update Script
Set up a cron job to automatically download the latest blacklist and update your firewall rules.
#!/bin/bash
# /usr/local/bin/update-reportedip-blocklist.sh
# Downloads the latest ReportedIP blacklist and updates Nginx blocklist
API_KEY="your-api-key-here"
API_URL="https://reportedip.com/wp-json/reportedip/v2/blacklist"
BLOCKLIST="/etc/nginx/blocklist.conf"
TMPFILE=$(mktemp)
# Download latest blacklist in TXT format
curl -sf -H "X-Key: $API_KEY" \
"$API_URL?format=txt&confidence=90&limit=50000" \
-o "$TMPFILE"
DOWNLOAD_OK=$?
COUNT=$(grep -cE '^[0-9a-fA-F.:]+$' "$TMPFILE")
# Never replace a working blocklist with a truncated or empty response
if [ "$DOWNLOAD_OK" -eq 0 ] && [ "$COUNT" -ge 1000 ]; then
# Convert to Nginx deny directives
grep -v "^#" "$TMPFILE" | grep -v "^$" | \
awk '{print "deny " $1 ";"}' > "$BLOCKLIST"
# Reload Nginx
nginx -t && systemctl reload nginx
echo "$(date): Blocklist updated with $(wc -l < "$BLOCKLIST") entries"
else
echo "$(date): Download failed or list too small ($COUNT) - keeping current blocklist" >&2
fi
rm -f "$TMPFILE"
Real-time vs. GitHub
Important: The GitHub repository is pushed daily, but the exported data carries a
48-hour false-positive cool-down. For real-time blocking with the most current data, use the API
directly — it reflects changes immediately as new reports come in, while the GitHub files lag
behind by up to two days. Mail servers can also consume the blacklist as a
DNSBL / RBL zone without downloading files at all.