Domain Create Modal anpassen Fehler auf Null

main
boban 2025-10-18 18:09:40 +02:00
parent b10cb90b09
commit 609bf48a46
5 changed files with 54 additions and 50 deletions

View File

@ -35,8 +35,8 @@ class DomainCreateModal extends ModalComponent
public bool $active = true;
// DKIM
public string $dkim_selector = 'dkim';
public int $dkim_bits = 2048; // 1024/2048/3072/4096
public string $dkim_selector;
public int $dkim_bits;
// Anzeige
public int $available_mib = 0;
@ -52,8 +52,8 @@ class DomainCreateModal extends ModalComponent
$this->max_quota_per_mailbox_mb = config('mailpool.defaults.max_quota_per_mailbox_mb', 3072);
$this->total_quota_mb = (int)config('mailpool.defaults.total_quota_mb', 10240);
$this->dkim_selector = (string)config('mailpool.defaults.dkim_selector', 'dkim');
$this->dkim_bits = (int)config('mailpool.defaults.dkim_bits', 2048);
$this->dkim_selector = (string) config('mailpool.defaults.dkim_selector', 'mwl1');
$this->dkim_bits = (int) config('mailpool.defaults.dkim_bits', 2048);
// Speicherpool-Grenze
$this->available_mib = (int)$pool->remainingPoolMb();

View File

@ -16,7 +16,7 @@ class DomainObserver
*/
public function created(Domain $domain): void
{
$selector = (string) config('mailpool.defaults.dkim_selector', 'dkim');
$selector = (string) config('mailpool.defaults.dkim_selector', 'mwl1');
$bits = (int) config('mailpool.defaults.dkim_bits', 2048);
$res = app(\App\Services\DkimService::class)

View File

@ -11,20 +11,42 @@ use RuntimeException;
class DkimService
{
/** Erzeugt Keypair & gibt den TXT-Record (ohne Host) zurück. */
public function generateForDomain(Domain $domainId, int $bits = 2048, string $selector = 'dkim'): array
public function generateForDomain(Domain $domain, int $bits = 2048, string $selector = null): array
{
$dirKey = $this->safeKey($domainId);
$selKey = $this->safeKey($selector, 32);
// 1) Selector zentral aus der Config (Fallback 'mwl1')
$selector = $selector ?: (string) config('mailpool.defaults.dkim_selector', 'mwl1');
$disk = Storage::disk('local');
$baseRel = "private/dkim/{$dirKey}";
$privRel = "{$baseRel}/{$selKey}.pem";
$pubRel = "{$baseRel}/{$selKey}.pub";
$dirKey = $this->safeKey($domain);
$selKey = $this->safeKey($selector, 32);
// 1) Ordner sicherstellen
$disk = Storage::disk('local');
$baseRel = "private/dkim/{$dirKey}";
$privRel = "{$baseRel}/{$selKey}.pem";
$pubRel = "{$baseRel}/{$selKey}.pub";
// 2) Idempotent: existiert das Paar schon? -> nur lesen & zurückgeben
if ($disk->exists($privRel) && $disk->exists($pubRel)) {
$privateKey = $disk->get($privRel);
$publicKeyPem = $disk->get($pubRel);
$publicKeyBase = self::extractPublicKeyBase64($publicKeyPem);
if (strlen($publicKeyBase) < 300) {
throw new \RuntimeException('DKIM: Public Key zu kurz vermutlich Parsing-Fehler.');
}
return [
'selector' => $selKey,
'priv_path' => storage_path("app/{$privRel}"),
'pub_path' => storage_path("app/{$pubRel}"),
'public_pem' => $publicKeyPem,
'private_pem' => $privateKey,
'dns_name' => "{$selKey}._domainkey",
'dns_txt' => "v=DKIM1; k=rsa; p={$publicKeyBase}",
'bits' => $bits,
];
}
// 3) Sonst neu generieren
$disk->makeDirectory($baseRel);
// 2) Keypair via PHP-OpenSSL (kein shell_exec)
$res = openssl_pkey_new([
'private_key_type' => OPENSSL_KEYTYPE_RSA,
'private_key_bits' => $bits,
@ -42,11 +64,12 @@ class DkimService
if ($details === false || empty($details['key'])) {
throw new \RuntimeException('DKIM: Public Key konnte nicht gelesen werden.');
}
$publicKeyPem = $details['key'];
Log::debug('dkim.pem.first_line', ['line' => strtok($publicKeyPem, "\n")]);
Log::debug('dkim.pem.len', ['len' => strlen($publicKeyPem)]);
$publicKeyPem = $details['key'];
$publicKeyBase = self::extractPublicKeyBase64($publicKeyPem);
if (strlen($publicKeyBase) < 300) {
throw new \RuntimeException('DKIM: Public Key zu kurz vermutlich Parsing-Fehler.');
}
// 3) Schreiben über Storage (legt Dateien an, keine zu langen Pfade in Komponenten)
if (!$disk->put($privRel, $privateKey)) {
throw new \RuntimeException("DKIM: Private-Key schreiben fehlgeschlagen: {$privRel}");
}
@ -54,27 +77,18 @@ class DkimService
throw new \RuntimeException("DKIM: Public-Key schreiben fehlgeschlagen: {$pubRel}");
}
$publicKeyBase64 = self::extractPublicKeyBase64($publicKeyPem);
Log::debug('dkim.p.len', ['len' => strlen($publicKeyBase64)]);
$dnsTxt = "v=DKIM1; k=rsa; p={$publicKeyBase64}";
// sanity: RSA2048 liegt typ. > 300 chars
if (strlen($publicKeyBase64) < 300) {
throw new \RuntimeException('DKIM: Public Key zu kurz vermutlich Parsing-Fehler.');
}
// 4) Rückgabe
return [
'selector' => $selKey,
'priv_path' => storage_path("app/{$privRel}"),
'pub_path' => storage_path("app/{$pubRel}"),
'public_pem' => $publicKeyPem,
'private_pem' => $privateKey,
'dns_name' => "{$selKey}._domainkey", // vor Domain hängen
'dns_txt' => $dnsTxt,
'dns_name' => "{$selKey}._domainkey",
'dns_txt' => "v=DKIM1; k=rsa; p={$publicKeyBase}",
'bits' => $bits,
];
}
protected function safeKey($value, int $max = 64): string
{
if (is_object($value)) {

View File

@ -13,14 +13,17 @@ return [
'dmarc_policy' => env('MAILPOOL_DMARC_POLICY', 'none'),
'defaults' => [
'max_aliases' => (int) env('MAILPOOL_DEFAULT_MAX_ALIASES', 400),
'max_mailboxes' => (int) env('MAILPOOL_DEFAULT_MAX_MAILBOXES', 10),
'dkim_selector' => 'mwl1',
'dkim_bits' => 2048,
'default_quota_mb' => (int) env('MAILPOOL_DEFAULT_MAILBOX_QUOTA_MB', 3072),
'max_quota_per_mailbox_mb' => env('MAILPOOL_DEFAULT_MAX_MAILBOX_QUOTA_MB', 3072),
'total_quota_mb' => (int) env('MAILPOOL_DEFAULT_DOMAIN_TOTAL_MB', 10240),
'max_aliases' => (int) env('MAILPOOL_DEFAULT_MAX_ALIASES', 400),
'max_mailboxes' => (int) env('MAILPOOL_DEFAULT_MAX_MAILBOXES', 10),
'rate_limit_per_hour' => env('MAILPOOL_DEFAULT_RATE_LIMIT_PER_HOUR', null),
'rate_limit_override' => (bool) env('MAILPOOL_DEFAULT_RATE_OVERRIDE', false),
'default_quota_mb' => (int) env('MAILPOOL_DEFAULT_MAILBOX_QUOTA_MB', 3072),
'max_quota_per_mailbox_mb' => env('MAILPOOL_DEFAULT_MAX_MAILBOX_QUOTA_MB', 3072),
'total_quota_mb' => (int) env('MAILPOOL_DEFAULT_DOMAIN_TOTAL_MB', 10240),
'rate_limit_per_hour' => env('MAILPOOL_DEFAULT_RATE_LIMIT_PER_HOUR', null),
'rate_limit_override' => (bool) env('MAILPOOL_DEFAULT_RATE_OVERRIDE', false),
],
];

View File

@ -1,13 +0,0 @@
<?php
return [
'base_domain' => env('BASE_DOMAIN', 'example.com'),
'sysmail_sub' => env('SYSMAIL_SUB', 'sysmail'),
'dkim_selector' => env('DKIM_SELECTOR', 'mwl1'),
'dkim' => [
'selector' => env('DKIM_SELECTOR', 'mwl1'),
'bits' => (int) env('DKIM_BITS', 2048),
],
];