253 lines
7.5 KiB
PHP
Executable File
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);
|
|
}
|
|
?>
|