option('ui'); $mail = $this->option('mail'); $webmail = $this->option('webmail'); $ssl = (bool)(int)$this->option('ssl'); @mkdir(self::STATE_DIR, 0755, true); foreach (['ui', 'mail', 'webmail'] as $key) { file_put_contents(self::STATE_DIR . "/{$key}", 'pending'); } $domains = ['ui' => $ui, 'mail' => $mail, 'webmail' => $webmail]; $allOk = true; // DNS prüfen foreach ($domains as $key => $domain) { if (!$domain) { file_put_contents(self::STATE_DIR . "/{$key}", 'skip'); continue; } file_put_contents(self::STATE_DIR . "/{$key}", 'running'); $hasDns = checkdnsrr($domain, 'A') || checkdnsrr($domain, 'AAAA'); if (!$hasDns) { file_put_contents(self::STATE_DIR . "/{$key}", 'nodns'); $allOk = false; } } if (!$allOk) { file_put_contents(self::STATE_DIR . '/done', '0'); Setting::set('ssl_configured', '0'); return self::SUCCESS; } // Nginx-Vhosts + optionales SSL via mailwolt-apply-domains // Das Script erstellt erst die Vhosts (mit ACME-Location), dann certbot --webroot $helper = '/usr/local/sbin/mailwolt-apply-domains'; $out = shell_exec(sprintf( 'sudo -n %s --ui-host %s --webmail-host %s --mail-host %s --ssl-auto %d', escapeshellarg($helper), escapeshellarg($ui), escapeshellarg($webmail), escapeshellarg($mail), $ssl ? 1 : 0, )); // Shell-Script schreibt per-Domain-Status selbst in die State-Dateien. // Fallback: Domains die noch auf running/pending stehen auf error setzen. foreach (['ui', 'mail', 'webmail'] as $key) { $status = trim((string) @file_get_contents(self::STATE_DIR . "/{$key}")); if ($status === 'running' || $status === 'pending') { file_put_contents(self::STATE_DIR . "/{$key}", 'error'); } } // done-Datei: Shell-Script schreibt "1"/"0"; Fallback wenn Script abstürzte. $doneVal = trim((string) @file_get_contents(self::STATE_DIR . '/done')); if ($doneVal === '') { file_put_contents(self::STATE_DIR . '/done', '0'); $doneVal = '0'; } // ssl_configured anhand tatsächlich ausgestellter LE-Zertifikate bestimmen $hasAnyCert = false; foreach ($domains as $domain) { if ($domain && is_dir("/etc/letsencrypt/live/{$domain}")) { $hasAnyCert = true; break; } } Setting::set('ssl_configured', $hasAnyCert ? '1' : '0'); // SESSION_SECURE_COOKIE wird nicht automatisch gesetzt — // nginx leitet HTTP→HTTPS weiter, Secure-Flag wird im Admin gesetzt return self::SUCCESS; } private function updateEnv(string $path, string $key, string $value): void { $content = @file_get_contents($path) ?: ''; $pattern = '/^' . preg_quote($key, '/') . '=[^\r\n]*/m'; $line = $key . '=' . $value; if (preg_match($pattern, $content)) { $content = preg_replace($pattern, $line, $content); } else { $content .= "\n{$line}"; } file_put_contents($path, $content); } }