nginx + Let’s Encrypt per acme.sh: Zertifikate automatisch
HTTPS ist heute Pflicht – das manuelle Zertifikatsmanagement aber nicht. acme.sh stellt Let’s-Encrypt-Zertifikate aus, legt sie direkt in deinen nginx-Serverblock und erneuert sie automatisch. So bekommst du gültige TLS-Zertifikate ohne Wartungsarbeit.
Warum acme.sh?
Let’s Encrypt ist der einfachste Weg zu kostenlosen TLS-Zertifikaten – aber das Ausstellen, Ablegen und Erneuern will trotzdem organisiert sein. Genau hier kommt acme.sh ins Spiel: ein reines Shell-Skript, das Zertifikate beantragt, auf Wunsch direkt in deinen nginx-Ordner legt und über den Cron täglich auf Ablauf prüft.
Der Vorteil gegenüber manuellem Vorgehen: Nach der Einrichtung passiert alles automatisch – du musst nur noch den Serverblock einmal richtig konfigurieren.
Konzept: ACME & Challenge-Typen
acme.sh spricht das ACME-Protokoll der Zertifizierungsstellen. Um zu beweisen, dass dir die Domain gehört, stehen mehrere Challenge-Typen zur Auswahl:
- Webroot – legt eine Prüfdatei unter
/var/www/html/.well-known/acme-challenge/ab (Port 80 muss erreichbar sein) - Standalone – acme.sh belegt kurzzeitig selbst Port 80 (nginx dabei stoppen!)
- nginx-Modus – acme.sh konfiguriert die Challenge automatisch über nginx
- DNS-API – legt einen TXT-Record per API an; einzige Option für Wildcard-Zertifikate
*.domain.de
Standard-Zertifizierungsstelle ist bei acme.sh inzwischen ZeroSSL. Da dieser Artikel Let’s Encrypt behandelt, stellen wir die Standard-CA um.
Voraussetzungen
Bevor es losgeht, sollten drei Dinge stimmen:
- DNS: Deine Domain zeigt per A-/AAAA-Record auf die IP des Servers
- nginx: läuft und bedient die Domain (mindestens auf Port 80)
- Firewall: Port 80 und 443 sind von außen erreichbar
Für die Zertifikate legen wir einen Ordner an:
sudo mkdir -p /etc/nginx/ssl
/etc/nginx braucht sudo.acme.sh installieren
acme.sh wird ins eigene Verzeichnis ~/.acme.sh installiert und richtet sich selbst einen Cron für die Erneuerung ein:
curl https://get.acme.sh | sh -s email=admin@meine.domain
Wer curl | sh vermeiden will, klont das Repository:
git clone https://github.com/acmesh-official/acme.sh.git
cd acme.sh
./acme.sh --install -m admin@meine.domain
Danach auf Let’s Encrypt umstellen und das Konto registrieren:
acme.sh --set-default-ca --server letsencrypt
acme.sh --register-account -m admin@meine.domain
--register-account verlangt Let’s Encrypt die Registrierung spätestens beim ersten Ausstellen.Zertifikat ausstellen
Die einfachste Variante bei laufendem nginx ist der Webroot-Modus – -w zeigt auf das DocumentRoot der Domain:
acme.sh --issue -d web.meine.domain -w /var/www/html
# mehrere Domains in einem Zertifikat (SAN):
acme.sh --issue -d meine.domain -d www.meine.domain -w /var/www/html
# Wildcard (nur mit DNS-API, z. B. Cloudflare):
acme.sh --issue -d "*.meine.domain" --dns dns_cf --server letsencrypt
Alternativen: --nginx (acme.sh erledigt die Challenge über nginx) oder --standalone (nginx kurz stoppen, Port 80 frei).
http://web.meine.domain/.well-known/acme-challenge/ im Browser öffnen.nginx & Zertifikatsinstallation
acme.sh legt die Zertifikate standardmäßig nur in ~/.acme.sh ab. Für nginx installieren wir sie an einen festen Ort und sorgen dafür, dass nginx nach jeder Erneuerung neu geladen wird:
acme.sh --install-cert -d web.meine.domain \
--key-file /etc/nginx/ssl/web.meine.domain.key \
--fullchain-file /etc/nginx/ssl/web.meine.domain.fullchain \
--reloadcmd "systemctl reload nginx"
Der Serverblock nutzt dann diese Pfade – inklusive HTTP→HTTPS-Weiterleitung:
server {
listen 80;
server_name web.meine.domain;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
http2 on;
server_name web.meine.domain;
ssl_certificate /etc/nginx/ssl/web.meine.domain.fullchain;
ssl_certificate_key /etc/nginx/ssl/web.meine.domain.key;
ssl_protocols TLSv1.2 TLSv1.3;
root /var/www/html;
index index.html;
}
Konfiguration prüfen und neu laden:
sudo nginx -t && sudo systemctl reload nginx
listen 443 ssl http2; veraltet – stattdessen listen 443 ssl; plus http2 on; verwenden. Ältere Versionen weiter mit listen 443 ssl http2;.Automatische Erneuerung
acme.sh installiert bei der Installation einen Cron, der täglich prüft, ob Zertifikate in weniger als 60 Tagen ablaufen – und sie dann erneuert. Der --reloadcmd sorgt dafür, dass nginx die neuen Dateien sofort lädt:
# manueller Test-Lauf (macht nichts kaputt):
acme.sh --cron
# Liste aller verwalteten Zertifikate:
acme.sh --list
# Erneuerung erzwingen (nur bei Bedarf!):
acme.sh --renew -d web.meine.domain --force
--staging-Server nutzen, erst dann die Produktion. --renew --force sparsam einsetzen.Betrieb & Absicherung
- Backup: Neben
/etc/nginx/sslgehört auch~/.acme.sh(mit Account- und CA-Infos) ins Backup – dann ist ein Umzug auf einen neuen Server problemlos möglich. - Rechte: Private Key nur für root lesbar halten:
sudo chmod 600 /etc/nginx/ssl/*.key - Prüfen: Nach der Einrichtung mit
curl -I https://web.meine.domainoder dem Browser testen; Uptime-Kuma überwacht danach dauerhaft. - Upgrade: acme.sh aktualisiert sich bei Cron-Läufen selbst – oder manuell mit
acme.sh --upgrade.
Häufige Probleme (FAQ)
| Problem | Lösung |
|---|---|
| Challenge schlägt mit 404 fehl | Webroot-Pfad prüfen, .well-known darf nicht per Rewrite blockiert werden; Port 80 muss offen sein |
| „Too many certificates“ | Rate Limit von Let’s Encrypt – 1 Woche warten oder mit --staging testen |
| Erneuerung findet nicht statt | Cron prüfen (crontab -l), acme.sh --cron manuell testen, --reloadcmd gesetzt? |
| Es kommt ZeroSSL statt Let’s Encrypt | acme.sh --set-default-ca --server letsencrypt ausführen |
| Wildcard wird abgelehnt | Wildcards funktionieren nur mit DNS-API-Challenge, nicht per Webroot |
| Zertifikat nach Server-Umzug ungültig | Altes Zertifikat entfernen und neu ausstellen lassen (--renew -d domain --force) |
Fazit
Mit acme.sh und nginx bekommst du ein Zertifikatssystem, das sich nach der Einrichtung selbst verwaltet: Ausstellen, Ablegen, Erneuern und nginx-Reload laufen automatisch. Übrig bleibt nur ein sauber konfigurierter Serverblock – und eine Domain, die dauerhaft unter HTTPS erreichbar ist.
~/.acme.sh + /etc/nginx/ssl gehören ins Backup.② Ohne
--reloadcmd lädt nginx neue Zertifikate nicht.③ Port 80 muss für die HTTP-Challenge offen bleiben.
④ Erst mit
--staging testen, dann produktion.