DNSBlock
This commit is contained in:
85
app/Services/ASNService.php
Normal file
85
app/Services/ASNService.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
class ASNService
|
||||
{
|
||||
public static function validateIP($ip, $asn)
|
||||
{
|
||||
// Remove 'AS' prefix if present for comparison
|
||||
$targetAsn = ltrim(strtoupper($asn), 'AS');
|
||||
|
||||
// Use whois command
|
||||
// This command queries Cymru's whois server which is reliable for IP to ASN mapping
|
||||
// Format: whois -h whois.cymru.com " -v [IP]"
|
||||
|
||||
$command = sprintf('whois -h whois.cymru.com " -v %s"', escapeshellarg($ip));
|
||||
|
||||
// Use proc_open to capture output and potential errors
|
||||
$descriptorspec = [
|
||||
0 => ["pipe", "r"], // stdin
|
||||
1 => ["pipe", "w"], // stdout
|
||||
2 => ["pipe", "w"] // stderr
|
||||
];
|
||||
|
||||
$process = proc_open($command, $descriptorspec, $pipes);
|
||||
|
||||
if (is_resource($process)) {
|
||||
$output = stream_get_contents($pipes[1]);
|
||||
$errors = stream_get_contents($pipes[2]);
|
||||
fclose($pipes[0]);
|
||||
fclose($pipes[1]);
|
||||
fclose($pipes[2]);
|
||||
$return_value = proc_close($process);
|
||||
|
||||
if ($return_value !== 0 || empty($output)) {
|
||||
// Whois command failed, try HTTP API fallback
|
||||
// Using ip-api.com (free, no key required for limited use)
|
||||
// Format: http://ip-api.com/json/{ip}?fields=status,message,as
|
||||
|
||||
$apiUrl = "http://ip-api.com/json/" . $ip . "?fields=status,message,as";
|
||||
$context = stream_context_create(['http' => ['timeout' => 3]]);
|
||||
$apiResponse = @file_get_contents($apiUrl, false, $context);
|
||||
|
||||
if ($apiResponse !== FALSE) {
|
||||
$data = json_decode($apiResponse, true);
|
||||
if (isset($data['status']) && $data['status'] === 'success' && isset($data['as'])) {
|
||||
// Format example: "AS15169 Google LLC"
|
||||
// Extract AS number
|
||||
if (preg_match('/AS(\d+)/', $data['as'], $matches)) {
|
||||
$foundAsn = $matches[1];
|
||||
return $foundAsn === $targetAsn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If both fail, strictly return false as requested to prevent invalid registrations
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse output
|
||||
// Output example:
|
||||
// AS | IP | BGP Prefix | CC | Registry | Allocated | AS Name
|
||||
// 15169 | 8.8.8.8 | 8.8.8.0/24 | US | arin | 2000-03-30 | GOOGLE, US
|
||||
|
||||
$lines = explode("\n", trim($output));
|
||||
foreach ($lines as $line) {
|
||||
if (strpos($line, 'AS') !== false && strpos($line, 'IP') !== false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$parts = explode('|', $line);
|
||||
if (count($parts) >= 1) {
|
||||
$foundAsn = trim($parts[0]);
|
||||
if ($foundAsn === $targetAsn) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user