Rechtebechebung für User mit Sudorechte

main
boban 2025-10-19 17:50:54 +02:00
parent d6007589ef
commit 450247d163
2 changed files with 11 additions and 43 deletions

View File

@ -17,7 +17,7 @@ class DkimStatus extends Component
{ {
$this->domain = $domain; $this->domain = $domain;
// aktiven Selector aus DB; sonst Default aus Config // aktiver Selector aus DB, sonst Default aus config
$this->selector = $selector $this->selector = $selector
?: optional( ?: optional(
$domain->dkimKeys()->where('is_active', true)->latest()->first() $domain->dkimKeys()->where('is_active', true)->latest()->first()
@ -26,46 +26,20 @@ class DkimStatus extends Component
} }
/** /**
* Prüft NUR lokal: * Minimalcheck: ist das Keyfile vorhanden & >0 Bytes?
* - Keyfile: /etc/opendkim/keys/<domain>/<selector>.private * Nutzt sudo /usr/bin/test, damit www-data auch bei 0600/0750 prüfen kann.
* - KeyTable & SigningTable enthalten passende Zeilen
*/ */
protected function isDkimReady(string $domain, string $selector): bool protected function isDkimReady(string $domain, string $selector): bool
{ {
$d = preg_quote($domain, '/'); $key = "/etc/opendkim/keys/{$domain}/{$selector}.private";
$s = preg_quote($selector, '/');
// 1) Key-Datei vorhanden & lesbar // -s => existiert und Größe > 0
$keyFile = "/etc/opendkim/keys/{$domain}/{$selector}.private"; $res = Process::run(['sudo','-n','/usr/bin/test','-s',$key]);
$hasFile = is_readable($keyFile) && (filesize($keyFile) > 0);
// 2) Tabellen-Inhalte lesen (leer wenn Datei fehlt) return $res->successful();
$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')
: '';
// Beispiel-Zeilen:
// 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
// Robust gegen Mehrfach-Spaces/Tabs:
$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;
} }
/** Button: (Re)generieren via Service (der ruft sudo-Helper auf) */ /** Button: (Re)generieren → Service kümmert sich um Helper & Reload */
public function regenerate(?string $selector = null): void public function regenerate(?string $selector = null): void
{ {
$selector = $selector $selector = $selector
@ -74,31 +48,25 @@ class DkimStatus extends Component
try { try {
/** @var DkimService $svc */ /** @var DkimService $svc */
$svc = app(DkimService::class); $svc = app(DkimService::class);
// erzeugt/aktualisiert Keys in storage, pflegt DB,
// ruft /usr/local/sbin/mailwolt-install-dkim via sudo -n auf,
// lädt opendkim neu (im Service)
$svc->generateForDomain($this->domain, 2048, $selector); $svc->generateForDomain($this->domain, 2048, $selector);
// Status neu prüfen // Status nach der Erzeugung erneut prüfen
$ok = $this->isDkimReady($this->domain->domain, $selector); $ok = $this->isDkimReady($this->domain->domain, $selector);
$this->dispatch('toast', $this->dispatch('toast',
type: $ok ? 'success' : 'warning', type: $ok ? 'success' : 'warning',
message: $ok ? 'DKIM ist aktiv.' : 'DKIM generiert OpenDKIM prüfen.' message: $ok ? 'DKIM ist aktiv.' : 'DKIM generiert OpenDKIM prüfen.'
); );
} catch (\Throwable $e) { } catch (\Throwable $e) {
$this->dispatch('toast', type: 'error', message: 'DKIM Fehler: '.$e->getMessage()); $this->dispatch('toast', type: 'error', message: 'DKIM Fehler: '.$e->getMessage());
} }
// aktuellen Selector merken (falls der Fallback zuvor anders war)
$this->selector = $selector; $this->selector = $selector;
} }
public function render(): View public function render(): View
{ {
$sel = $this->selector ?: (string) config('mailpool.defaults.dkim_selector', 'mwl1'); $sel = $this->selector ?: (string) config('mailpool.defaults.dkim_selector', 'mwl1');
$dkimOk = $this->isDkimReady($this->domain->domain, $sel); $dkimOk = $this->isDkimReady($this->domain->domain, $sel);
return view('livewire.ui.domain.dkim-status', compact('dkimOk')); return view('livewire.ui.domain.dkim-status', compact('dkimOk'));

View File

@ -17,7 +17,7 @@ class DkimService
{ {
$selector = $selector ?: (string) config('mailpool.defaults.dkim_selector', 'mwl1'); $selector = $selector ?: (string) config('mailpool.defaults.dkim_selector', 'mwl1');
$dirKey = $this->safeKey($domain); $dirKey = $this->safeKey($domain->domain);
$selKey = $this->safeKey($selector, 32); $selKey = $this->safeKey($selector, 32);
// Disk "local" zeigt bei dir auf storage/app/private (siehe Kommentar in deinem Code) // Disk "local" zeigt bei dir auf storage/app/private (siehe Kommentar in deinem Code)