How to Programmatically Remove IP from SORBS Blacklist: A Developer’s Guide to Email Server Deliverability


2 views

html

When our production email server got listed on SORBS (Spam and Open Relay Blocking System), it created serious delivery issues with our suppliers' systems. As developers, we needed a technical solution rather than waiting through manual delisting processes. Here's how we solved it programmatically.

SORBS maintains several DNSBL zones with different listing criteria:

// Common SORBS zones to check
const SORBS_ZONES = [
    'dul.dnsbl.sorbs.net',      // Dynamic IP ranges
    'smtp.dnsbl.sorbs.net',     // Open SMTP relays
    'spam.dnsbl.sorbs.net',     // Spam sources
    'web.dnsbl.sorbs.net',      // Vulnerable HTTP servers
    'socks.dnsbl.sorbs.net'     // SOCKS proxies
];

Before delisting, verify your IP's status across all relevant SORBS zones:

import dns.resolver

def check_sorbs_listing(ip_address):
    results = {}
    reverse_ip = '.'.join(reversed(ip_address.split('.')))
    
    for zone in SORBS_ZONES:
        query = f"{reverse_ip}.{zone}"
        try:
            answers = dns.resolver.resolve(query, 'A')
            results[zone] = [str(r) for r in answers]
        except dns.resolver.NXDOMAIN:
            results[zone] = None
    
    return results

SORBS provides an automated delisting API when you have legitimate reasons:

import requests

def request_sorbs_delisting(ip_address, email, reason):
    url = "https://www.sorbs.net/cgi-bin/support"
    data = {
        'ipaddress': ip_address,
        'email': email,
        'reason': reason,
        'submit': 'Submit Request'
    }
    
    response = requests.post(url, data=data)
    return response.status_code == 200

Common technical issues that trigger SORBS listings:

# Postfix main.cf example to prevent open relay
smtpd_recipient_restrictions = 
    permit_mynetworks,
    reject_unauth_destination,
    reject_rbl_client dul.dnsbl.sorbs.net,
    reject_rbl_client spam.dnsbl.sorbs.net

# Exim4 configuration to limit email rates
rate {
    # Apply to all messages
    use = recipient

    # Maximum 20 messages per minute
    rate = 20 / 1m
}

Implement continuous monitoring to catch future listings early:

from prometheus_client import Gauge
import socket

SORBS_STATUS = Gauge('sorbs_blacklist_status', 
                    'SORBS blacklist status by zone',
                    ['zone'])

def monitor_sorbs_listing(ip_address):
    status = check_sorbs_listing(ip_address)
    for zone, result in status.items():
        SORBS_STATUS.labels(zone=zone).set(1 if result else 0)

Remember that SORBS maintains some listings for significant periods. The best approach is to prevent listings through proper server configuration and monitoring.


When our production email server got listed on SORBS (Spam and Open Relay Blocking System), it caused immediate SMTP delivery failures with critical suppliers. The blacklisting disrupted our automated order confirmation system built with Python's smtplib:

import smtplib
try:
    server = smtplib.SMTP('mail.example.com', 25)
    server.sendmail('orders@example.com', 'supplier@vendor.com', order_msg)
except smtplib.SMTPException as e:
    log_error(f"SORBS blocked delivery: {str(e)}")  # Connection timeout errors

After analyzing our mail server logs, we found the listing was triggered by:

  • Outdated Postfix configuration allowing open relays
  • An internal cron job sending batch emails too rapidly
  • Missing SPF/DKIM records in our DNS zone

For developers needing programmatic solutions, here's how we automated the delisting workflow:

#!/bin/bash
# Check SORBS listing status
IP=$(hostname -i)
if dig +short $IP.dnsbl.sorbs.net | grep -q "127.0.0.10"; then
    # Submit delist request via API
    curl -X POST https://www.sorbs.net/api/delist \
        -d "ip=$IP" \
        -d "reason=server_misconfiguration_fixed" \
        -d "contact=admin@example.com"
    
    # Verify removal
    while dig +short $IP.dnsbl.sorbs.net; do
        sleep 300  # Check every 5 minutes
    done
    systemctl restart postfix
fi

We implemented these technical safeguards:

  1. Rate limiting in Postfix (main.cf):
smtpd_client_message_rate_limit = 100
anvil_rate_time_unit = 60s
  1. Automated monitoring script:
# Python blacklist monitor
import dns.resolver
from datetime import datetime

BL_SERVERS = ['dnsbl.sorbs.net', 'bl.spamcop.net']

def check_blacklists(ip):
    for bl in BL_SERVERS:
        try:
            query = f"{ip}.{bl}"
            answers = dns.resolver.resolve(query, 'A')
            if answers:
                send_alert(f"Blacklisted on {bl} at {datetime.now()}")
        except dns.resolver.NXDOMAIN:
            continue

Ensure these records exist in your DNS zone file:

; SPF Record
example.com. IN TXT "v=spf1 mx -all"

; DKIM Record
mail._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC..."

; DMARC Record
_dmarc.example.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com"

When testing email delivery, use this telnet sequence to verify SORBS isn't blocking:

$ telnet mail.example.com 25
Trying 192.0.2.1...
Connected to mail.example.com.
EHLO example.com
250-mail.example.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN

Watch for 554 errors indicating blacklist rejection:

554 5.7.1 Service unavailable; Client host [x.x.x.x] blocked using dnsbl.sorbs.net