180 lines
6.6 KiB
PHP
180 lines
6.6 KiB
PHP
<?php
|
|
|
|
namespace App\Observers;
|
|
|
|
use App\Models\DkimKey;
|
|
use App\Models\Domain;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Process;
|
|
|
|
class DomainObserver
|
|
{
|
|
/**
|
|
* DKIM bei neuen Domains erzeugen + in OpenDKIM installieren.
|
|
* Läuft NUR, wenn die Domain aktiv ist (anpassbar).
|
|
*/
|
|
public function created(Domain $domain): void
|
|
{
|
|
if ($domain->is_server) return;
|
|
|
|
$selector = (string) config('mailpool.defaults.dkim_selector', 'mwl1');
|
|
$bits = (int) config('mailpool.defaults.dkim_bits', 2048);
|
|
|
|
// Service erledigt: Key generieren, DB (upsert) pflegen, Helper ausführen, OpenDKIM reloaden
|
|
app(\App\Services\DkimService::class)->generateForDomain($domain, $bits, $selector);
|
|
|
|
// DNS-Records: aktiven Key aus DB lesen und provisionieren
|
|
$active = $domain->dkimKeys()->where('is_active', true)->latest()->first();
|
|
if ($active) {
|
|
app(\App\Services\DnsRecordService::class)->provision(
|
|
$domain,
|
|
$active->selector,
|
|
"v=DKIM1; k=rsa; p={$active->public_key_txt}",
|
|
[
|
|
'spf_tail' => \App\Models\Setting::get('mailpool.spf_tail', '~all'),
|
|
'spf_extra' => \App\Models\Setting::get('mailpool.spf_extra', []),
|
|
'dmarc_policy' => \App\Models\Setting::get('mailpool.dmarc_policy', 'none'),
|
|
'rua' => \App\Models\Setting::get('mailpool.rua', null),
|
|
]
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Beim Löschen alle DKIM-Selector dieser Domain aus OpenDKIM entfernen.
|
|
*/
|
|
public function deleting(Domain $domain): void
|
|
{
|
|
try {
|
|
$svc = app(\App\Services\DkimService::class);
|
|
|
|
// Selector VOR dem Delete einsammeln (Relation oder direkte Query)
|
|
$selectors = DkimKey::where('domain_id', $domain->id)->pluck('selector')->all();
|
|
$selectors = $selectors ?: ['mwl1'];
|
|
|
|
foreach ($selectors as $sel) {
|
|
$cmd = ['sudo','-n','/usr/local/sbin/mailwolt-remove-dkim', $domain->domain, $sel];
|
|
$res = Process::timeout(30)->run($cmd);
|
|
Log::info('DKIM remove exit', [
|
|
'domain' => $domain->domain,
|
|
'selector' => $sel,
|
|
'exit' => $res->exitCode(),
|
|
'out' => $res->output(),
|
|
'err' => $res->errorOutput(),
|
|
]);
|
|
if ($res->failed()) {
|
|
throw new \RuntimeException('OpenDKIM-Remove fehlgeschlagen: '.$res->errorOutput());
|
|
}
|
|
}
|
|
|
|
// lokale Backups unter storage/… löschen (App-User, kein sudo nötig)
|
|
$path = storage_path("app/private/dkim/{$domain->domain}");
|
|
if (is_dir($path)) {
|
|
\Illuminate\Support\Facades\File::deleteDirectory($path);
|
|
}
|
|
|
|
// OpenDKIM neu laden (best effort)
|
|
Process::run(['sudo','-n','/bin/systemctl','reload','opendkim']);
|
|
} catch (\Throwable $e) {
|
|
Log::error('Domain deleting cleanup failed', [
|
|
'domain' => $domain->domain,
|
|
'error' => $e->getMessage(),
|
|
]);
|
|
// Optional: Exception werfen, um das Löschen vollständig abzubrechen
|
|
// throw $e;
|
|
}
|
|
}
|
|
|
|
/** Nur noch Info-Log NACH dem Löschen (kein Cleanup mehr hier) */
|
|
public function deleted(Domain $domain): void
|
|
{
|
|
Log::info('Domain deleted', ['domain' => $domain->domain]);
|
|
}
|
|
|
|
/** Für forceDelete bei SoftDeletes */
|
|
public function forceDeleted(Domain $domain): void
|
|
{
|
|
$this->deleted($domain);
|
|
}
|
|
|
|
|
|
// public function deleted(Domain $domain): void
|
|
// {
|
|
// try {
|
|
// $svc = app(\App\Services\DkimService::class);
|
|
//
|
|
// foreach ($domain->dkimKeys as $key) {
|
|
// $svc->removeForDomain($domain, $key->selector);
|
|
// }
|
|
//
|
|
// // Local storage wegräumen (kein Root nötig)
|
|
// $path = storage_path("app/private/dkim/{$domain->domain}");
|
|
// if (is_dir($path)) {
|
|
// \Illuminate\Support\Facades\File::deleteDirectory($path);
|
|
// }
|
|
//
|
|
// Log::info("Domain deleted + DKIM cleaned", ['domain' => $domain->domain]);
|
|
// } catch (\Throwable $e) {
|
|
// Log::error("Domain delete cleanup failed", ['domain'=>$domain->domain,'error'=>$e->getMessage()]);
|
|
// }
|
|
// }
|
|
//
|
|
// public function forceDeleted(Domain $domain): void
|
|
// {
|
|
// $this->deleted($domain);
|
|
// }
|
|
|
|
// public function created(Domain $domain): void
|
|
// {
|
|
// if ($domain->is_server) {
|
|
// return;
|
|
// }
|
|
//
|
|
// $selector = (string) config('mailpool.defaults.dkim_selector', 'mwl1');
|
|
// $bits = (int) config('mailpool.defaults.dkim_bits', 2048);
|
|
//
|
|
// $res = app(\App\Services\DkimService::class)
|
|
// ->generateForDomain($domain, $bits, $selector);
|
|
//
|
|
// // DNS-Records gleich anlegen/aktualisieren
|
|
// app(\App\Services\DnsRecordService::class)->provision(
|
|
// $domain,
|
|
// $dk->selector,
|
|
// "v=DKIM1; k=rsa; p={$dk->public_key_txt}",
|
|
// [
|
|
// 'spf_tail' => \App\Models\Setting::get('mailpool.spf_tail', '~all'),
|
|
// 'spf_extra' => \App\Models\Setting::get('mailpool.spf_extra', []),
|
|
// 'dmarc_policy' => \App\Models\Setting::get('mailpool.dmarc_policy', 'none'),
|
|
// 'rua' => \App\Models\Setting::get('mailpool.rua', null),
|
|
// ]
|
|
// );
|
|
// }
|
|
|
|
// public function deleted(Domain $domain): void
|
|
// {
|
|
// try {
|
|
// /** @var \App\Services\DkimService $svc */
|
|
// $svc = app(\App\Services\DkimService::class);
|
|
//
|
|
// // Entferne DKIM aus OpenDKIM Config
|
|
// $svc->removeForDomain($domain);
|
|
//
|
|
// // Optionale lokale Dateien löschen
|
|
// $path = storage_path("app/private/dkim/{$domain->domain}");
|
|
// if (is_dir($path)) {
|
|
// \Illuminate\Support\Facades\File::deleteDirectory($path);
|
|
// }
|
|
//
|
|
// // Reload OpenDKIM
|
|
// \Illuminate\Support\Facades\Process::run(['sudo','-n','/usr/bin/systemctl','reload','opendkim']);
|
|
//
|
|
// Log::info("Domain deleted + DKIM cleaned", ['domain' => $domain->domain]);
|
|
// } catch (\Throwable $e) {
|
|
// Log::error("Domain delete cleanup failed", [
|
|
// 'domain' => $domain->domain,
|
|
// 'error' => $e->getMessage(),
|
|
// ]);
|
|
// }
|
|
// }
|
|
}
|