palpalani / laravel-dns-deny-list-check
A modern Laravel package for checking IP addresses against verified DNS-based blacklists (DNSBL/RBL) to ensure email deliverability
Fund package maintenance!
palpalani
Installs: 3 686
Dependents: 0
Suggesters: 0
Security: 0
Stars: 2
Watchers: 1
Forks: 1
Open Issues: 1
pkg:composer/palpalani/laravel-dns-deny-list-check
Requires
- php: ^8.3
- illuminate/contracts: ^11.0|^12.0
- spatie/laravel-package-tools: ^1.1
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.8
- orchestra/testbench: ^10.0.0||^9.0.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
README
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.
๐ Table of Contents
- Features
- Requirements
- Architecture
- Installation
- Configuration
- Usage
- Testing
- Production Considerations
- Documentation
- Tools & Standards
- Quality Metrics
- Contributing
- Security
- License
โจ Features
- ๐ Production-Verified DNSBL Servers - Only 12 verified, functional servers (January 2025)
- ๐ Modern PHP 8.3+ - 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 using Pest
- ๐ก๏ธ Edge Case Handling - Graceful error handling and validation
- ๐ Production Ready - Zero false positives, reliable DNSBL servers only
- ๐ Type Safe - Full PHPStan static analysis coverage
๐ Requirements
- PHP 8.3 or higher
- Laravel 11.x or 12.x
- ext-dns (for DNS lookups)
๐๏ธ Architecture
Built with modern PHP and Laravel best practices:
- Type Safety: Full type hints, strict types, and PHPStan analysis
- Testing: Comprehensive Pest test suite with high coverage
- Code Quality: Laravel Pint for code formatting, PHPStan for static analysis
- Performance: Optimized DNS queries with configurable timeouts
๐ 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:
# Run all tests composer test # Run tests with coverage composer test-coverage
The package includes 47 tests with 374 assertions using Pest covering:
- โ IPv4 and IPv6 validation
- โ DNSBL server connectivity
- โ Error handling and edge cases
- โ Facade functionality
- โ Performance testing
- โ Configuration validation
- โ Type safety and static analysis
Code Quality
# Run PHPStan static analysis composer analyse # Fix code style with Laravel Pint composer format
๐ 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
Comprehensive documentation is available in the repository:
๐ง Tools & Standards
This package uses modern development tools and follows best practices:
- Testing: Pest PHP - A delightful PHP testing framework
- Code Style: Laravel Pint - Opinionated PHP code style fixer
- Static Analysis: PHPStan with Larastan
- CI/CD: GitHub Actions with comprehensive test matrix
- Code Quality: Automated code style fixes and static analysis on every push
๐ Quality Metrics
- โ 100% Type Coverage - Full type hints and PHPStan analysis
- โ 47 Tests - Comprehensive test suite with Pest
- โ 374 Assertions - Thorough validation of all features
- โ Zero Dependencies - No external HTTP dependencies, uses native DNS resolution
- โ Production Verified - Only active, reliable DNSBL servers
๐ 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:
- 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' ];
- 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}' ];
- 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'); }
- 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; }
- 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']; }
- 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' ];
- 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}' ];
- 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; }
- 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/' ];
- 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 static analysis composer analyse # Fix code style with Laravel Pint composer format
Contribution Guidelines
- โ Follow PSR-12 coding standards (enforced by Laravel Pint)
- โ Write tests for new features using Pest
- โ
Ensure PHPStan analysis passes (
composer analyse) - โ Update documentation accordingly
- โ Ensure all tests pass before submitting PR
- โ Follow semantic versioning for releases
๐ 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
- palPalani - Creator and maintainer
- All Contributors - Thank you for your contributions!
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!