argument('domain'); $email = (string)$this->option('email'); $self = (bool)$this->option('self-signed'); $this->certPath = "{$this->sslDir}/cert.pem"; $this->keyPath = "{$this->sslDir}/key.pem"; if (!is_dir($this->sslDir)) { @mkdir($this->sslDir, 0750, true); @chgrp($this->sslDir, 'www-data'); } if ($self) { return $this->issueSelfSigned($domain); } // Versuche Let's Encrypt – bei Fehler fallback self-signed $rc = $this->issueLetsEncrypt($domain, $email); if ($rc !== 0) { $this->warn('Let’s Encrypt fehlgeschlagen – erstelle Self-Signed als Fallback…'); return $this->issueSelfSigned($domain); } return $rc; } private function issueLetsEncrypt(string $domain, string $email): int { if (empty($email)) { $this->error('Für Let’s Encrypt ist --email erforderlich.'); return 2; } // Webroot sicherstellen (Nginx-Standort ist im Installer bereits konfiguriert) @mkdir('/var/www/letsencrypt', 0755, true); $cmd = [ 'bash','-lc', // non-interactive, webroot challenge "certbot certonly --webroot -w /var/www/letsencrypt -d {$domain} ". "--email ".escapeshellarg($email)." --agree-tos --no-eff-email --non-interactive --rsa-key-size 2048" ]; $p = new Process($cmd, null, ['PATH' => getenv('PATH') ?: '/usr/bin:/bin']); $p->setTimeout(600); $p->run(function($type,$buff){ $this->output->write($buff); }); if (!$p->isSuccessful()) { $this->error('Certbot-Fehler.'); return 1; } // Pfade vom Certbot-Store $leBase = "/etc/letsencrypt/live/{$domain}"; $fullchain = "{$leBase}/fullchain.pem"; $privkey = "{$leBase}/privkey.pem"; if (!is_file($fullchain) || !is_file($privkey)) { $this->error("LE-Dateien fehlen unter {$leBase}"); return 1; } // In unsere Standard-Pfade kopieren (Nginx zeigt bereits darauf) if (!@copy($fullchain, $this->certPath) || !@copy($privkey, $this->keyPath)) { $this->error('Konnte Zertifikate nicht in /etc/mailwolt/ssl kopieren.'); return 1; } @chown($this->certPath, 'root'); @chgrp($this->certPath, 'www-data'); @chmod($this->certPath, 0640); @chown($this->keyPath, 'root'); @chgrp($this->keyPath, 'www-data'); @chmod($this->keyPath, 0640); // Nginx reload $reload = new Process(['bash','-lc','systemctl reload nginx']); $reload->run(); $this->info('Let’s Encrypt Zertifikat gesetzt und Nginx neu geladen.'); return 0; } private function issueSelfSigned(string $domain): int { $cfgPath = "{$this->sslDir}/openssl.cnf"; $cfg = <<keyPath} -out {$this->certPath} -config {$cfgPath}" ]; $p = new Process($cmd); $p->setTimeout(60); $p->run(function($t,$b){ $this->output->write($b); }); if (!$p->isSuccessful()) { $this->error('Self-Signed Erstellung fehlgeschlagen.'); return 1; } @chown($this->certPath, 'root'); @chgrp($this->certPath, 'www-data'); @chmod($this->certPath, 0640); @chown($this->keyPath, 'root'); @chgrp($this->keyPath, 'www-data'); @chmod($this->keyPath, 0640); @chmod($this->sslDir, 0750); $reload = new Process(['bash','-lc','systemctl reload nginx']); $reload->run(); $this->info('Self-Signed Zertifikat erstellt und Nginx neu geladen.'); return 0; } }