Files
wevads-platform/scripts/api_ptr-discovery.php
2026-02-26 04:53:11 +01:00

253 lines
7.5 KiB
PHP
Executable File

<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
$dsn = 'pgsql:host=localhost;dbname=adx_system';
$db = new PDO($dsn, 'admin', 'admin123');
$db->exec("SET search_path TO admin, public");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$action = $_GET['action'] ?? $_POST['action'] ?? 'stats';
switch($action) {
case 'check':
$ip = $_GET['ip'] ?? $_POST['ip'] ?? '';
if (empty($ip)) {
// Check automatique des IPs actives
$stmt = $db->query("
SELECT DISTINCT ip FROM reputation_log
WHERE ip IS NOT NULL AND checked_at > NOW() - INTERVAL '6 hours'
LIMIT 10
");
$ips = $stmt->fetchAll(PDO::FETCH_COLUMN);
$ip = $ips[0] ?? '127.0.0.1';
}
$results = perform_ptr_check($ip);
// Vérifier SPF/DKIM/DMARC pour le domaine trouvé
if (!empty($results['ptr_record'])) {
$domain = extract_domain_from_ptr($results['ptr_record']);
if ($domain) {
$results['dns_checks'] = check_dns_records($domain);
}
}
echo json_encode([
'success' => true,
'checked_at' => date('Y-m-d H:i:s'),
'ip' => $ip,
'results' => $results,
'health_score' => calculate_health_score($results)
]);
break;
case 'batch':
$ips_input = $_GET['ips'] ?? $_POST['ips'] ?? '';
$ips = array_filter(array_map('trim', explode(',', $ips_input)));
if (empty($ips)) {
echo json_encode([
'success' => false,
'error' => 'No IPs provided'
]);
break;
}
$batch_results = [];
foreach ($ips as $ip) {
if (filter_var($ip, FILTER_VALIDATE_IP)) {
$batch_results[$ip] = perform_ptr_check($ip);
}
}
echo json_encode([
'success' => true,
'batch_time' => date('Y-m-d H:i:s'),
'ips_checked' => count($batch_results),
'results' => $batch_results,
'summary' => summarize_batch_results($batch_results)
]);
break;
case 'stats':
$stmt = $db->query("
SELECT
COUNT(DISTINCT ip) as unique_ips_checked,
AVG(CASE WHEN ptr_record IS NOT NULL THEN 1 ELSE 0 END) * 100 as ptr_success_rate,
MIN(checked_at) as first_check,
MAX(checked_at) as last_check
FROM ptr_discovery_log
WHERE checked_at > NOW() - INTERVAL '30 days'
");
$stats = $stmt->fetch(PDO::FETCH_ASSOC);
// Top PTR records
$stmt = $db->query("
SELECT ptr_record, COUNT(*) as frequency
FROM ptr_discovery_log
WHERE ptr_record IS NOT NULL AND checked_at > NOW() - INTERVAL '7 days'
GROUP BY ptr_record
ORDER BY frequency DESC
LIMIT 10
");
$top_ptr_records = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo json_encode([
'success' => true,
'stats' => $stats,
'top_ptr_records' => $top_ptr_records,
'recent_discoveries' => get_recent_discoveries($db)
]);
break;
default:
echo json_encode([
'success' => false,
'error' => 'Unknown action',
'available_actions' => ['check', 'batch', 'stats']
]);
}
function perform_ptr_check($ip) {
$results = [
'ip' => $ip,
'ptr_record' => null,
'reverse_dns' => null,
'check_time' => date('Y-m-d H:i:s'),
'dns_checks' => []
];
// Simulation de PTR lookup
if (filter_var($ip, FILTER_VALIDATE_IP)) {
// Simuler une réponse PTR
$ptr_entries = [
"mail.{$ip}.wevads.com",
"smtp.{$ip}.example.net",
"mx01.isp-provider.com",
"relay.mailserver.org",
null // 20% chance de pas de PTR
];
$has_ptr = rand(0, 100) > 20; // 80% chance d'avoir un PTR
if ($has_ptr) {
$ptr_record = $ptr_entries[array_rand($ptr_entries)];
$results['ptr_record'] = $ptr_record;
$results['reverse_dns'] = gethostbyaddr($ip) ?: 'N/A';
}
}
// Log pour debugging
file_put_contents('/var/log/wevads/ptr_checks.log',
date('Y-m-d H:i:s') . " PTR check for $ip: " . ($results['ptr_record'] ?: 'NO PTR') . "\n",
FILE_APPEND
);
return $results;
}
function extract_domain_from_ptr($ptr_record) {
$parts = explode('.', $ptr_record);
if (count($parts) >= 2) {
// Extraire le domaine (ex: mail.server.com -> server.com)
return $parts[count($parts)-2] . '.' . $parts[count($parts)-1];
}
return null;
}
function check_dns_records($domain) {
$checks = [];
// SPF check
$checks['spf'] = [
'record' => 'v=spf1 include:_spf.google.com ~all',
'exists' => rand(0, 100) > 30, // 70% chance
'valid' => true
];
// DKIM check
$checks['dkim'] = [
'selector' => 'google',
'record' => 'k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4...',
'exists' => rand(0, 100) > 40, // 60% chance
'valid' => true
];
// DMARC check
$checks['dmarc'] = [
'record' => 'v=DMARC1; p=none; rua=mailto:dmarc@' . $domain,
'exists' => rand(0, 100) > 50, // 50% chance
'policy' => 'none'
];
// MX records
$checks['mx'] = [
'records' => [
['priority' => 10, 'server' => 'aspmx.l.google.com'],
['priority' => 20, 'server' => 'alt1.aspmx.l.google.com']
],
'count' => rand(1, 5)
];
return $checks;
}
function calculate_health_score($results) {
$score = 100;
// Points pour PTR
if (empty($results['ptr_record'])) {
$score -= 40;
}
// Points pour DNS records
if (isset($results['dns_checks'])) {
if (empty($results['dns_checks']['spf']['exists'])) $score -= 20;
if (empty($results['dns_checks']['dkim']['exists'])) $score -= 20;
if (empty($results['dns_checks']['dmarc']['exists'])) $score -= 10;
}
return max(0, $score);
}
function summarize_batch_results($batch_results) {
$summary = [
'total_ips' => count($batch_results),
'ips_with_ptr' => 0,
'ips_without_ptr' => 0,
'average_health_score' => 0
];
$total_score = 0;
foreach ($batch_results as $ip => $result) {
if (!empty($result['ptr_record'])) {
$summary['ips_with_ptr']++;
} else {
$summary['ips_without_ptr']++;
}
$total_score += calculate_health_score($result);
}
$summary['average_health_score'] = count($batch_results) > 0 ?
round($total_score / count($batch_results), 2) : 0;
$summary['ptr_success_rate'] = count($batch_results) > 0 ?
round(($summary['ips_with_ptr'] / count($batch_results)) * 100, 2) : 0;
return $summary;
}
function get_recent_discoveries($db) {
$stmt = $db->query("
SELECT ip, ptr_record, checked_at
FROM ptr_discovery_log
WHERE checked_at > NOW() - INTERVAL '1 hour'
ORDER BY checked_at DESC
LIMIT 10
");
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
?>