Wer eine eigene Website oder auch eine Nextcloud-Instanz betreibt, der sollte auch großen Wert auf Sicherheit legen. In der heutigen Zeit gehört dabei HTTPS zum Sicherheits-Standard, wenn es um die verschlüsselte Übertragung von Daten im Internet geht.
Um die eigene Seite mittels HTTPS abzusichern, ist zunächst einmal ein SSL-Zertifikat notwendig. Früher musste man sich ein solches Zertifikat von einer Zertifizierungsstelle für viel Geld kaufen. Im Jahr 2015 trat jedoch Let’s Encrypt auf den Plan – eine Zertifizierungsstelle, die kostenlos Zertifikate für TLS anbietet, um damit verschlüsselte Verbindungen im Web zum Standard zu machen. Gerade im privaten Bereich hat sich Let’s Encrypt zu einem de-facto Standard entwickelt.
Seitdem kann sich jedermann selbst Zertifikate für HTTPS ausstellen lassen. Dazu wird lediglich ein Let’s Encrypt Client benötigt, der die eigentliche Generierung der Zertifikate übernimmt. In meinen Tutorials habe ich bisher immer Certbot als Client für Let’s Encrypt empfohlen, da dieses Programm in den Paketquellen fast aller Distributionen enthalten ist. Dennoch könnte sich genau dieser Umstand als Nachteil erweisen. So schaltet Let’s Encrypt aus Sicherheitsgründen das Validierungsverfahren „TLS-SNI-01“ bald ab. Nutzer von Debian laufen bald Gefahr, dass die Zertifikate nicht mehr erneuert werden können, da die Version von Certbot in Debian Stable zu alt ist und keine anderen Validierungsmethoden unterstützt (siehe hier).
Ein alternativer Let’s Encrypt Client ist acme.sh. Wie der Name bereits vermuten lässt, handelt es sich hierbei um ein reines Shell-Skript, welches die Generierung der Zertifikate übernimmt. Man ist damit nicht mehr von Programmen in den Paketquellen der Linux-Distributionen abhängig. Darüber hinaus ist acme.sh ein sehr fortschrittlicher Client, der bisher alle Features von Let’s Encrypt unterstützt. Grund genug, die diesen Let’s Encrypt Client einmal genauer anzusehen.
Der Artikel basiert dabei auf Ubuntu Server 18.04 LTS, alle gezeigten Schritte sollten sich aber auch auf anderen Distributionen umsetzen lassen. Als Webserver kommt nginx zum Einsatz.
Update-Historie (letztes Update 18.06.2021)- 18.06.2021:
- Konfiguration acme.sh, so dass immer Zertifikate über Let’s Encrypt bezogen werden.
- 03.02.2020:
- Cipher Suite DHE-RSA-AES256-GCM-SHA384 entfernt.
- 17.08.2019:
- acme.sh sollte nicht mit Root-Rechten ausgeführt werden, daher wird für die Ausführung von acme.sh ein spezieller User angelegt.
- 24.07.2019:
- Anpassungen für TLSv1.3 (ssl_ciphers und ssl_ecdh_curve).
- 15.06.2019:
- ECDHE-RSA-AES256-SHA384 aus den ssl_ciphers entfernt (wird beim Qualys SSL Labs Test als „weak“ eingestuft).
- 18.05.2019:
- Hinweis hinzugefügt, dass bei der Generierung der Zertifikate am besten Copy&Paste und „Suchen & Ersetzen“ genutzt wird.
- 18.02.2019:
- Hinweis für Meldung „-bash: /home/user/.acme.sh/acme.sh.env: Permission denied“ hinzugefügt.
- 13.02.2019:
- Hinweis für die Berechtigungen des Verzeichnisses /var/www/letsencrypt hinzugefügt.
- 11.02.2019:
- Anleitung zum Upgrade von acme.sh hinzugefügt.
- Hinweis auf Überschreiben der Crontab durch Installation von acme.sh hinzugefügt/Sichern der bestehenden Crontab.
- 09.02.2019:
- Hinweis auf neuen Artikel zum Umstieg von Certbot auf acme.sh hinzugefügt.
Inhalt
Installation von acme.sh
Es handelt sich bei acme.sh nur um ein Skript, jedoch kann es in gewisser Art installiert werden. Die Installation beinhaltet hauptsächlich die Einrichtung eines Cronjobs zur automatischen Erneuerung ausgestellter Zertifikate.
acme.sh sollte nicht mit Root-Rechten ausgeführt werden, daher legen wir einen speziellen User an und fügen diesen der Gruppe www-data hinzu:
adduser letsencrypt usermod -a -G www-data letsencrypt
Der User braucht nun die Berechtigungen, um nginx später ohne Passwort neu laden zu können:
visudo
Am Ende wird folgende Zeile hinzugefügt:
letsencrypt ALL=NOPASSWD: /bin/systemctl reload nginx.service
Für die Installation von acme.sh wechseln wird nun den User:
su - letsencrypt
Hinweis: Wenn ein bereits bestehender User für die Generierung der Zertifikate genommen wird, sollte nun kontrolliert werden, ob bereits Conjobs für diesen User angelegt wurden, da acme.sh bei der Installation sämtliche bereits bestehenden Conjobs überschreibt.
Falls bereits Cronjobs eingerichtet sind, dann solltet ihr euch daher vorher die aktuelle Crontab sichern:
crontab -l > crontab.bak
Nach der Installation von acme.sh können mittels dieser Datei die „alten“ Cronjobs wieder mit contab -e hinzugefügt werden.
Diese Installation besteht eigentlich nur in der Ausführung des Skripts mit bestimmten Parametern und gestaltet sich recht einfach. Dazu gibt es eine spezielle Seite, die das Skript zur Installation beinhaltet: https://get.acme.sh.
curl https://get.acme.sh | sh
Hinweis: Es ist immer gefährlich, eine unbekannte Quelle direkt in die Shell zu pipen, da man nie so genau weiß, was diese Quelle (in diesem Fall das Skript genau ausführt). Man sollte sich die Quelle (in diesem Fall https://get.acme.sh) vor der Ausführung des Befehle genau ansehen und überprüfen, ob hier nichts verdächtiges passiert. Für wen das Pipen auf die Shell nicht in Frage kommt, der findet noch ein paar alternative Installationsmöglichkeiten auf der Wiki-Seite des GitHub-Projekts.

Nach der Installation von acme.sh einmal mit dem entsprechenden User ab- und wieder anmelden:
exit su - letsencrypt
Nun wird acme.sh noch gleich so konfiguriert, dass standardmäßig Zertifikate von Let’s Encrypt bezogen werden (ab dem 01.08.2021 nutzt acme.sh als Standard Zertifikate von ZeroSSL – siehe hier).
Dazu wird vor der Ausstellung des ersten Zertifikats folgender Befehl benötigt:
acme.sh --set-default-ca --server letsencrypt
Nach der Installation muss das Terminal einmal geschlossen und wieder geöffnet werden. Alternativ kann man den Rechner auch einfach neu starten.
Damit ist die Installation bereits abgeschlossen, so dass wir wieder auf den normalen User wechseln können:
exit
Als nächstes wird das System auf die Verwendung von SSL-Zertifikaten vorbereitet.
Vorbereitung des Systems
Zunächst richten wir die benötigten Verzeichnis ein, die später für die Zertifiakt-Generierung benötigt werden. Ebenfalls passen wir gleich die Berechtigungen entsprechend an:
mkdir -p /var/www/letsencrypt/.well-known/acme-challenge chown -R www-data:www-data /var/www/letsencrypt chmod -R 775 /var/www/letsencrypt mkdir -p /etc/letsencrypt/meinedomain.de chown -R www-data:www-data /etc/letsencrypt chmod -R 775 /etc/letsencrypt
Ich nutze hier immer einen Unterordner, der mit der Domain übereinstimmt, für welche die Zertifikate ausgestellt werden sollen (in diesem Beispiel einfach meinedomain.de).
Als nächstes muss der Webserver in der Lage sein, über HTTP (Port 80) im Unterverzeichnis /.well–known/acme–challenge für Let’s Encrypt erreichbar zu sein. Im virtuellen Host für die entsprechende Domain könnte dies dann folgendermaßen aussehen:
server { listen 80 default_server; listen [::]:80 default_server; server_name meinedomain.de 192.168.178.60; root /var/www; location ^~ /.well-known/acme-challenge { default_type text/plain; root /var/www/letsencrypt; } }
Zertifikate mit acme.sh erzeugen
Nach den Vorbereitungen sind wir nun soweit, dass wir Zertifikate über acme.sh ausstellen lassen können.
Ich gehe im folgenden davon aus, dass auf dem System bereits nginx als Webserver installiert und eingerichtet wurde. Für die Generierung der Zertifikate wird daher der sog. Webroot-Modus genutzt. acme.sh unterstützt allerdings auch andere Modi (z.B. einen Standalone-Modus, wenn kein Webserver auf dem System läuft). Es gibt auch einen speziellen Modus für nginx, allerdings werden hier die virtuellen Hosts vom Webserver bei der Generierung/Erneuerung der Zertifikate kurzzeitig verändert/ausgetauscht. Da ich meine vHosts lieber unangetastet lassen möchte, nutze ich daher immer nur den Webroot-Modus.
Zunächst wechseln wir auf den speziell angelegten User:
su - letsencrypt
Ein Zertifikat wird durch einen einzigen Befehl erzeugt.
Tipp: Am besten übernimmt man den Befehl mittels Copy&Paste in einen beliebigen Text-Editor, mit dem man dann die Domain mit „Suchen und Ersetzen“ einfach durch die tatsächlich verwendete Domain einfügt. Auf diese Weise kann man Tippfehler vermeiden.
acme.sh --issue -d meinedomain.de --server letsencrypt --keylength 4096 -w /var/www/letsencrypt --key-file /etc/letsencrypt/meinedomain.de/key.pem --ca-file /etc/letsencrypt/meinedomain.de/ca.pem --cert-file /etc/letsencrypt/meinedomain.de/cert.pem --fullchain-file /etc/letsencrypt/meinedomain.de/fullchain.pem --reloadcmd "sudo /bin/systemctl reload nginx.service"
Mit den Parametern werden die Details zu Generierung der Zertifikate angegeben:
-
-d meinedomain.de
Gibt die Domain an, für die das Zertifikat erzeugt werden soll.
-
--server letsencrypt
Gibt an, dass die Zertifikate über Let’s Encrypt bezogen werden sollen. Diese Option ist an dieser Stelle optional, wenn das Standard-Verhalten von acme.sh bereits vorher angepasst wurde (s.o.).
-
--keylength 4096
Gibt die Schlüssellänge des RSA-Zertifikats an. Standardmäßig werden hier 2048 Bit verwendet. Das ist in der Regel ausreichend, jedoch sollte man für erhöhte Sicherheit auf eine Schlüssellänge von 4096 Bit setzen.
-
-w /var/www/letsencrypt
Gibt das Verzeichnis an, in dem die Challenge-Dateien gespeichert werden. Dies muss das Verzeichnis sein, welches bei nginx als root Verzeichnis für /.well-known/acme-challenge angegeben wurde (im jeweiligen virtuellen Host).
- acme.sh speichert die Zertifikat-Dateien im Verzeichnis ~/.acme.sh/meinedomain.de. Es wird davon abgeraten, diese Dateien direkt in den virtuellen Hosts des Webservers zu referenzieren. Aus diesem Grund wird mit den Parametern –key-file , –ca-file , –cert-file und –fullchain-file die Speicherorte der Dateien angegeben, wo die entsprechenden Dateien „installiert“ werden sollen. Nur diese Dateien werden dann später in den vHosts von nginx eingebunden.
-
--reloadcmd
Gibt den Befehl an, der nach erfolgreicher Ausstellung/Erneuerung der Zertifikate ausgeführt werden soll. Damit der Webserver die neuen Zertifikate korrekt einbinden kann, wird nginx hier einfach kurz neu gestartet. Wenn hier mehrere Befehle ausgeführt werden sollen, sind diese durch ein Semikolon zu trennen.
Nach dem Generieren können alle von acme.sh ausgestellten Zertifikate auf dem System durch folgenden Befehl angezeigt werden:
acme.sh --list
Ebenfalls wird durch diesen Befehl die Gültigkeitsdauer der Zertifikate angezeigt (dazu später mehr).
Nun wechseln wir wieder auf den normalen User zurück:
exit
Diffie-Hellman-Parameter erzeugen
Die Zertifikate selbst sind der wichtigste Punkt, wenn es um die Verschlüsselung der Verbindung über HTTPS geht. Um die Sicherheit noch weiter zu erhöhen, sollten noch sog. Diffie-Hellman-Parameter genutzt werden. Ohne nun die technischen Details zu beleuchten, geht es um einen sicheren Schlüsselaustausch bei Verbindungsaufbau. Die Generierung des Schlüssels muss dabei nur einmal erfolgen.
Achtung: Die Erzeugung der Diffie-Hellman-Parameter dauert gerade auf schwächerer Hardware sehr lange. Hier muss man bis zur Fertigstellung u.U. mehrere Stunden warten. In diesem Fall kann auch eine Schlüssel mit „nur“ 2048 Bit berechnet werden (die Zahl des zweiten Befehls gibt hierbei die Länge des Schlüssels in Bit an). Auf stärkerer Hardware ist allerdings eine Schlüssellänge von 4096 Bit empfehlenswert.
mkdir -p /etc/nginx/dhparams openssl dhparam -out /etc/nginx/dhparams/dhparams.pem 4096
Einbinden der Zertifikate in nginx
Die Zertifikate können nun einfach mit nginx verwendet werden. Ich beschränke mich hier auf das reine Einbinden der Zertifikate und der entsprechenden SSL-Einstellungen.
Damit das Ganze übersichtlich bleibt, lagere ich die SSL-Settings immer in eine spezielle Datei aus, die dann später in die virtuellen Hosts eingebunden wird. Auf diese Weise sind alle Einstellungen bzgl. SSL nur an einem Ort zu finden.
Dazu legen wir zunächst eine neue Datei an:
mkdir -p /etc/nginx/snippets nano /etc/nginx/snippets/ssl.conf
Hier werden dann ausschließlich die Anweisungen für SSL aufgeführt:
# Certificates used ssl_certificate /etc/letsencrypt/meinedomain.de/fullchain.pem; ssl_certificate_key /etc/letsencrypt/meinedomain.de/key.pem; # This should be ca.pem (certificate with the additional intermediate certificate) # See here: https://certbot.eff.org/docs/using.html ssl_trusted_certificate /etc/letsencrypt/meinedomain.de/ca.pem; # Diffie-Hellman parameter, recommended 4096 bits ssl_dhparam /etc/nginx/dhparams/dhparams.pem; # Not using TLSv1 will break: # Android <= 4.4.40 # IE <= 10 # IE mobile <=10 # Removing TLSv1.1 breaks nothing else! # TLSv1.3 is not supported by most clients, but it should be enabled. ssl_protocols TLSv1.2 TLSv1.3; # Cipher suite from https://cipherli.st/ # Max. security, but lower compatibility ssl_ciphers 'TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384'; # Cipher suite from https://wiki.mozilla.org/Security/Server_Side_TLS #ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; # (Modern) cipher suite from https://mozilla.github.io/server-side-tls/ssl-config-generator/ #ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; # Use multiple curves. ssl_ecdh_curve secp521r1:secp384r1; # Server should determine the ciphers, not the client ssl_prefer_server_ciphers on; # OCSP Stapling # fetch OCSP records from URL in ssl_certificate and cache them ssl_stapling on; ssl_stapling_verify on; resolver 192.168.178.1; # SSL session handling ssl_session_timeout 24h; ssl_session_cache shared:SSL:50m; ssl_session_tickets off;
Neben dem Einbinden der eigentlichen Zertifikate dienen alle weiteren Anweisung ebenso der Sicherheit/Verschlüsselung. Daher bitte auch die Kommentare in der Datei beachten.
Im jeweiligen virtuellen Host für HTTPS ist dann einfach diese ssl.conf einzubinden:
server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name meinedomain.de 192.168.178.60; include /etc/nginx/snippets/ssl.conf; # # Here you would add the statements for some web applications, e.g. Nextcloud. # }
Wichtig: Die SSL-Anweisungen dürfen nicht doppelt im server-Block für HTTPS aufgeführt werden. Wenn hier bereits Optionen angegeben sind, die ebenfalls in der Datei ssl.conf aufgeführt sind, dann sind diese im server-Block für HTTPS zu entfernen.
Nach einem Neustart des Webservers sollten die Zertifikate korrekt eingebunden worden sein:
service nginx restart
Überprüfung der Zertifikate
Abschließend lohnt eine Überprüfung der Zertifikate. Hierzu ist der SSL Server Test von Qualys SSL Labs gut geeignet. Mit der gezeigten Konfiguration sollte ein Rating mit A+ und 100% in allen Kategorien erreicht werden:

Falls hier eine niedrigere Bewertung angezeigt werden sollte, liegt dies vermutlich an der SSL-Konfiguration des Webservers. In diesem Fall sollten die entsprechenden Anweisungen der Datei ssl.conf nochmals kontrolliert werden.
Erneuerung der Zertifikate
Die Zertifikate von Let’s Encrypt sind nur für die Dauer von 90 Tagen gültig (Begründung siehe hier) und müssen anschließend erneuert werden.
Bei der Installation von acme.sh wurde ein Cronjob angelegt, der regelmäßig prüft, ob Zertifikate erneuert werden müssen und diese Erneuerung dann ggf. automatisch ausführt. Im Grunde genommen muss man sich daher gar nicht weiter um die Zertifikate kümmern.
Dennoch sollte man nach dem initialen Ausstellen der Zertifikate und Ablauf der 90 Tage kontrollieren, ob die automatische Erneuerung auch wirklich durchgeführt wurde.
Die Gültigkeitsdauer der installierten Zertifikate kann wieder mit folgendem Befehl ermittelt werden:
su - letsencrypt acme.sh --list
Upgrade von acme.sh
Für acme.sh werden regelmäßig auch Updates veröffentlicht (siehe GitHub Release-Page). In diesem Fall kann das Skript mit nur einem Befehl auf den neusten Stand gebracht werden:
su - letsencrypt acme.sh --upgrade
Das Reizvolle daran ist nun, dass man diese Updates komplett ohne Abhängigkeiten von den Paketquellen der jeweiligen Distributionen einspielen kann.
Fazit
acme.sh macht als Let’s Encrypt Client einen sehr soliden Eindruck. Die Bedienung gestaltet sich recht einfach und da es sich um ein reines Shell Skript handelt, ist man unabhängig von Programmversionen in den Paketquellen einzelner Linux-Distributionen. Ebenfalls wird automatisch ein Cronjob für die Erneuerung der Zertifikate angelegt, so dass man sich nach der ersten Generierung der Zertifikate nicht mehr um deren Erneuerung kümmern muss. Aus genau diesen Gründen werde ich in Zukunft auch acme.sh als Let’s Encrypt Client empfehlen.
Abschließend noch ein Hinweis für Webserver-Admins, die noch einen anderen Let’s Encrypt Client verwenden und auf acme.sh umsteigen wollen: Der nächste Artikel hier im Blog wird den Umstieg zu acme.sh im Detail beleuchten…
Update: Der Artikel zum Umstieg von Certbot auf acme.sh ist online: Let’s Encrypt: Umstieg von Certbot auf acme.sh (nginx)
Weiterführende Artikel
- Nextcloud auf Ubuntu Server 18.04 LTS mit nginx, MariaDB, PHP, Let’s Encrypt, Redis und Fail2ban
- Ubuntu Server 18.04 LTS als Hyper-V Gastsystem installieren und optimal einrichten
Hallo Jan,
wie würde so etwas aussehen, wenn man 2-3 Webseiten mit unterschiedlichen Domain am laufen hat auf einem Server?
Gruß Danny
Hi Danny,
das ist ganz einfach: Für die weiteren Domains einfach weitere Zertifikate ausstellen lassen, pro Webseite dann ein vHost und hier die Zertifikate entsprechend einbinden.
Man kann auch mehrere Domains in ein Zertifikat „zusammen fassen“ (dann einfach beim Aufruf von acme.sh den Parameter „-d“ mehrfach angeben), das mache ich aber persönlich nicht, da ich gerne für jede Domain ein Zertifikat habe, welches ich dann auch separat verwalten kann.
Gruß,
Jan
Hallo!
Vielen Dank für die ausführtliche Anleitung. Ich bin diese Punkt für Punkt durchgegangen, um Zertifikate für meine Nextcloud zu erhalten. Leider klappte es nicht.
Ein Problem, das ich lösen konnte war, dass man zur Benutzung der acme.sh zuerst eine Emailadresse hinterlegen muss, bevor man ihren Befehl ausführen kann.
Was ich aber nicht verstehe, ist folgendes:
„Als nächstes muss der Webserver in der Lage sein, über HTTP (Port 80) im Unterverzeichnis /.well–known/acme–challenge für Let’s Encrypt erreichbar zu sein. Im virtuellen Host für die entsprechende Domain könnte dies dann folgendermaßen aussehen:
[…]“
Mir ist nicht klar, was der virtuelle Host ist. Nach einiger Recherche, habe ich folgendes ausgeführt:
mkdir /etc/nginx/sites-available/
nano /etc/nginx/sites-available/meine.domain.conf
und ihren server {…}-Block dort eingefügt.
Dann stolperte ich noch über folgendes:
„Im jeweiligen virtuellen Host für HTTPS ist dann einfach diese ssl.conf einzubinden:“
In welche Datei gehört nun dieser server {…}-Block?
Gruß
Frank
Mit freundlichem
Hi Frank,
bei acme.sh musste ich noch nie eine Mail-Adresse hinterlegen, das scheint dann wenn neu zu sein.
Virtuelle Hosts sind die Dateien, die bestimmen, was der Webserver ausliefert. Diese lege ich immer in das Verzeichnis /etc/nginx/conf.d, du kannst aber auch das Verzeichnis /etc/nginx/sites-enabled nutzen. Das wird bei dir vermutlich der Fehler sein, wenn in „sites-available“ werden die vHosts nicht geladen, sondern quasi nur geparkt.
Gruß,
Jan
Hallo,
zunächst: vielen Dank für Ihre Anleitungen, sie helfen mir sehr.
Seit ein paar Tagen erreiche ich meine Nextcloud nicht mehr per Browser (keine sichere Verbindung). Ich habe also diese Anleitung angewandt, habe jedoch keinen Erfolg.
Beim Abrufen der Zertifikate erscheint folgende Meldung:
[Mon Oct 17 21:04:03 UTC 2022] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Mon Oct 17 21:04:03 UTC 2022] Single domain=’struck.dedyn.io‘
[Mon Oct 17 21:04:03 UTC 2022] Getting domain auth token for each domain
[Mon Oct 17 21:04:06 UTC 2022] Getting webroot for domain=’struck.dedyn.io‘
[Mon Oct 17 21:04:06 UTC 2022] Verifying: struck.dedyn.io
[Mon Oct 17 21:04:07 UTC 2022] Pending, The CA is processing your order, please just wait. (1/30)
[Mon Oct 17 21:04:10 UTC 2022] struck.dedyn.io:Verify error:217.229.219.81: Fetching http://struck.dedyn.io/.well-known/acme-challenge/9SsyXqUNBibFYZz4y7hYz7_8OS97NtyDtD_2ssg6zC8: Connection refused
[Mon Oct 17 21:04:11 UTC 2022] Please check log file for more details: /home/acmeuser/.acme.sh/acme.sh.log
Zugriffsrechte und Ordnerzugehörigkeiten sind kontrolliert und funktionieren (Testdatei kann erstellt, jedoch nicht aufgerufen werden).
Ein weiteres Problem taucht nun auf, wenn ich versuche NGINX neu zu starten. Hier erscheint die Meldung:
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Mon 2022-10-17 21:09:25 UTC; 4s ago
Docs: https://nginx.org/en/docs/
Process: 9530 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=1/FAILURE)
Oct 17 21:09:24 struckloud systemd[1]: Starting nginx – high performance web server…
Oct 17 21:09:24 struckloud nginx[9530]: nginx: [emerg] a duplicate default server for 0.0.0.0:80 in /etc/nginx/conf.d/http.conf:2
Oct 17 21:09:25 struckloud systemd[1]: nginx.service: Control process exited, code=exited, status=1/FAILURE
Oct 17 21:09:25 struckloud systemd[1]: nginx.service: Failed with result ‚exit-code‘.
Oct 17 21:09:25 struckloud systemd[1]: Failed to start nginx – high performance web server.
Die Config-Datei sieht wie folgt aus:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name struck.dedyn.io 192.168.178.60;
root /var/www;
location ^~ /.well-known/acme-challenge {
default_type text/plain;
root /var/www/letsencrypt;
}
}
Ich hoffe, sie können mir helfen.
Vielen Dank und viele Grüße
Hi Sebastian,
wenn ein Kommentar nicht gleich erscheint, ist dieser vermutlich im Spam-Filter hängen geblieben. Das kann schnell mal passieren, wenn z.B. Code im Kommentar enthalten ist. In diesem Fall muss ich den Kommentar manuell freigeben, daher kann es eine Weile dauern.
acme.sh kann nur funktionieren, wenn der Webserver läuft, was bei dir nicht der Fall ist. Hier sind zwei vHosts so definiert, dass diese auf Port 80 lauschen wollen. Hier kann immer nur ein vHost lauschen, daher musst du den anderen entfernen. Ich vermute bei dir mal stark, dass da noch der default-vHost aktiv ist (/etc/nginx/conf.d/default.conf). Diesen kannst du im Normalfall einfach löschen oder die Dateiendung ändern (z.B. auf ‚default.conf-disabled‘). Danach sollte nginx sich wieder starten lassen.
Bitte nun auch nicht die Zertifikats-Generierung zig mal hintereinander ausführen, da kommst du schnell an ein Rate-Limit und dann ist die Domain erst einmal für 7 Tage gesperrt. Bitte vorher manuell ausprobieren, ob die „acme-chellenge“ richtig funktioniert. Beschrieben ist das Ganze in diesem Abschnitt.
Gruß,
Jan
Hallo Jan,
tausend Dank für deine Antwort und entschuldige den Doppelpost. Ich war mir nur unsicher, ob ich versehentlich was falsch gemacht habe.
Habe nun alle conf-Dateien im conf.d-Ordner „abgeschaltet“. Ich schaffe es jedoch nicht, sowohl eine http.conf als auch eine https.conf wie von dir beschrieben nebeneinander laufen zulassen. Nginx meldet dann sofort wieder den Fehler. Wenn ich nur die http.conf aktiviere, dann funktioniert nginx. Was mache ich falsch?
Der Test mit der test-Datei funktioniert scheinbar auch nicht.
Soll ich hier die log-Datei posten?
Hi Sebastian,
ja, wenn nginx nicht läuft, kann der Webserver die Anfrage nicht beantworten, daher muss zunächst einmal nginx wieder starten.
Kann es sein, dass nginx bei dir nicht /etc/nginx/conf.d verwendet, sondern /etc/nginx/sites-enabled? Ist in diesem Ordner noch was vorhanden?
Was sagt bei dir „nginx -t“?
Gruß,
Jan
Die Ausgabe lautet wie folgt:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Der Ordner sites-enabled ist nicht vorhanden.
Was kann ich noch tun?
Hi Sebastian,
ein „service nginx restart“ und anschließendes „service nginx status“ gibt aus, dass der Webserver läuft?
Wenn dann der manuelle acme-challenge-Test nicht funktioniert, sollte in der /var/log/nginx/error.log ein Fehler aufgeführt werden, dass er die gesuchte Datei nicht finden kann. Das zeigt dann zumindest einmal, dass der Request auf beim Server ankommt. In diesem Fall stimmte dann die Konfiguration von nginx nicht.
Sollte im Logfile nichts dergleichen aufgeführt werden, kommt der Request gar nicht an und der Fehler liegt „davor“, z.B. bei der Firewall oder IP/DynDNS-Konfiguration.
Gruß,
Jan
Hallo Jan,
entschuldige, ich kann auf deine Antwort nicht mehr antworten, deswegen ein neuer Kommentar.
Ich frage mich immer noch, wie ich die beiden Einträge für Port 80 und 443 in eine Datei bekomme. Wenn ich zwei conf-Dateien habe, weigert sich nginx, mit oben beschriebener Fehlermeldung zu starten. Also habe ich aktuell nur die conf-Datei mit den Einträgen für Port 80.
Bin nun bei der acme.sh weitergekommen und erhalte folgenden Fehler:
… Can not write token to file …
Mir scheint, es geht dabei um den gleichen Fehler, wie bei dem Fehler das der Test mit der Text-Datei fehlschlägt. An welcher Stelle kann ich da nochmal gucken? Wieso ist die Test-Datei nicht erreichbar? Bin Schritt für Schritt alles durchgegangen.
Grüße, Sebastian
Hi Sebastian,
schau dir mal diesen Artikel an: Hier ist das Ganze noch mal Schritt für Schritt erklärt.
Prinzipiell muss es bei dir mehrere vHosts geben, die auf dem gleichen Port laufen sollen. Das ist der Grund warum nginx dann nicht startet.
Dieses „Cannot write token to file“ klingt eher wie ein Berechtigungsproblem. Stimmen die Berechtigungen des Users für Let’s Encrypt? Ist dieser Teil der Webserver-Gruppe?`
Gruß,
Jan
Hallo Jan,
ich gehe nachher alles nochmal Schritt für Schritt durch, aber wenn ich das richtig verstehe, werden hier auch vHost-configs erzeugt: /etc/nginx/conf.d/nextcloud.meinedomain.de.conf
/etc/nginx/conf.d/HttpGateway.conf
Verzeihe, ich vergaß: Der User für Let’s encrypt ist Teil der www-data Gruppe und die Ordner sind für die Gruppe schreibberechtigt.
Es tut mir leid, aber irgendwie komme ich da nicht weiter und weiß nicht woran es liegt.
Grüße,
Sebastian
Hi Sebastian,
wirklich nochmal alles Schritt für Schritt durchgehen würde ich hier auch empfehlen. Meistens wurde hier ein kleiner Schritt übersehen, der aber doch wichtig ist.
Und ja: Mehrere vHosts sind normal, der eine hört eben auf Port 80, der andere auf 443. Es dürfen nur keine zwei vHosts auf den gleichen Port und server_name hören.
Gruß,
Jan
Hallo Jan,
jetzt muss ich sicherheitshalber nochmal nachfragen: ich lasse also in der https.conf den Servername einfach weg? Was ist diese IP-Adresse eigentlich?
Viele Grüße und nochmal Danke für deine ganze Hilfe
Hi Sebastian,
nein, einen server_name sollte jeder vHost haben. Ich meinte nur, dass sich die vHosts irgendwie unterscheiden müssen, der server_name kann dazu genutzt werden. Das sollte für dich aber keine Rolle spielen, es geht ja nur um eine Domain, oder? Der server_name sollte immer zur Domain passen.
Gruß,
Jan
Hallo Jan,
ich habe irgendwas kaputt-konfiguriert. Bei nginx geht bei mir gar nichts mehr. Gibt es irgendwie einen eleganten Weg, das Grundsystem komplett neu aufzusetzen (dabei gleichzeitig Ubuntu zu updaten) und dabei die Dateien (auf einer Extra-Festplatte) und die Strukturen (Benutzer mit ihren Passwörtern etc.) zu behalten?
Danke für die Hilfe und viele Grüße
Hi Sebastian,
wenn nginx nicht mehr mag, kann das auch mal eine Kleinigkeit sein. Was ergibt der Befehl „nginx -t“?
Du kannst natürlich ein Backup aller Sachen machen, die auf dem Server laufen, Ubuntu neu aufsetzen und anschließend die Backups zurück spielen. Ich weiß nicht, was alles bei dir installiert ist, aber für Nextcloud können dazu beispielsweise diese Skripte verwendet werden.
Das Ziel des Backups muss natürlich etwas sein, was das Neuaufsetzen des Servers überlebt, z.B. eine externe Festplatte oder auf ein Samba-Share im Netzwerk.
Gruß,
Jan
Hallo Jan,
dir erst einmal ein frohes, neues und hoffentlich erfolgreiches Jahr! Ich habe hier Probleme mit meiner Jitsi-Installation, die ich erst im Oktober frisch aufgesetzt habe. Die Zertifikate konnten mit acme aus mir nicht wirklich erfindlichen Gründen nicht erneuert werden. Ich habe bisher versucht, den .well-known-Ordner mit dem samt /acme-challenge per rm -r sowie die Certs aus den Ordnern /etc/letsencrypt/rsa-certs sowie /etc/letsencrypt/ecc-certs zu löschen und die Zugriffsrechte neu zu setzen. Rufe ich anschließend den acme-User auf, um noch einmal Zertifikate zu beantragen, bleibt das Ganze erneut mit:
‚meinedomain:Verify error:xxxxx: Fetching http://meinedomain/.well-known/acme-challenge/xxxxxxxxxxxxxxxx: Connection refused‘ hängen.
der Mittelteil des Logs wirft dies hier aus:
[Fr 6. Jan 07:46:16 CET 2023] d=’meine-domain‘
[Fr 6. Jan 07:46:16 CET 2023] ok, let’s start to verify
[Fr 6. Jan 07:46:16 CET 2023] Verifying: meine-domain
[Fr 6. Jan 07:46:16 CET 2023] d=’meine-domain‘
[Fr 6. Jan 07:46:16 CET 2023] keyauthorization=’XXXXXX‘
[Fr 6. Jan 07:46:16 CET 2023] uri=’https://acme-v02.api.letsencrypt.org/acme/chall-v3/192943138627/SmyP4w‘
[Fr 6. Jan 07:46:16 CET 2023] _currentRoot=’/var/www/letsencrypt‘
[Fr 6. Jan 07:46:16 CET 2023] wellknown_path=’/var/www/letsencrypt/.well-known/acme-challenge‘
[Fr 6. Jan 07:46:16 CET 2023] writing token:XXXXXX to /var/www/letsencrypt/.well-known/acme-challenge/XXXXXX
[Fr 6. Jan 07:46:16 CET 2023] Changing owner/group of .well-known to www-data:www-data
[Fr 6. Jan 07:46:16 CET 2023] chown: changing ownership of ‚/var/www/letsencrypt/.well-known/acme-challenge/XXXXXX‘: Operation not permitted
chown: changing ownership of ‚/var/www/letsencrypt/.well-known/acme-challenge‘: Operation not permitted
chown: changing ownership of ‚/var/www/letsencrypt/.well-known‘: Operation not permitted
[Fr 6. Jan 07:46:16 CET 2023] chown: changing ownership of ‚/var/www/letsencrypt/.well-known/acme-challenge/XXXXXX‘: Operation not permitted
chown: changing ownership of ‚/var/www/letsencrypt/.well-known/acme-challenge‘: Operation not permitted
chown: changing ownership of ‚/var/www/letsencrypt/.well-known‘: Operation not permitted
[Fr 6. Jan 07:46:16 CET 2023] url=’https://acme-v02.api.letsencrypt.org/acme/chall-v3/192943138627/SmyP4w‘
[Fr 6. Jan 07:46:16 CET 2023] payload='{}‘
[Fr 6. Jan 07:46:16 CET 2023] POST
Hast du einen Tipp? Wie bekomme ich acme wieder zum Laufen? Oder wie kann ich es deinstallieren (muss ich das überhaupt) und stattdessen Certbot benutzen? Oder soll ich lieber alles platt machen und Jitsi – nun mit Ubuntu 22 LTS – installieren offenbar ist da die Zertifikatsanforderung mit Let’s Encrypt ja schon eingebaut. Es wäre nur schade um einige andere Konfigurationen, die ich auf dem jetzigen Server schon vorgenommen habe.
Vielen Dank und viele Grüße
Stefan
Hi Stefan,
eine sehr detaillierte Anleitung bzgl. acme.sh findest du im Artikel über Nextcloud. Vielleicht ist das ja hilfreich. Ich vermute aber mal ein Problem mit den Zugriffsrechten, bzw. die fehlende Zuordnung des Users für acme.sh zur Gruppe www-data.
Certbot kannst du natürlich auch verwenden, ich bevorzuge hier nach wie vor acme.sh, da hier keinerlei Abhängigkeiten bestehen (reines Bash-Skript).
Ich denke platt machen musst du den Server nicht, ein Update auf Ubuntu 22.04 LTS ist momentan noch nicht zwingend erforderlich. Dennoch hättest du nach diesem Upgrade dann wieder ein paar Jahre Ruhe.
Gruß,
Jan
Hallo Jan,
danke für deine Anwort. Leider komme ich trotzdem nicht weiter. Ich habe noch einmal alle Zugriffsrechte wie in deiner Beschreibung zugewiesen. Der Versuch, eine Text- und Testdatei in .well-known/acme-challenge/ über http zu öffnen, scheitert vielleicht auch daran, das offenbar die Umleitung auf https ein Hindernis darstellt, bei der Beantragung aber die acme-Shell erscheint dann später auch „Connection refused“. Was kann ich tun?
1. Redirect auf https rausnehmen (im weiteren Betrieb muss es aber doch auch über https funktionieren)?
2. Soll ich den letsencrypt- bzw. acme-User neu anlegen?
3. Den Ordner /var/www/letsencrypt/löschen? Darin befinden sich versteckt neben .well-known:
ls -all
total 12
drwxrwxr-x 3 www-data www-data 4096 Jan 13 16:35 .
drwxr-xr-x 4 www-data www-data 4096 Okt 6 18:31 ..
drwxrwxr-x 3 www-data www-data 4096 Jan 13 16:35 .well-known
(offenbar im Zusammenhang mit den fehlgeschlagenen Versuchen).
4. die acme.sh deinstallieren, um certbot zu nutzen. Ich habe das Gefühl, dass sich das in die Quere kommt.
Das nginx log gibt übrigens nach dem letzten Versuch von gestern Folgendes aus:
[emerg] 694#694: cannot load certificate „/etc/letsencrypt/rsa-certs/fullchain.pem“: BIO_new_file() failed (SSL: error:02001002:system library:fopen:No s>
Wie gesagt, es ist alles 3 Monate gelaufen. Erstaunlich, dass es bei der ersten Erneuerung der certs dann abschmiert.
Gruß Stefan
Hi Stefan,
also die letzte Fehlermeldung sieht so aus, als wenn das Zertifikat nicht mehr da wäre und nginx es nicht mehr finden könnte.
Alles löschen (acme-User, etc.) und neu anlegen wird wohl auch nichts bringen, denn hier ist ja nichts Spezielles dran.
Aber „Connection refused“ sieht so aus, als wenn die Verbindung (über Port 80?) blockiert werden würde. Hier also noch mal überprüfen:
Das wäre nun noch so die Punkte, wo ich mit der Fehlersuche beginnen würde.
Gruß,
Jan