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; // } //}