From 1e288af617e1bb55f1f95493da018eff73661589 Mon Sep 17 00:00:00 2001 From: sorcier Date: Wed, 4 Nov 2026 11:33:08 +0100 Subject: [PATCH] fix(metrics): robust contact detection with AstDB fallback and reset f2b counters on clear log (v1.4.7) --- public/api.php | 4 ++-- public/index.php | 2 +- src/SystemChecker.php | 21 +++++++++++++++++++++ src/SystemMetrics.php | 40 ++++++++++++++++++++++++++++++++++++---- version.json | 11 +++++------ 5 files changed, 65 insertions(+), 13 deletions(-) diff --git a/public/api.php b/public/api.php index d00703a..b51e03d 100644 --- a/public/api.php +++ b/public/api.php @@ -140,7 +140,7 @@ try { $installedVerData = file_exists("{$appDir}/version.json") ? json_decode((string)file_get_contents("{$appDir}/version.json"), true) : []; - $installedVer = $installedVerData['version'] ?? '1.4.6'; + $installedVer = $installedVerData['version'] ?? '1.4.7'; echo json_encode([ 'success' => true, @@ -227,7 +227,7 @@ try { @chmod($webLog, 0664); } @unlink('/tmp/nexus_fw_status_cache.json'); - exec('sudo /usr/bin/fail2ban-client reload 2>&1'); + exec('sudo /usr/bin/systemctl restart fail2ban 2>&1 || sudo /usr/bin/fail2ban-client reload 2>&1'); echo json_encode([ 'success' => true, diff --git a/public/index.php b/public/index.php index bc1a690..f878e3f 100644 --- a/public/index.php +++ b/public/index.php @@ -18,7 +18,7 @@ $companyLogo = trim($branding['company_logo'] ?? ''); $hasBranding = !empty($companyName) || !empty($companyLogo); $appVerData = file_exists(__DIR__ . '/../version.json') ? json_decode((string)file_get_contents(__DIR__ . '/../version.json'), true) : []; -$appVersion = $appVerData['version'] ?? '1.4.6'; +$appVersion = $appVerData['version'] ?? '1.4.7'; ?> diff --git a/src/SystemChecker.php b/src/SystemChecker.php index ea7601d..f481749 100644 --- a/src/SystemChecker.php +++ b/src/SystemChecker.php @@ -225,6 +225,27 @@ class SystemChecker @mkdir('/var/spool/asterisk/voicemail/default', 0775, true); + // Synchroniser manager.conf avec le mot de passe AMI de la base SQLite si nécessaire (ex: après restauration de backup) + $mgrConf = '/etc/asterisk/manager.conf'; + if (is_file($mgrConf) && is_writable($mgrConf)) { + try { + $db = Database::getConnection(); + $st = $db->query('SELECT ami_user, ami_secret FROM settings WHERE id = 1')->fetch(); + if (!empty($st['ami_secret'])) { + $sec = trim((string)$st['ami_secret']); + $usr = trim((string)($st['ami_user'] ?? 'pbxgui')) ?: 'pbxgui'; + $content = (string)file_get_contents($mgrConf); + if (str_contains($content, "[{$usr}]")) { + $updated = preg_replace("/(\[{$usr}\][^\[]*secret\s*=\s*)([^\r\n]+)/i", "\${1}{$sec}", $content); + if ($updated !== null && $updated !== $content) { + file_put_contents($mgrConf, $updated); + @exec('asterisk -rx "manager reload" 2>/dev/null || true'); + } + } + } + } catch (\Throwable) {} + } + $astConf = '/etc/asterisk/asterisk.conf'; if (is_file($astConf) && is_writable($astConf)) { $content = (string)file_get_contents($astConf); diff --git a/src/SystemMetrics.php b/src/SystemMetrics.php index 9992a0d..183dd85 100644 --- a/src/SystemMetrics.php +++ b/src/SystemMetrics.php @@ -298,17 +298,19 @@ class SystemMetrics } } + $seenExts = []; foreach (preg_split('/\r?\n/', $rawContacts) ?: [] as $line) { - // Contact: 101/sip:101@10.10.167.162:5060 5dd9a21be8 Avail 9.234 - // or with -nan: Contact: 102/sip:102@10.10.168.228:5060;x-ast-txp=trans bb0686ce80 Unavail -nan - if (preg_match('/Contact:\s+([^\s\/]+)\/sip:([^\s]+)\s+([a-f0-9]+)\s+(\S+)\s+(-?[0-9.]+|nan|-nan)/i', $line, $m)) { + // Supporte sip:, sips:, sans préfixe, tous types de hash et RTT (numérique, nan, N/A ou absent) + if (preg_match('/Contact:\s+([^\s\/]+)\/(?:sips?:)?([^\s]+)\s+([a-zA-Z0-9]+)\s+(\S+)(?:\s+(\S+))?/i', $line, $m)) { $extNum = $m[1]; $uri = $m[2]; $status = $m[4]; + $rttRaw = $m[5] ?? null; $isAvail = (stripos($status, 'Avail') !== false && stripos($status, 'Unavail') === false) || stripos($status, 'NonQual') !== false; if ($isAvail) { $onlineCount++; } + $seenExts[$extNum] = true; $meta = $contactMeta[$extNum] ?? []; $fullUri = $meta['uri'] ?? ("sip:" . $uri); @@ -330,7 +332,37 @@ class SystemMetrics 'user_agent' => $userAgent, 'active_transport' => $activeTransport, 'status' => $status, - 'rtt_ms' => is_numeric($m[5]) ? round((float)$m[5], 1) : null, + 'rtt_ms' => ($rttRaw !== null && is_numeric($rttRaw)) ? round((float)$rttRaw, 1) : null, + ]; + } + } + + // Filet de sécurité 100% infaillible : Tous les contacts enregistrés dans AstDB (/registrar/contact) + // non encore répertoriés (par exemple si qualify est désactivé ou RTT non disponible) + $nowTime = time(); + foreach ($contactMeta as $extNum => $meta) { + if (isset($seenExts[$extNum])) { + continue; + } + $exp = (int)($meta['expiration_time'] ?? 0); + if ($exp === 0 || $exp > $nowTime) { + $onlineCount++; + $fullUri = $meta['uri'] ?? ''; + $activeTransport = 'udp'; + if (preg_match('/transport=(tls|wss|ws|tcp|udp)/i', $fullUri, $tm)) { + $activeTransport = strtolower($tm[1]); + } elseif (preg_match('/x-ast-txp=transport-(tls|wss|ws|tcp|udp)/i', $fullUri, $tm)) { + $activeTransport = strtolower($tm[1]); + } elseif (str_starts_with($fullUri, 'sips:')) { + $activeTransport = 'tls'; + } + $contacts[] = [ + 'extension' => (string)$extNum, + 'uri' => $fullUri, + 'user_agent' => $meta['user_agent'] ?? '', + 'active_transport' => $activeTransport, + 'status' => 'Avail', + 'rtt_ms' => null, ]; } } diff --git a/version.json b/version.json index 3d98894..3d1e0ae 100644 --- a/version.json +++ b/version.json @@ -1,13 +1,12 @@ { - "version": "1.4.6", + "version": "1.4.7", "codename": "Helios", "release_date": "2026-11-04", "min_php_version": "8.2", "changelog": [ - "Fiabilisation clé en main de la messagerie vocale (*97 / *98) sur toute installation fraîche Debian (install.sh & fix.sh)", - "Neutralisation préventive des modules voicemail ODBC/IMAP incompatibles sur Debian (évite les conflits bloquant app_voicemail)", - "Inclusion automatique de voicemail.custom.conf et musiconhold.custom.conf dès l'installation", - "Génération et permissions strictes sur les répertoires de spool voicemail (/var/spool/asterisk/voicemail)", - "Contrôle d'intégrité renforcé dans le diagnostic système (SystemChecker)" + "Détection ultra-robuste de l'état des téléphones IP (support SIPS, statuts sans qualify et fallback infaillible AstDB)", + "Réinitialisation immédiate du compteur d'attaques contrées Fail2ban lors du vidage du journal de sécurité", + "Synchronisation automatique des identifiants AMI (/etc/asterisk/manager.conf) après restauration d'une sauvegarde", + "Correction et fiabilisation de la messagerie vocale (*97 / *98) sur toute installation fraîche Debian" ] }