palpalani/laravel-dns-deny-list-check

checks if the given IP address or hostname is blacklisted on the configured dnsbl servers

1.0.0 2025-09-22 05:21 UTC

This package is auto-updated.

Last update: 2025-09-29 04:29:46 UTC


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

A modern, production-ready Laravel package for checking email server IP addresses against verified DNS-based blacklists (DNSBL/RBL). This package helps ensure email deliverability by testing your mail server against 12 carefully curated, actively maintained blacklist services.

โœจ Features

  • ๐Ÿ” Production-Verified DNSBL Servers - Only 12 verified, functional servers (January 2025)
  • ๐Ÿš€ Modern PHP 8.1+ - Uses readonly properties, constructor promotion, and strict typing
  • ๐ŸŒ Full IPv4 & IPv6 Support - Handles both IP versions with proper reverse notation
  • โšก Performance Optimized - Configurable timeouts and optional concurrent checking
  • ๐Ÿ“Š Detailed Statistics - Comprehensive response data with performance metrics
  • ๐ŸŽฏ Tier-Based Checking - Critical, Important, and Supplementary DNSBL categories
  • ๐Ÿ”ง Laravel Integration - Service provider, facade, and configuration support
  • โœ… Comprehensive Testing - 47 tests with 374 assertions
  • ๐Ÿ›ก๏ธ Edge Case Handling - Graceful error handling and validation

๐Ÿ“‹ Requirements

  • PHP 8.1 or higher
  • Laravel 10.0 or higher
  • ext-dns (for DNS lookups)

๐Ÿš€ Installation

Install the package via Composer:

composer require palpalani/laravel-dns-deny-list-check

The service provider will be automatically registered thanks to Laravel's package auto-discovery.

Configuration (Optional)

Publish the configuration file to customize DNSBL servers:

php artisan vendor:publish --provider="palPalani\DnsDenyListCheck\DnsDenyListCheckServiceProvider" --tag="laravel-dns-deny-list-check-config"

This creates config/dns-deny-list-check.php with 12 production-verified DNSBL servers:

return [
    'servers' => [
        // TIER 1: CRITICAL - Most trusted DNSBLs
        ['name' => 'SpamCop Blocking List', 'host' => 'bl.spamcop.net', 'tier' => 1, 'priority' => 'critical'],
        ['name' => 'Barracuda Reputation Block List', 'host' => 'b.barracudacentral.org', 'tier' => 1, 'priority' => 'critical'],
        ['name' => 'UCEPROTECT Level 1', 'host' => 'dnsbl-1.uceprotect.net', 'tier' => 1, 'priority' => 'critical'],
        
        // TIER 2: IMPORTANT - Specialized authority DNSBLs
        ['name' => 'DroneB Anti-Abuse', 'host' => 'dnsbl.dronebl.org', 'tier' => 2, 'priority' => 'important'],
        ['name' => 'Backscatterer IPS', 'host' => 'ips.backscatterer.org', 'tier' => 2, 'priority' => 'important'],
        // ... additional servers
    ],
];

๐Ÿ“– Usage

Basic Usage

use palPalani\DnsDenyListCheck\DnsDenyListCheck;

// Using the class directly
$checker = new DnsDenyListCheck();
$result = $checker->check('8.8.8.8');

// Using the facade
use palPalani\DnsDenyListCheck\DnsDenyListCheckFacade as DnsDenyListCheck;

$result = DnsDenyListCheck::check('8.8.8.8');

Response Structure

[
    'success' => true,
    'message' => 'IP check completed: 0 blacklists found IP as listed out of 12 total servers checked.',
    'data' => [
        [
            'host' => 'bl.spamcop.net',
            'listed' => false,
            'response_time' => 0.123,
            'tier' => 1,
            'priority' => 'critical'
        ],
        // ... more results
    ],
    'stats' => [
        'total_checked' => 12,
        'total_listed' => 0,
        'total_unlisted' => 12,
        'total_errors' => 0,
        'average_response_time' => 0.098
    ],
    'ip_version' => 'IPv4',
    'checked_at' => '2025-01-22T10:30:45.123456Z'
]

Advanced Configuration

use palPalani\DnsDenyListCheck\DnsDenyListCheck;

// Custom server list
$customServers = [
    ['name' => 'Custom DNSBL', 'host' => 'custom.dnsbl.com', 'tier' => 1, 'priority' => 'critical']
];

$checker = new DnsDenyListCheck(
    dnsblServers: $customServers,
    timeoutSeconds: 15,
    ipv6Enabled: true,
    concurrentEnabled: false
);

$result = $checker->check('2001:db8::1'); // IPv6 support

Laravel Service Container

// In a service provider
$this->app->bind(DnsDenyListCheck::class, function ($app) {
    return new DnsDenyListCheck(
        timeoutSeconds: config('dns-deny-list-check.timeout', 10)
    );
});

// In a controller
public function checkIp(DnsDenyListCheck $checker, Request $request)
{
    $result = $checker->check($request->ip());
    
    return response()->json($result);
}

๐Ÿงช Testing

Run the comprehensive test suite:

composer test

The package includes 47 tests with 374 assertions covering:

  • โœ… IPv4 and IPv6 validation
  • โœ… DNSBL server connectivity
  • โœ… Error handling and edge cases
  • โœ… Facade functionality
  • โœ… Performance testing
  • โœ… Configuration validation

Test Coverage

# Run tests with coverage (requires Xdebug)
vendor/bin/phpunit --coverage-html coverage

# Run specific test group
vendor/bin/phpunit --group integration

๐Ÿ”’ Production Considerations

DNSBL Server Reliability

This package uses only verified, production-ready DNSBL servers (January 2025):

  • โŒ Removed non-functional services: SORBS (shut down June 2024), SpamRats, defunct Spamhaus services
  • โœ… 12 verified servers: Tested for DNS resolution, active maintenance, and low false positives
  • ๐ŸŽฏ Tier-based approach: Critical (3), Important (4), Supplementary (5) categories

Performance Tips

// For high-volume applications
$checker = new DnsDenyListCheck(
    timeoutSeconds: 5,        // Reduce timeout for faster responses
    concurrentEnabled: true   // Enable concurrent checking (when available)
);

// Cache results to avoid repeated checks
Cache::remember("dnsbl_check_{$ip}", 3600, function () use ($ip, $checker) {
    return $checker->check($ip);
});

Error Handling

$result = DnsDenyListCheck::check($ip);

if (!$result['success']) {
    Log::warning('DNSBL check failed', [
        'ip' => $ip,
        'error' => $result['message']
    ]);
    
    // Fallback logic
    return ['status' => 'unknown', 'reason' => 'DNSBL service unavailable'];
}

// Check if IP is blacklisted
$blacklisted = $result['stats']['total_listed'] > 0;

๐Ÿ“š Documentation

๐Ÿ“‹ Changelog

Please see CHANGELOG for more information on what has changed recently.

ToDo

๐Ÿ“‹ Alternative Blacklist Checking Techniques

Here are other methods beyond DNS-based blacklists for email deliverability checking:

  1. API-Based Reputation Services
// Example: Reputation services with REST APIs
$reputation_apis = [
    'Microsoft SNDS' => 'https://postmaster.live.com/snds/', // Requires signup
    'Google Postmaster Tools' => 'https://www.gmail.com/postmaster/',
    'Yahoo Sender Hub' => 'https://senders.yahooinc.com/',
    'Mailgun Reputation API' => 'https://api.mailgun.net/v4/ip/reputation',
    'SendGrid Reputation' => 'https://api.sendgrid.com/v3/ips/{ip}/reputation'
];
  1. Multi-Service Aggregators
// Services that check multiple blacklists via single API
$aggregator_services = [
    'MXToolbox API' => 'https://api.mxtoolbox.com/api/v1/monitor',
    'WhatIsMyIPAddress API' => 'https://api.whatismyipaddress.com/blacklist',
    'DNSlytics API' => 'https://api.dnslytics.com/v1/ip2blacklists',
    'HackerTarget API' => 'https://api.hackertarget.com/blacklistchecker/',
    'ipqualityscore.com' => 'https://ipqualityscore.com/api/json/ip/{api_key}/{ip}'
];
  1. SURBL/URIBL Domain Checking
// Check domains/URLs instead of IPs
$domain_blacklists = [
    'SURBL Multi' => 'multi.surbl.org',
    'URIBL Multi' => 'multi.uribl.com',
    'URIBL Black' => 'black.uribl.com',
    'URIBL Red' => 'red.uribl.com',
    'Spamhaus DBL' => 'dbl.spamhaus.org'
];

// Example usage: Check if domain is blacklisted
function checkDomainBlacklist($domain, $blacklist) {
    $query = $domain . '.' . $blacklist . '.';
    return checkdnsrr($query, 'A');
}
  1. SMTP Test Connections
// Test actual SMTP delivery capability
function testSmtpDelivery($ip, $targetMx) {
    $socket = fsockopen($targetMx, 25, $errno, $errstr, 10);
    if (!$socket) return false;

    $response = fgets($socket);
    if (strpos($response, '220') !== 0) {
        fclose($socket);
        return false;
    }

    fputs($socket, "HELO test.com\r\n");
    $response = fgets($socket);

    fclose($socket);
    return strpos($response, '250') === 0;
}
  1. GeoIP & ASN-Based Checks
// Check IP geography and network ownership
$geolocation_services = [
    'MaxMind GeoIP2' => 'https://dev.maxmind.com/geoip/geoip2/',
    'IPinfo.io' => 'https://ipinfo.io/{ip}/json',
    'ip-api.com' => 'http://ip-api.com/json/{ip}',
    'IPGeolocation.io' => 'https://api.ipgeolocation.io/ipgeo'
];

// Example: Block specific countries/ASNs known for spam
function checkGeoReputation($ip) {
    $high_risk_countries = ['CN', 'RU', 'KP']; // Example
    $high_risk_asns = ['AS12345', 'AS67890']; // Example spam networks

    // Implementation would check against these lists
    return ['risk_level' => 'low', 'country' => 'US', 'asn' => 'AS15169'];
}
  1. Machine Learning Reputation Scoring
// AI/ML-based reputation services
$ml_reputation_services = [
    'AWS GuardDuty' => 'https://aws.amazon.com/guardduty/',
    'Microsoft Defender' => 'https://docs.microsoft.com/en-us/microsoft-365/security/',
    'Cisco Talos' => 'https://talosintelligence.com/reputation_center',
    'VirusTotal' => 'https://www.virustotal.com/api/v3/ip_addresses/{ip}',
    'AbuseIPDB' => 'https://api.abuseipdb.com/api/v2/check'
];
  1. Real-Time Threat Intelligence
// Live threat feeds and intelligence services
$threat_intelligence = [
    'Emerging Threats' => 'https://rules.emergingthreats.net/',
    'AlienVault OTX' => 'https://otx.alienvault.com/api/v1/indicators/',
    'ThreatCrowd' => 'https://www.threatcrowd.org/searchApi/v2/ip/report/',
    'IBM X-Force' => 'https://api.xforce.ibmcloud.com/ipr/{ip}',
    'Shodan' => 'https://api.shodan.io/shodan/host/{ip}'
];
  1. Email Authentication Checks
// Verify SPF, DKIM, DMARC configuration
function checkEmailAuthentication($domain) {
    $checks = [];

    // SPF Record
    $spf = dns_get_record($domain, DNS_TXT);
    $checks['spf'] = array_filter($spf, fn($r) => str_contains($r['txt'], 'v=spf1'));

    // DMARC Record  
    $dmarc = dns_get_record('_dmarc.' . $domain, DNS_TXT);
    $checks['dmarc'] = array_filter($dmarc, fn($r) => str_contains($r['txt'], 'v=DMARC1'));

    // DKIM (requires knowing selector)
    // $dkim = dns_get_record('selector._domainkey.' . $domain, DNS_TXT);

    return $checks;
}
  1. Historical Analysis
// Track IP reputation over time
$historical_services = [
    'Passive DNS' => 'https://www.circl.lu/services/passive-dns/',
    'SecurityTrails' => 'https://api.securitytrails.com/v1/history/{ip}/a',
    'WhoisXML API' => 'https://reverse-ip-api.whoisxmlapi.com/api/v1',
    'DomainTools' => 'https://api.domaintools.com/v1/{ip}/host-domains/'
];
  1. Integration Examples
// Combined approach using multiple techniques
class ComprehensiveReputationChecker {
    public function checkReputation($ip) {
        return [
            'dnsbl' => $this->checkDnsbl($ip),           // Your current implementation
            'api_reputation' => $this->checkApiReputation($ip),
            'smtp_test' => $this->testSmtpConnectivity($ip),
            'geo_analysis' => $this->checkGeoReputation($ip),
            'threat_intel' => $this->checkThreatIntelligence($ip),
            'final_score' => $this->calculateFinalScore()
        ];
    }
}

๐Ÿค Contributing

We welcome contributions! Please see CONTRIBUTING for details.

Development Setup

# Clone the repository
git clone https://github.com/palpalani/laravel-dns-deny-list-check.git
cd laravel-dns-deny-list-check

# Install dependencies
composer install

# Run tests
composer test

# Run code style fixes
composer format

Contribution Guidelines

  • Follow PSR-12 coding standards
  • Write tests for new features
  • Update documentation accordingly
  • Ensure all tests pass before submitting PR

๐Ÿ” Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

For security-related issues, please email security@palpalani.com instead of using the issue tracker.

๐Ÿ“ฆ Versioning

We use SemVer for versioning. For the versions available, see the tags on this repository.

๐Ÿ‘ฅ Credits

Acknowledgments

  • Spatie - For excellent Laravel package tools and inspiration
  • DNSBL Service Providers - For maintaining public blacklist services
  • Laravel Community - For feedback and testing

๐Ÿ“„ License

The MIT License (MIT). Please see License File for more information.

๐Ÿš€ Ready to ensure email deliverability?
Install Laravel DNS Deny List Check and start protecting your email reputation today!