Мониторинг черных списков: скрипты, API и уведомления по вебхукам
Мониторинг черных списков — это регулярная проверка ваших IP-адресов и доменов отправки по нескольким черным спискам DNS (DNSBL) по расписанию с уведомлением только при изменении результата. Если заметить запись в момент ее появления, а не тогда, когда клиенты начнут жаловаться на вернувшиеся письма, у вас будет время найти причину и запросить удаление, пока ущерб не разросся.
На практике это можно сделать двумя способами: запустить собственный небольшой скрипт на dig и cron или передать проверки сервису через API и вебхуки. В обоих случаях от двух деталей зависит, будет ли мониторинг показывать правду: запросы через публичные резолверы такие списки, как Spamhaus, отклоняют, и ответы на них вводят в заблуждение, а коды ошибок ни в коем случае нельзя считать записями в списке.
Приведенные здесь правила операторов списков основаны на их официальных страницах по состоянию на ноябрь 2026 года. Правила меняются, поэтому, прежде чем полагаться на настройку, уточните их. Общие сведения о работе DNSBL см. в материале что такое DNSBL (RBL).
Что отслеживать и какие списки опрашивать
Начните с перечня объектов, которые действительно нужно отслеживать.
- IP-адреса отправки. Это адреса, с которых на самом деле отправляет почту ваш сервер или почтовый провайдер. Сайт и почта часто работают на разных машинах, поэтому проверьте адрес в заголовках Received отправленного вами письма. Если вы отправляете почту по IPv6, отслеживайте и эти адреса.
- Домены. Домен в адресе From и все домены, встречающиеся в ссылках внутри ваших писем. Домены проверяются по доменным черным спискам, которые отделены от списков по IP.
Формат запроса определен в RFC 5782. Для IPv4 октеты переворачиваются и добавляется зона списка, так что 192.0.2.99 превращается в 99.2.0.192 с последующим именем зоны. Для IPv6 адрес записывается как 32 шестнадцатеричных полубайта (nibble) в обратном порядке. Домен просто ставится перед зоной. Для записи в списке возвращается запись A, по соглашению из диапазона 127.0.0.0/8; для отсутствующего адреса — NXDOMAIN. RFC также отмечает, что списки должны публиковать запись TXT с объяснением причины внесения.
Отслеживайте несколько списков, а не один, потому что разные получатели используют разные списки. Значение каждого кода ответа зависит от оператора; распространенные коды разобраны в нашем руководстве по кодам ответа DNSBL.
Почему публичные резолверы дают неверные ответы
Частая ошибка самодельного мониторинга — отправка запросов через публичный резолвер, например Google Public DNS (8.8.8.8) или Cloudflare (1.1.1.1). В официальном FAQ Spamhaus по использованию DNSBL объясняется, что при этом происходит:
- Бесплатное использование DNSBL Spamhaus допускается при условии, что оно некоммерческое и что запросы не идут через публичный или открытый резолвер либо с IP с типовой обратной DNS-записью.
- Через бесплатные открытые резолверы, такие как Google Public DNS, на запросы в большинстве случаев приходит ответ «не в списке» (NXDOMAIN). Иными словами, IP из списка может выглядеть чистым.
- На запросы через публичный резолвер может также приходить 127.255.255.254. Это код ошибки, а не запись в списке. Аналогично 127.255.255.252 означает опечатку в имени DNSBL, а 127.255.255.255 — чрезмерное число запросов. Spamhaus указывает, что эти коды нельзя понимать как признак того, что запрошенный объект внесен в список.
- Резолверы, подменяющие ответы NXDOMAIN, возвращают вместо них IP-адрес, поэтому правильного NXDOMAIN вы никогда не увидите.
Главная рекомендация FAQ — использовать собственный DNS-резолвер. Тем, кому приходится оставаться на публичном резолвере, Spamhaus предлагает свой Data Query Service (DQS); что в нем бесплатно, уточняйте в его условиях. Чтобы узнать, какой резолвер вы на самом деле используете, FAQ предлагает команду dig txt whoami.fastly.net.
RFC 5782 добавляет встроенную проверку работоспособности: список IPv4 должен содержать запись для 127.0.0.2 и не должен содержать 127.0.0.1, а клиентам следует периодически проверять эти тестовые записи, чтобы убедиться, что список работает. В примере Spamhaus 2.0.0.127.zen.spamhaus.org возвращает 127.0.0.10, 127.0.0.4 и 127.0.0.2, а 1.0.0.127.zen.spamhaus.org — NXDOMAIN. Мониторинг должен сначала проверять это и отбрасывать прогон, если проверка не прошла.
Вариант 1: скрипт на dig и cron
Ниже минимальный скрипт, который проверяет один адрес IPv4 по Spamhaus ZEN и SpamCop (bl.spamcop.net; согласно документации SpamCop, для IP из списка он отвечает 127.0.0.2). Подставьте свой адрес и зоны.
#!/bin/sh
# Запрашивайте собственный рекурсивный резолвер (например, unbound на том же хосте), но не публичный
RESOLVER=127.0.0.1
IP=192.0.2.10
ZONES="zen.spamhaus.org bl.spamcop.net"
REV=$(echo "$IP" | awk -F. '{print $4"."$3"."$2"."$1}')
q() {
out=$(dig +time=3 +tries=1 @"$RESOLVER" "$1" A) || { echo ERR; return; }
case "$out" in
*"status: NOERROR"*) a=$(printf '%s\n' "$out" | awk '$4=="A"{print $5}'); echo "${a:-NX}" ;;
*"status: NXDOMAIN"*) echo NX ;;
*) echo ERR ;;
esac
}
for Z in $ZONES; do
# Если тестовая запись 127.0.0.2 не возвращает код внесения, этому прогону доверять нельзя
case "$(q "2.0.0.127.$Z")" in
127.255.255.*|NX|ERR) echo "$Z ERROR test-entry"; continue ;;
127.*) ;;
*) echo "$Z ERROR test-entry"; continue ;;
esac
A=$(q "$REV.$Z")
case "$A" in
NX) echo "$Z CLEAN" ;;
ERR) echo "$Z ERROR no-answer" ;;
127.255.255.*) echo "$Z ERROR $A" ;;
127.*) echo "$Z LISTED $A" ;;
*) echo "$Z ERROR unexpected $A" ;;
esac
doneЧто делает скрипт:
- Чистым считается только статус NXDOMAIN, 127.255.255.x — ошибка, а любой другой 127.x — запись в списке. Все, что вне 127.0.0.0/8, считается аномалией, например признаком подменяющего ответы резолвера.
- При тайм-ауте dig завершается с ненулевым кодом, а при SERVFAIL и REFUSED — с кодом 0. Ни один из этих случаев не считается чистым; скрипт фиксирует ошибку.
- Коды ответа зависят от списка. Например, некоторые списки используют 127.0.0.1 в знак того, что запрос отклонен, поэтому читайте документацию каждого добавляемого списка и при необходимости дополняйте конструкцию case.
Затем пусть cron сравнивает каждый прогон с предыдущим и отправляет письмо только при изменениях:
# Пример: запуск каждый час, письмо отправляется только если вывод отличается от предыдущего прогона
0 * * * * /usr/local/bin/dnsbl-watch.sh > /var/tmp/dnsbl.now 2>&1; cmp -s /var/tmp/dnsbl.now /var/tmp/dnsbl.prev || mail -s "DNSBL status changed" you@example.com < /var/tmp/dnsbl.now; mv /var/tmp/dnsbl.now /var/tmp/dnsbl.prevЕжечасный интервал — лишь пример. Spamhaus предоставляет бесплатный доступ для некоммерческого использования с небольшим объемом запросов, а клиентам, превышающим его порог объема запросов, нужен платный вариант; по мере роста числа отслеживаемых IP проверяйте условия каждого списка. FAQ также советует выполнить команды несколько раз, чтобы убедиться, что результаты не меняются.
Вариант 2: пакетный API DNSBL Checker и вебхуки
Если вы не хотите поддерживать резолвер и правила разбора для каждого списка, проверки можно поручить сервису. Ниже описан API v1 этого сайта — только то, что действительно делает серверная реализация. Справочник находится по адресу /en/api-docs, а ключи выдаются на странице участника /account. Для регистрации нужен только адрес электронной почты, а вход выполняется по ссылке, присланной на почту.
Аутентификация и лимиты
- Ключи начинаются с
dnsbl_и показываются один раз, сразу после выдачи; хранится только хеш. Повторная выдача ключа делает предыдущий недействительным. - Передавайте ключ в заголовке
X-API-Keyв каждом запросе. Только HTTPS; обычный http:// перенаправляется на https://, поэтому сразу обращайтесь по https://. - Лимиты: 1 000 проверок в день (одна цель — одна проверка), 100 целей в пакете и 50 регистраций мониторинга. При превышении дневного лимита возвращается
429сdaily_limit_exceededи отметкой времениresets_at.
Пакетные проверки
Отправьте массив targets с доменными именами или IP-адресами на POST /api/v1/batch:
curl -X POST https://dnsblchecker.com/api/v1/batch \
-H "X-API-Key: $DNSBL_API_KEY" -H "Content-Type: application/json" \
-d '{"targets":["example.com"]}'Если какая-либо цель еще требует проверки, ответ будет 202 с batch_id. Опрашивайте GET /api/v1/batch/{batch_id} каждые несколько секунд, пока status не станет done (сокращенный пример; числа и название списка приведены для иллюстрации, это не реальный результат):
{
"batch_id": 1, "status": "done", "created": "2026-11-03 09:10:41", "count": 1, "pending": 0,
"results": [
{
"target": "example.com", "type": "domain",
"status": "done", "verdict": "listed",
"checked_at": "2026-11-03 09:12",
"lists_checked": 80, "listed_count": 1, "error_count": 4,
"listed_on": [
{ "list": "ZapBL RHSBL", "zone": "rhsbl.zapbl.net", "response": "127.0.0.2" }
]
}
]
}verdictравенlisted, если хотя бы один список сообщает о внесении, иначе —clean. Списки, не ответившие вовремя или ответившие кодом ошибки, например 127.255.255.x, учитываются вerror_countи никогда не считаются записями.- Если есть сохраненный результат за последние 30 дней, пакет возвращает его. При мониторинге по расписанию всегда смотрите на
checked_at. - Некорректные цели возвращаются в
rejectedс указанием причины и не учитываются. Если передать URL, используется только имя хоста. Диапазоны, предназначенные только для документации, например 192.0.2.0/24, отклоняются, поэтому тестируйте на реальном IP отправки.
Мониторинг с вебхуками
Зарегистрируйте target и callback_url через POST /api/v1/monitors. После этого каждая зарегистрированная цель проверяется раз в день без использования кэша (первая проверка выполняется примерно в течение суток после регистрации), а JSON-запрос POST отправляется на ваш URL только при первой проверке (monitor.initial) и когда вердикт меняется между listed и clean (monitor.status_changed).
curl -X POST https://dnsblchecker.com/api/v1/monitors \
-H "X-API-Key: $DNSBL_API_KEY" -H "Content-Type: application/json" \
-d '{"target":"example.com","callback_url":"https://your-app.example/hooks/dnsbl"}'signing_secretв ответе показывается только один раз. Каждая доставка содержит заголовокX-DNSBL-Signature: sha256=...— HMAC-SHA256 исходного тела, вычисленный с этим секретом в качестве ключа. Проверяйте его на своей стороне.callback_urlдолжен использовать https на порте 443 и разрешаться в публичный IP; перенаправления не выполняются, а тайм-аут составляет 10 секунд, поэтому ставьте тяжелую обработку в очередь и отвечайте быстро.- Если ваша конечная точка возвращает что-либо кроме
2xxили соединение не удается, доставка повторяется при следующей ежедневной проверке. Причина отображается какlast_delivery_errorвGET /api/v1/monitors, аDELETE /api/v1/monitors/{monitor_id}удаляет мониторинг.
import hmac, hashlib
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
ok = hmac.compare_digest(expected, request.headers.get("X-DNSBL-Signature", ""))Настройка уведомлений: частота, несколько списков и ложные тревоги
Мониторинг полезен, только если его уведомления продолжают читать и через несколько месяцев. Тот, что срабатывает постоянно, вскоре начинают игнорировать.
Частота
- Разделяйте частоту запросов и частоту уведомлений. Опрашивайте по расписанию, но уведомляйте только при смене состояния. Ежедневное сообщение «все чисто» похоронит то единственное уведомление, которое действительно важно.
- RFC 5782 указывает, что TTL списка должен отражать скорость его изменения и что списки источников спама могут использовать TTL в несколько минут. Выбирайте интервал с учетом того, что некоторые записи появляются и истекают быстро.
- Слишком частые запросы могут нарушить условия использования списка или привести к ответу 127.255.255.255 (чрезмерное число запросов) вместо реальных ответов.
Несколько списков
- Указывайте название списка в каждом уведомлении. Списки различаются тем, сколько получателей их используют, поэтому по самым важным для ваших получателей спискам можно уведомлять сразу, а остальные собирать в сводку.
- Описанный выше вебхук срабатывает только при смене вердикта между listed и clean. Если цель уже в списке и затем появляется во втором списке, событие не отправляется. Чтобы отловить этот случай, следите за
last_listed_countвGET /api/v1/monitorsили запускайте пакетную проверку и читайтеlisted_on.
Ложные срабатывания и временные ответы
- Учитывайте ошибки отдельно от записей. Spamhaus предупреждает операторов, чтобы они не отклоняли и не фильтровали почту по его кодам ошибок; та же логика применима к мониторингу. Тайм-аут или ответ 127.255.255.x никогда не должен вызывать уведомление о внесении в список.
- Чтобы не реагировать на единичный странный результат, уведомляйте только после двух одинаковых результатов подряд или повторяйте запрос через несколько минут, прежде чем что-либо отправлять.
- Если ошибки не прекращаются, подозревайте смену резолвера или изменения на стороне списка и в первую очередь смотрите на результат тестовой записи.
- Домашний IP в Spamhaus PBL — это запись по политике, а не обвинение: она означает, что с этого адреса не следует отправлять почту напрямую. Решите для каждого списка, что считать поводом для уведомления (см. удаление из Spamhaus).
Что делать при обнаружении записи
- Подтвердите ее. Проверьте на странице проверки самого оператора и запишите название списка, время и указанную причину, если она есть.
- Сначала устраните причину. Ищите взломанные аккаунты, используемые злоумышленниками веб-формы, зараженные машины, плохую гигиену списков рассылки и несоответствие обратной DNS-записи (PTR) или имени в HELO. Запрос на удаление при сохраняющейся причине обычно ведет к новой записи.
- Следуйте процедуре удаления этого списка. Решение об удалении принимает оператор каждого списка, и подача запроса не гарантирует снятия записи. Если вы не управляете IP, как в случае виртуального хостинга, обратитесь к хостинг-провайдеру или интернет-провайдеру.
- Пусть мониторинг подтвердит результат. Получатели также используют собственные фильтры, поэтому после возвращения вердикта к clean продолжайте следить за доставкой.
Для разовой проверки IP или домена воспользуйтесь сервисом проверки по черным спискам. Если поиск причины или работа с запросами вам не под силу, вы можете обратиться к нам за помощью. Полный порядок диагностики при возврате писем см. в материале письма, заблокированные из-за черных списков.
Мы порекомендуем специалистов, которые возьмут на себя запросы на исключение из списков, консультации и советы (от JPY 50,000). Решение об исключении принимает оператор каждого списка, поэтому результат гарантировать нельзя.
Получить помощьЭтот сайт может получать вознаграждение за рекомендацию от указанных специалистов. About
Частые вопросы
Я проверил через 8.8.8.8, и записи нет. Значит, все чисто?
Не обязательно. В FAQ Spamhaus сказано, что на запросы через бесплатные открытые резолверы, такие как Google Public DNS, в большинстве случаев приходит ответ «не в списке» (NXDOMAIN), так что IP из списка может выглядеть чистым. Отправляйте запросы через собственный резолвер или используйте страницу проверки оператора.
Я получил 127.255.255.254. Это значит, что я в списке?
Нет. Это код ошибки, возвращаемый на запросы через публичный или открытый резолвер, и Spamhaus указывает, что он не означает внесения объекта в список. Зафиксируйте его как ошибку и не отправляйте уведомление о внесении.
Можно ли использовать ежедневный вызов пакетного API в качестве мониторинга?
Пакет может вернуть сохраненный результат давностью до 30 дней, так что это не всегда текущее состояние. Проверяйте checked_at или используйте мониторинг с вебхуками (POST /api/v1/monitors), который каждый день выполняет свежую проверку.
Нужно ли запрашивать удаление сразу после срабатывания уведомления?
Сначала устраните причину. Запрос, поданный при сохраняющейся проблеме, обычно заканчивается новой записью. Решение всегда остается за оператором списка.
Использованные официальные страницы
Факты в этой статье на момент публикации были сверены с официальными страницами ниже. Правила и поведение сервисов меняются без предупреждения, поэтому перед важными решениями проверьте официальные страницы.
- RFC 5782: DNS Blacklists and Whitelists
- Spamhaus FAQ: DNSBL Usage
- Spamhaus: Using our public mirrors? Check your return codes now
- SpamCop FAQ: How do I configure my mailserver to reject mail based on the blocklist?
Похожие статьи
Как читать коды ответа DNSBL: что значит 127.0.0.2 по RFC 5782, коды Spamhaus, SpamCop и UCEPROTECT, коды ошибок и разница NXDOMAIN и SERVFAIL.
Попали в Spamhaus? Узнайте, в каком вы списке (ZEN, PBL, XBL, CSS, SBL, DBL), что означают коды ответа и как правильно добиться исключения из каждого.
Письма блокирует чёрный список? Разберите код возврата, проверьте причины в правильном порядке, оцените важность записей и правильно запросите исключение.