load(); } public function render() { return view('livewire.ui.security.rbl-card'); } public function refresh(): void { // Manuelles Re-Check via Command (asynchron, damit UI nicht blockiert) @shell_exec('nohup php /var/www/mailwolt/artisan rbl:probe --force >/dev/null 2>&1 &'); // Sofortige UI-Aktualisierung aus Settings (altes Ergebnis) … $this->load(true); // … und kurzer Hinweis $this->dispatch('toast', type:'info', title:'RBL-Prüfung gestartet', text:'Ergebnis wird aktualisiert, sobald verfügbar.', duration:2500); } protected function load(bool $force = false): void { $payload = $force ? (array) Setting::get('health.rbl', []) // direkt aus DB : (array) (Cache::get('health.rbl') ?: Setting::get('health.rbl', [])); $this->ip = (string)($payload['ip'] ?? '–'); $this->ipv4 = $payload['ipv4'] ?? null; $this->ipv6 = $payload['ipv6'] ?? null; $this->hits = (int)($payload['hits'] ?? 0); $this->lists = (array)($payload['lists'] ?? []); $this->meta = (array)($payload['meta'] ?? []); $this->checkedAt = $payload['checked_at'] ?? null; $this->validUntil = $payload['valid_until'] ?? null; } } //namespace App\Livewire\Ui\Security; // //use Illuminate\Support\Facades\Cache; //use Livewire\Component; // //class RblCard extends Component //{ // public string $ip = '–'; // public int $hits = 0; // public array $lists = []; // // public ?string $ipv4 = null; // public ?string $ipv6 = null; // // // Schalte registrierungspflichtige Listen (Barracuda etc.) optional zu // private bool $includeRegistered = false; // env('RBL_INCLUDE_REGISTERED', false) wenn du willst // // public function mount(): void // { // $this->load(); // } // // public function render() // { // return view('livewire.ui.security.rbl-card'); // } // // public function refresh(): void // { // Cache::forget('dash.rbl'); // $this->load(true); // } // // protected function load(bool $force = false): void // { // [$ip4, $ip6] = $this->resolvePublicIpsFromInstallerEnv(); // // $this->ipv4 = $ip4 ?: trim((string)env('SERVER_PUBLIC_IPV4', '')) ?: '–'; // $this->ipv6 = $ip6 ?: trim((string)env('SERVER_PUBLIC_IPV6', '')) ?: '–'; // // $data = Cache::remember('dash.rbl', $force ? 1 : 6 * 3600, function () { // $candidate = $this->validIPv4($this->ipv4 ?? '') ? $this->ipv4 : null; // // if (!$candidate) { // $fromFile = trim((string)@file_get_contents('/etc/mailwolt/public_ip')); // if ($this->validIPv4($fromFile)) $candidate = $fromFile; // } // if (!$candidate) { // $curl = trim((string)@shell_exec("curl -fsS --max-time 2 ifconfig.me 2>/dev/null")); // if ($this->validIPv4($curl)) $candidate = $curl; // } // // $ip = $candidate ?: '0.0.0.0'; // $lists = $this->queryRblLists($ip); // // return ['ip' => $ip, 'hits' => count($lists), 'lists' => $lists]; // }); // // foreach ($data as $k => $v) $this->$k = $v; // } // // /** bevorzugt Installer-ENV */ // private function resolvePublicIpsFromInstallerEnv(): array // { // $file = '/etc/mailwolt/installer.env'; // if (!is_readable($file)) return [null, null]; // // $ipv4 = $ipv6 = null; // $lines = @file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: []; // foreach ($lines as $line) { // if (preg_match('/^\s*#/', $line) || !str_contains($line, '=')) continue; // [$k, $v] = array_map('trim', explode('=', $line, 2)); // $v = trim($v, " \t\n\r\0\x0B\"'"); // if ($k === 'SERVER_PUBLIC_IPV4' && $this->validIPv4($v)) $ipv4 = $v; // if ($k === 'SERVER_PUBLIC_IPV6' && $this->validIPv6($v)) $ipv6 = $v; // } // return [$ipv4, $ipv6]; // } // // private function validIPv4(?string $ip): bool // { // return (bool)filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4); // } // // private function validIPv6(?string $ip): bool // { // return (bool)filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6); // } // // /** // * Prüft die IP gegen gängige **öffentliche** RBLs. // * @return array gelistete RBL-Zonen // */ // private function queryRblLists(string $ip): array // { // if (!$this->validIPv4($ip)) return []; // // $rev = implode('.', array_reverse(explode('.', $ip))); // // // nur Zonen prüfen, die es wirklich gibt // $zones = [ // 'zen.spamhaus.org', // 'psbl.surriel.com', // 'dnsbl-1.uceprotect.net', // 'all.s5h.net', // ]; // $zones = array_values(array_filter($zones, fn($z) => @checkdnsrr($z.'.','NS'))); // // $listed = []; // foreach ($zones as $zone) { // $q = "{$rev}.{$zone}."; // // $a = @dns_get_record($q, DNS_A) ?: []; // if (!count($a)) continue; // // $ips = array_column($a, 'ip'); // // // --- WICHTIG: Spamhaus "blocked" / Ratelimit ignorieren // if (array_intersect($ips, ['127.255.255.254','127.255.255.255'])) { // // optional: merk dir, dass Spamhaus blockt -> UI-Hinweis // $listed[] = ['zone'=>$zone, 'code'=>'blocked', 'txt'=>null]; // continue; // } // // $txtRecs = @dns_get_record($q, DNS_TXT) ?: []; // $txt = $txtRecs[0]['txt'] ?? null; // // $listed[] = ['zone'=>$zone, 'code'=>$ips[0] ?? null, 'txt'=>$txt]; // } // // // Nur echte Treffer zurückgeben; „blocked“ separat signalisieren // $real = array_values(array_filter($listed, fn($e) => ($e['code'] ?? null) !== 'blocked')); // // // Falls alles nur "blocked" war, gib leere Liste zurück // return array_map(fn($e) => $e['zone'].($e['code'] ? " ({$e['code']})" : ''), $real); // } //} ////declare(strict_types=1); // //namespace App\Livewire\Ui\Security; // //use Livewire\Component; //use Illuminate\Support\Facades\Cache; // //class RblCard extends Component //{ // public string $ip = '–'; // public int $hits = 0; // public array $lists = []; // // public ?string $ipv4 = null; // public ?string $ipv6 = null; // // public function mount(): void // { // $this->load(); // } // // public function render() // { // return view('livewire.ui.security.rbl-card'); // } // // public function refresh(): void // { // Cache::forget('dash.rbl'); // $this->load(true); // } // // protected function load(bool $force = false): void // { // // 1) IPv4/IPv6 bevorzugt aus /etc/mailwolt/installer.env // [$ip4, $ip6] = $this->resolvePublicIpsFromInstallerEnv(); // // // 2) Fallback auf .env // $this->ipv4 = $ip4 ?: trim((string) env('SERVER_PUBLIC_IPV4', '')) ?: '–'; // $this->ipv6 = $ip6 ?: trim((string) env('SERVER_PUBLIC_IPV6', '')) ?: '–'; // // // 3) RBL-Ermittlung (cached) // $data = Cache::remember('dash.rbl', $force ? 1 : 21600, function () { // // bevorzugt eine valide IPv4 für den RBL-Check // $candidate = $this->validIPv4($this->ipv4 ?? '') ? $this->ipv4 : null; // // if (!$candidate) { // $fromFile = @file_get_contents('/etc/mailwolt/public_ip') ?: ''; // $fromFile = trim($fromFile); // if ($this->validIPv4($fromFile)) { // $candidate = $fromFile; // } // } // // if (!$candidate) { // // letzter Fallback – kann auf Hardened-Systemen geblockt sein // $curl = @shell_exec("curl -fsS --max-time 2 ifconfig.me 2>/dev/null") ?: ''; // $curl = trim($curl); // if ($this->validIPv4($curl)) { // $candidate = $curl; // } // } // // $ip = $candidate ?: '0.0.0.0'; // $lists = $this->queryRblLists($ip); // // return ['ip' => $ip, 'hits' => count($lists), 'lists' => $lists]; // }); // // // 4) Werte ins Component-State // foreach ($data as $k => $v) { // $this->$k = $v; // } // } // // /** Bevorzugt Installer-ENV; gibt [ipv4, ipv6] zurück oder [null, null]. */ // private function resolvePublicIpsFromInstallerEnv(): array // { // $file = '/etc/mailwolt/installer.env'; // if (!is_readable($file)) { // return [null, null]; // } // // $ipv4 = null; // $ipv6 = null; // // $lines = @file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: []; // foreach ($lines as $line) { // // Kommentare überspringen // if (preg_match('/^\s*#/', $line)) { // continue; // } // // KEY=VALUE (VALUE evtl. in "..." oder '...') // if (!str_contains($line, '=')) { // continue; // } // [$k, $v] = array_map('trim', explode('=', $line, 2)); // $v = trim($v, " \t\n\r\0\x0B\"'"); // // if ($k === 'SERVER_PUBLIC_IPV4' && $this->validIPv4($v)) { // $ipv4 = $v; // } elseif ($k === 'SERVER_PUBLIC_IPV6' && $this->validIPv6($v)) { // $ipv6 = $v; // } // } // // return [$ipv4, $ipv6]; // } // // private function validIPv4(?string $ip): bool // { // return (bool) filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4); // } // // private function validIPv6(?string $ip): bool // { // return (bool) filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6); // } // // /** // * Prüft die IP gegen ein paar gängige RBLs. // * Nutzt PHP-DNS (checkdnsrr), keine externen Tools. // * // * @return array gelistete RBL-Zonen // */ // private function queryRblLists(string $ip): array // { // // Nur IPv4 prüfen (die meisten Listen hier sind v4) // if (!$this->validIPv4($ip)) { // return []; // } // // $rev = implode('.', array_reverse(explode('.', $ip))); // $sources = [ // 'zen.spamhaus.org', // 'bl.spamcop.net', // 'dnsbl.sorbs.net', // 'b.barracudacentral.org', // ]; // // $listed = []; // foreach ($sources as $zone) { // $qname = "{$rev}.{$zone}"; // // A-Record oder TXT deuten auf Listing hin // if (@checkdnsrr($qname . '.', 'A') || @checkdnsrr($qname . '.', 'TXT')) { // $listed[] = $zone; // } // } // // return $listed; // } //} // //namespace App\Livewire\Ui\Security; // //use Livewire\Component; //use Illuminate\Support\Facades\Cache; // //class RblCard extends Component //{ // public string $ip = '–'; // public int $hits = 0; // public array $lists = []; // // public ?string $ipv4 = null; // public ?string $ipv6 = null; // // // public function mount(): void { $this->load(); } // public function render() { return view('livewire.ui.security.rbl-card'); } // public function refresh(): void { $this->load(true); } // // protected function load(bool $force=false): void // { // $this->ipv4 = trim(env('SERVER_PUBLIC_IPV4')) ?: '–'; // $this->ipv6 = trim(env('SERVER_PUBLIC_IPV6')) ?: '–'; // // $data = Cache::remember('dash.rbl', $force ? 1 : 21600, function () { // $ip = trim(@file_get_contents('/etc/mailwolt/public_ip') ?: ''); // if ($ip === '') $ip = trim(@shell_exec("curl -fsS --max-time 2 ifconfig.me 2>/dev/null") ?? ''); // if (!preg_match('/^\d+\.\d+\.\d+\.\d+$/', $ip)) $ip = '0.0.0.0'; // // $rev = implode('.', array_reverse(explode('.', $ip))); // $sources = [ // 'zen.spamhaus.org', // 'bl.spamcop.net', // 'dnsbl.sorbs.net', // 'b.barracudacentral.org', // ]; // // $lists = []; // foreach ($sources as $s) { // $q = "$rev.$s"; // $res = trim(@shell_exec("dig +short ".escapeshellarg($q)." A 2>/dev/null") ?? ''); // if ($res !== '') $lists[] = $s; // } // // return ['ip'=>$ip, 'hits'=>count($lists), 'lists'=>$lists]; // }); // // foreach ($data as $k=>$v) $this->$k = $v; // } //}