domain = $domain; // aktiven Selector aus DB, sonst Default aus Config $this->selector = $selector ?: optional( $domain->dkimKeys()->where('is_active', true)->latest()->first() )->selector ?: (string) config('mailpool.defaults.dkim_selector', 'mwl1'); } /** Prüft nur lokale Voraussetzungen (Keyfile + KeyTable + SigningTable) */ protected function isDkimReady(string $domain, string $selector): bool { $d = preg_quote($domain, '/'); $s = preg_quote($selector, '/'); // 1) Key-Datei unter /etc/opendkim/keys//.private $keyFile = "/etc/opendkim/keys/{$domain}/{$selector}.private"; $hasFile = is_readable($keyFile) && filesize($keyFile) > 0; // 2) Einträge in KeyTable + SigningTable $keyTab = is_readable('/etc/opendkim/KeyTable') ? (string) @file_get_contents('/etc/opendkim/KeyTable') : ''; $signTab = is_readable('/etc/opendkim/SigningTable') ? (string) @file_get_contents('/etc/opendkim/SigningTable') : ''; // Beispiele: // KeyTable: mwl1._domainkey.sysmail.toastra.com sysmail.toastra.com:mwl1:/etc/opendkim/keys/sysmail.toastra.com/mwl1.private // SigningTable:*@sysmail.toastra.com mwl1._domainkey.sysmail.toastra.com $inKey = (bool) preg_match( "/^{$s}\._domainkey\.{$d}\s+{$d}:{$s}:/m", $keyTab ); $inSign = (bool) preg_match( "/^\*\@{$d}\s+{$s}\._domainkey\.{$d}\s*$/m", $signTab ); return $hasFile && $inKey && $inSign; } /** Reparieren/Neu erzeugen */ public function regenerate(?string $selector = null): void { $selector = $selector ?: ($this->selector ?: (string) config('mailpool.defaults.dkim_selector', 'mwl1')); try { /** @var DkimService $svc */ $svc = app(DkimService::class); // erzeugt/aktualisiert Keys in storage, pflegt DB, ruft Helper auf (falls vorhanden) $svc->generateForDomain($this->domain, 2048, $selector); // OpenDKIM neu laden (idempotent) Process::run(['systemctl', 'reload', 'opendkim']); // Status neu prüfen $ok = $this->isDkimReady($this->domain->domain, $selector); $this->dispatch('toast', type: $ok ? 'success' : 'warning', message: $ok ? 'DKIM ist aktiv.' : 'DKIM generiert – OpenDKIM prüfen.'); } catch (\Throwable $e) { $this->dispatch('toast', type: 'error', message: 'DKIM Fehler: '.$e->getMessage()); } $this->selector = $selector; // für Folge-Checks } public function render(): View { $dkimOk = $this->isDkimReady($this->domain->domain, $this->selector ?: (string) config('mailpool.defaults.dkim_selector', 'mwl1')); return view('livewire.ui.domain.dkim-status', compact('dkimOk')); } }