Чёрный список (BLACKLIST)
GET https://api.abuseipdb.ru/api/v2/blacklist — выгрузка наиболее «злоупотребляющих» адресов: JSON или простой список IP по одному в строке. Это витрина базы жалоб, которую удобно импортировать в firewall.
Раздел «API v2»: Обзор · Проверка IP (CHECK) · Жалобы по IP (REPORTS) · Отправить жалобу (REPORT) · Чёрный список (BLACKLIST) · Проверка подсети (CHECK-BLOCK) · Массовые жалобы (BULK-REPORT) · Удаление жалоб (CLEAR-ADDRESS) · Лимиты · Ошибки · Fail2Ban, CSF, Suricata · FAQ
Запрос
curl -G https://api.abuseipdb.ru/api/v2/blacklist \
-d confidenceMinimum=90 \
-H "Key: YOUR_OWN_API_KEY" \
-H "Accept: application/json"
Параметры
| Параметр | Обязателен | По умолчанию | Допустимо | Описание |
|---|---|---|---|---|
confidenceMinimum | нет | 100 | 25…100 | нижняя граница оценки адреса; вне диапазона — 422 |
limit | нет | 10000 | 1…500000 | сколько адресов вернуть; больше потолка вашего тарифа — молча усекается; больше 500000 — 422 |
plaintext | нет | выключен | флаг | вернуть text/plain, по одному IP в строке |
onlyCountries | нет | — | ISO 3166 alpha-2 через запятую | только адреса указанных стран (US,MX,CA) |
exceptCountries | нет | — | ISO 3166 alpha-2 через запятую | все страны, кроме указанных |
ipVersion | нет | 4 и 6 вместе | 4 или 6 | только IPv4 или только IPv6 |
onlyCountries и exceptCountries взаимоисключающие: если передать оба, фильтр по странам не применяется, а ответ вернёт данные без countryCode. Регистр кодов не важен.
JSON-ответ
{
"meta": {
"generatedAt": "2026-11-07T02:00:00+00:00"
},
"data": [
{
"ipAddress": "5.188.10.179",
"abuseConfidenceScore": 100,
"lastReportedAt": "2026-11-07T01:17:02+00:00"
},
{
"ipAddress": "185.222.209.14",
"abuseConfidenceScore": 100,
"lastReportedAt": "2026-11-07T01:17:02+00:00"
}
]
}
| Поле | Что означает |
|---|---|
meta.generatedAt | момент формирования списка, ISO 8601 UTC |
data[].ipAddress | адрес |
data[].abuseConfidenceScore | оценка адреса 25…100 |
data[].lastReportedAt | время последней жалобы |
data[].countryCode | код страны; приходит только когда задан один из фильтров onlyCountries/exceptCountries/ipVersion |
Сортировка: по abuseConfidenceScore по убыванию, затем по lastReportedAt по убыванию (сначала самые свежие).
Plaintext-ответ
Два равнозначных способа получить список IP построчно:
# 1. флаг plaintext
curl -G https://api.abuseipdb.ru/api/v2/blacklist \
-d confidenceMinimum=90 \
-d plaintext \
-H "Key: YOUR_OWN_API_KEY" \
-H "Accept: application/json"
# 2. заголовок Accept
curl -G https://api.abuseipdb.ru/api/v2/blacklist \
-d confidenceMinimum=90 \
-H "Key: YOUR_OWN_API_KEY" \
-H "Accept: text/plain"
Ответ:
5.188.10.179
185.222.209.14
95.70.0.46
191.96.249.183
115.238.245.8
122.226.181.164
122.226.181.167
В обоих режимах отметка свежести списка всегда приходит в заголовке ответа X-Generated-At (ISO 8601 UTC). Проверяйте её перед импортом: если список не обновлялся дольше суток, правила firewall устарели.
Жёсткие лимиты по тарифу
Размер выгрузки ограничен тарифом ключа. limit больше потолка тарифа не вызывает ошибку — список просто усекается до потолка (это позволяет не падать при смене тарифа). А вот limit больше 500000 — это уже ошибка 422: большее значение не поддерживает ни один тариф.
| Тариф | Потолок limit | Что видит клиент |
|---|---|---|
| free | 10 000 | limit=500000 вернёт не больше 10 000 адресов |
| premium | 100 000 | limit=500000 вернёт не больше 100 000 адресов |
| admin | 500 000 | полный потолок |
Если нужен максимально большой список, который позволяет ваш тариф, передавайте limit=500000: сервер сам усечёт его до потолка вашего тарифа.
Список строится по жалобам за последние 365 дней — параметра maxAgeInDays у blacklist нет (как и у abuseipdb.com).
Почему в списке нет «слабых» адресов
- Жёсткий минимум
abuseConfidenceScore— 25%. Адреса с оценкой ниже в список не попадают никогда, даже приconfidenceMinimum=25. - Причина первая: одна-две жалобы легко «топят» целую сеть, и чёрный список на их основе опасен. Поэтому мы рекомендуем 75–100% для блокировки, особенно для защиты от DoS.
- Причина вторая: диапазон ниже 25% — это почти вся база, выгрузка была бы бесполезно огромной.
Импорт в firewall: предупреждения
Список устаревает. Значения оценок со временем снижаются: адреса «выздоравливают» и выпадают из списка. Если вы импортируете IP в
iptables/nftables, список нужно регулярно обновлять (cron каждые 5–60 минут) или полностью сбрасывать устаревшие правила. AbuseIPDB.RU не отвечает за потерянные соединения с «легитимных» адресов, попавших в список.
- Перед блокировкой соберите статистику: сколько адресов вернулось, кто они, какие страны.
- Не блокируйте больше 10 000 адресов одним списком без теста. Firewall-утилиты вроде CSF могут не справиться с импортом десятков тысяч правил; используйте
ipset/nftables-сеты и проверяйте нагрузку на своём железе. - Импортируйте атомарно: скачайте во временный файл, проверьте
X-Generated-Atи количество строк, затем замените рабочий набор. - Для защиты от DoS берите
confidenceMinimum75–100; для наблюдаемости — 25–50.
Рекомендуемая схема обновления
#!/usr/bin/env bash
# /usr/local/bin/update-abuseipdb-blacklist.sh
set -euo pipefail
KEY="${ABUSEIPDB_KEY:?ABUSEIPDB_KEY is not set}"
OUT=/var/lib/abuseipdb/blacklist.txt
TMP="$(mktemp)"
curl -sS -G https://api.abuseipdb.ru/api/v2/blacklist \
-d confidenceMinimum=75 \
-d limit=500000 \
-d plaintext \
-H "Key: ${KEY}" \
-H "Accept: text/plain" \
-o "$TMP"
# 1) отсекаем пустой/битый ответ
wc -l "$TMP" | grep -qE '^[0-9]+ ' || { rm -f "$TMP"; exit 1; }
test -s "$TMP" || { rm -f "$TMP"; exit 1; }
# 2) заменяем атомарно
install -m 0644 "$TMP" "$OUT"
rm -f "$TMP"
# 3) применяем к ipset (пример)
ipset flush abuseipdb || ipset create abuseipdb hash:ip maxelem 500000
grep -vE '^\s*$' "$OUT" | xargs -r -n 500 ipset add abuseipdb
Добавьте в cron:
*/15 * * * * /usr/local/bin/update-abuseipdb-blacklist.sh >> /var/log/abuseipdb-blacklist.log 2>&1
Примеры
Python — сохранить plaintext в файл и посчитать количество:
import requests
API_KEY = "YOUR_OWN_API_KEY"
url = "https://api.abuseipdb.ru/api/v2/blacklist"
response = requests.get(
url,
params={"confidenceMinimum": 75, "limit": 500000, "plaintext": 1},
headers={"Key": API_KEY, "Accept": "text/plain"},
timeout=120,
)
response.raise_for_status()
generated_at = response.headers.get("X-Generated-At", "unknown")
ips = [line.strip() for line in response.text.splitlines() if line.strip()]
print(f"сформирован: {generated_at}, адресов: {len(ips)}")
with open("/var/lib/abuseipdb/blacklist.txt", "w", encoding="utf-8") as handle:
handle.write("\n".join(ips) + "\n")
PHP — JSON-режим:
<?php
$query = http_build_query(['confidenceMinimum' => 90, 'limit' => 100000]);
$ch = curl_init('https://api.abuseipdb.ru/api/v2/blacklist?' . $query);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Key: ' . getenv('ABUSEIPDB_KEY'), 'Accept: application/json'],
CURLOPT_TIMEOUT => 120,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($status !== 200) {
throw new RuntimeException("API v2 HTTP $status: $body");
}
$payload = json_decode($body, true);
$generatedAt = $payload['meta']['generatedAt'] ?? null;
printf("список от %s, адресов: %d\n", $generatedAt, count($payload['data']));
Ошибки BLACKLIST
| Код | Причина | source.parameter |
|---|---|---|
401 | ключ отсутствует/неверен/отозван | — |
422 | confidenceMinimum вне 25…100 | confidenceMinimum |
422 | limit не целое или меньше 1 | limit |
422 | ipVersion не 4 и не 6 | ipVersion |
422 | код страны не ISO 3166 alpha-2 | onlyCountries / exceptCountries |
429 | дневной лимит | — |
Замечания по совместимости: на abuseipdb.com confidenceMinimum, onlyCountries и exceptCountries — платные фильтры, у нас они работают на любом тарифе (расширение AbuseIPDB.RU). Дневной лимит считается общим счётчиком на ключ, а не отдельным для blacklist — см. Лимиты.
Версия 2.2.0 · AbuseIPDB.RU · webmaster@abuseipdb.ru · source: docs/ABUSE-API-blacklist.md