Monitoring8 min read

Catch IP blacklistings before customers do

Spamhaus, Barracuda, SORBS, UCEPROTECT. When your sending IP lands on a list, mail stops landing in inboxes. Users do not see why. Here is how to catch listings in minutes instead of days.

There is no useful warning before an IP is blacklisted. Spamhaus does not email you. Your ESP does not page on-call. The first sign is usually a drop in placement and a spike in support tickets two days later.

The only way to catch a listing early is to actively query the blacklists yourself, on a schedule, from a script you control. Here is how.

The blacklists that actually matter

In 2026, four lists affect a non-trivial share of inbound mail at Gmail, Outlook, and large enterprise MTAs: Spamhaus ZEN (combines SBL, XBL, PBL, CSS), Barracuda, SpamCop, and SORBS. UCEPROTECT has fans and detractors; monitor level 1 but expect level 2/3 to fire a lot even on clean IPs.

How DNSBL queries work

A DNSBL (DNS-based block list) answers queries of the form reversed.ip.blacklist.example. If the query returns anything (usually a 127.0.0.x address), the IP is listed. NXDOMAIN means clean.

# Example: is 192.0.2.42 on Spamhaus ZEN?
# Reverse the IP octets: 42.2.0.192, append zen.spamhaus.org
dig +short 42.2.0.192.zen.spamhaus.org
# Returns 127.0.0.4 -> listed (in CSS)
# Returns nothing -> clean

IPv6 works the same way but with 32 nibbles reversed. Most blacklists support IPv6 badly; for IPv6 sending, rely on ESP-level reputation signals instead of DNSBL checks.

The check script

Reverses the IP once, fans out queries to ~10 blacklists in parallel, collects the verdicts, alerts if any fire. Runs in under a second.

#!/usr/bin/env bash
# /usr/local/bin/dnsbl_check.sh
set -euo pipefail

IP="$1"
SLACK="${SLACK_WEBHOOK}"

# Reverse the IP
IFS=. read -r a b c d <<< "$IP"
REV="$d.$c.$b.$a"

# Blacklists worth checking in 2026
BLACKLISTS=(
  zen.spamhaus.org
  b.barracudacentral.org
  bl.spamcop.net
  dnsbl.sorbs.net
  dnsbl-1.uceprotect.net
  psbl.surriel.com
  bl.mailspike.net
  dnsbl.invaluement.com
  truncate.gbudb.net
  bl.score.senderscore.com
)

LISTED=()

# Query each blacklist in parallel (subshell + wait)
for bl in "${BLACKLISTS[@]}"; do
  (
    RESULT=$(dig +time=2 +tries=1 +short "${REV}.${bl}." || true)
    if [[ -n "$RESULT" ]]; then
      echo "$bl -> $RESULT"
    fi
  ) &
done
wait

# Rerun sequentially to collect results (simple approach)
for bl in "${BLACKLISTS[@]}"; do
  RESULT=$(dig +time=2 +tries=1 +short "${REV}.${bl}." || true)
  [[ -n "$RESULT" ]] && LISTED+=("$bl -> $RESULT")
done

if [[ ${#LISTED[@]} -gt 0 ]]; then
  MSG="IP $IP listed on: ${LISTED[*]}"
  curl -s -X POST "$SLACK" -H "Content-Type: application/json" \
    -d "{\"text\":\":rotating_light: $MSG\"}"
  echo "$MSG"
  exit 2
fi

echo "OK - $IP clean on ${#BLACKLISTS[@]} blacklists"
exit 0

Scheduling and rate limits

Most blacklists have a query rate policy. Spamhaus, in particular, will stop returning results if your resolver exceeds their query volume. For personal or small-business use the limits are generous; for a tool that checks on behalf of customers you need a Spamhaus Data Query Service (DQS) subscription and a dedicated resolver endpoint.

For most self-monitoring use cases:

  • Every 15 minutes per IP is a safe rate for Spamhaus and the others. Do not go sub-minute.
  • Use your own resolver, not 8.8.8.8. Spamhaus rate-limits Google's resolver heavily; queries may start returning empty even on genuinely listed IPs.
  • Cache aggressively. A 5-minute cache per (IP, list) pair cuts query volume by 3x if you have multiple monitoring jobs.
Resolver matters

If your checks always come back "clean" regardless of reality, you are probably rate-limited at the resolver level without knowing it. Test deliberately: query a known-listed test IP like 127.0.0.2 against zen.spamhaus.org. That address is guaranteed listed. If you get no response, your resolver is the problem.

Wiring to Nagios / Prometheus

The script above is already Nagios-compatible (exit codes 0/2, one-line status). For Prometheus, emit the count of listings as a gauge:

# Write to textfile collector
{
  echo "# TYPE dnsbl_listings gauge"
  for IP in 192.0.2.42 192.0.2.43; do
    COUNT=$(./dnsbl_check.sh "$IP" 2>/dev/null | grep -c '->' || true)
    echo "dnsbl_listings{ip=\"$IP\"} $COUNT"
  done
} > /var/lib/node_exporter/textfile/dnsbl.prom.$$
mv /var/lib/node_exporter/textfile/dnsbl.prom.$$ /var/lib/node_exporter/textfile/dnsbl.prom
# Alertmanager rule
- alert: IPBlacklisted
  expr: dnsbl_listings > 0
  for: 10m
  labels:
    severity: critical
  annotations:
    summary: "IP {{ $labels.ip }} listed on {{ $value }} blacklists"

What to do when an alert fires

  1. Confirm. Some blacklists have false positives; some return temporary listings that resolve themselves in 30 minutes. Wait for the for: 10m window.
  2. Identify the specific list. Spamhaus ZEN is actually five sub-lists (SBL, XBL, PBL, CSS, DROP). The return code tells you which one: 127.0.0.2 = SBL, .4 = XBL,.10/.11 = PBL, .3 = CSS.
  3. Check the reason. Most lists publish a lookup page with evidence and instructions. For dedicated IPs with legitimate mail, a delisting request is usually approved within 24 hours.
  4. Pause sending from the listed IP until delisting, unless you are warming a shared pool where the listing is not about your traffic.

Shared IP caveat

If you send through a shared ESP pool, you cannot control listings on the upstream IPs. Your ESP does. But you should still monitor — if the shared pool gets listed, you need to know immediately so you can pause cadence or rotate to a different pool.

For dedicated IPs, a listing is your problem and you have to act.

FAQ

How many blacklists is enough to monitor?

Ten is plenty. Spamhaus, Barracuda, SpamCop, SORBS, and Mailspike cover the majority of ingestion at Gmail and Outlook. The long tail of regional blacklists matters only for niche audiences.

What about MXToolbox / MultiRBL.valli.org?

Useful for ad-hoc investigation, rate-limited for automated monitoring. Build your own checker for the sustained monitoring and use these sites when an alert fires to investigate depth.

What if my domain, not my IP, is blacklisted?

Some lists are URI-based (Spamhaus DBL). Check by querying acme.io.dbl.spamhaus.org. If it returns a 127.0.1.x address, the domain is listed. Follow the same pattern as IP-based checks.

Does blacklisting always cause placement drops?

Listings on Spamhaus SBL and Barracuda will cause immediate placement drops at Gmail/Outlook. Listings on smaller or more aggressive lists (UCEPROTECT level 2/3) have minimal effect. Weight your response accordingly.
Related reading

Check your deliverability across 20+ providers

Gmail, Outlook, Yahoo, Mail.ru, Yandex, GMX, ProtonMail and more. Real inbox screenshots, SPF/DKIM/DMARC, spam engine verdicts. Free, no signup.

Run Free Test →

Unlimited tests · 20+ seed mailboxes · Live results · No account required