palpalani/laravel-dns-deny-list-check
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.
Built with modern PHP and Laravel best practices:
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.
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
],
];
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');
[
'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'
]
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
// 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);
}
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:
# Run PHPStan static analysis
composer analyse
# Fix code style with Laravel Pint
composer format
This package uses only verified, production-ready DNSBL servers (January 2025):
// 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);
});
$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;
Comprehensive documentation is available in the repository:
This package uses modern development tools and follows best practices:
Please see CHANGELOG for more information on what has changed recently.
๐ Alternative Blacklist Checking Techniques
Here are other methods beyond DNS-based blacklists for email deliverability checking:
// 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'
];
// 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}'
];
// 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');
}
// 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;
}
// 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'];
}
// 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'
];
// 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}'
];
// 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;
}
// 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/'
];
// 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()
];
}
}
We welcome contributions! Please see CONTRIBUTING for details.
# 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
composer analyse)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.
We use SemVer for versioning. For the versions available, see the tags on this repository.
The MIT License (MIT). Please see License File for more information.
How can I help you explore Laravel packages today?