Dieser Artikel zeigt Euch, wie man eine eigene Webseite unter Ubuntu Server 24.04 LTS mit Hilfe des nginx Web-Servers und Let’s Encrypt einfach und kostenlos mit HTTPS absichern kann.
Diskussion
Transport Layer Security (kurz TLS) ist ein Verschlüsselungsverfahren zum sicheren Übertragen von Daten über öffentliche Netzwerke. Bekannter ist es immer noch unter dem alten Namen SSL (Secure Sockets Layer). TLS ist die Grundlage für das Übertragungsprotokoll HTTPS, einer Erweiterung des HTTP-Protokolls, das die Übertragung von Daten verschlüsselt.
Wenn Du in Deinem Web-Browser eine Webseite aufrufst, dann wird sie dir entweder per HTTPS oder aber HTTP übermittelt. Du erkennst das am Präfix der URL. Lautet dieser http://
, dann ist es eine HTTP-Verbindung, lautet er https://
, dann ist es eine HTTPS-Verbindung.
Da HTTP-Verbindungen in allen modernen Web-Browsern mittlerweile als potentiell unsicher gekennzeichnet werden, gibt es kaum noch öffentliche Webseiten ohne HTTPS. Aber warum ist das so?
-
HTTPS verschlüsselt den Datenverkehr zwischen dem Web-Browser des Anwenders und deiner Webseite. Niemand außer euch beiden kann also sehen, welche Daten ihr untereinander austauscht. Und was fast noch wichtiger ist, niemand kann diese Daten ändern. Der letzte Aspekt wird leider viel zu oft unterschätzt. Das Argument, dass die eigene Website nur statischen Inhalt anzeigt und keine Benutzerdaten erfragt, geht hier ins Leere. Stell dir vor, jemand fängt alle Anfragen für Deine Webseite ab und lenkt sie stattdessen auf eine andere Webseite mit kriminellem Inhalten um. Das ist nicht schön, mit HTTPS kannst Du dies zuverlässig unterbinden.
-
Die Datenschutzgrundverordnung (DSGVO) verpflichtet Webseiten-Betreiber, das eigene Angebot nach dem aktuellen Stand der Technik zu schützen (siehe Art. 32 DSGVO Sicherheit der Verarbeitung). HTTPS als ein Baustein in der Sicherheitsarchitektur kann ohne Zweifel als aktueller Stand der Technik betrachtet werden.
-
Die Unterstützung von HTTP/2 setzt in der Regel den Einsatz von TLS voraus.
-
Die Google-Suche bewertet Webseiten mit HTTPS tendenziell höher als Webseiten ohne HTTPS. Das hat natürlich Auswirkung auf das Suchergebnis unter Google.
Wen das nicht überzeugt, dem sei die Webseite https://doesmysiteneedhttps.com ans Herz gelegt.
Die Nutzung von HTTPS für die eigene Webseite muss nichts kosten und kann mit sehr geringem Aufwand implementiert werden. Im weiteren Verlauf dieses Blog-Artikels zeige ich euch, wie einfach das gehen kann.
Let’s Encrypt
Die Grundlage von HTTPS sind TLS-Zertifikate, die von einer vertrauenswürdigen Zertifizierungsstelle ausgegeben werden. Let’s Encrypt (zu deutsch: Lasst uns verschlüsseln) ist eine Zertifizierungsstelle, die kostenlose TLS-Zertifikate anbietet. Diese sind nur drei Monate gültig und werden durch Automation regelmäßig erneuert. Hauptsponsoren dieses Projekts sind unter anderem Amazon Web Services (AWS), Google Chrome, die Electronic Frontier Foundation (EFF), die Mozilla Foundation, Meta und Cisco Systems.
Grundlage für die automatische Bereitstellung und Aktualisierung von Zertifikaten durch Let’s Encrypt ist das sogenannte ACME-Protokoll (Automatic Certificate Management Environment Protocol), ein standardisiertes Internetprotokoll, das unter anderem prüft, ob der Anfragende auch wirklich die Kontrolle über eine Domäne hat.
Als Betreiber einer oder mehrerer Webseiten benötigt man lediglich einen ACME-kompatiblen Client und schon kann man bei Let’s Encrypt neue TLS-Zertifikate erfragen, und das kostenlos. Klingt gut, oder?
Los geht’s
Voraussetzung:
- Ein lauffähiger Ubuntu Server 24.04 LTS. Der Artikel Ubuntu Server 24.04 installieren enthält alle Informationen, die dafür notwendig sind.
Wir werden jetzt folgendes tun:
-
Die aktuelle Stable-Version von nginx unter Ubuntu Server 24.04 LTS installieren und so konfigurieren, dass eine Webseite unter http://www.beispiel.de abrufbar ist.
-
Den ACME-Client Certbot installieren und nginx so konfigurieren, dass unsere Webseite auch unter https://www.beispiel.de abrufbar ist.
-
Die nginx-Konfiguration weiter optimieren, indem wir das http2-Protokoll freischalten.
nginx installieren
Der nginx Web-Server ist ein Open Source-Projekt der amerikanischen Firma F5 Networks und unter der BSD-Lizenz lizenziert. Ursprünglich ein Projekt des russischen Software-Entwicklers Igor Sysoev, um den wachsenden Skalierungsbedarf der russischen Suchmaschine Rambler abzusichern, ist nginx heute nach Apache der weltweit zweit populärste Web-Server im Einsatz. nginx wird besonders gern als Reverse Proxy und zur Lastenverteilung (Load balancer) eingesetzt, nicht selten auch in Kombination mit dem altehrwürdigen Apache Web-Server.
Die Installation des offiziellen Ubuntu-Pakets für nginx werden wir nicht nutzen, da diese Version oft veraltet ist. Solltest Du nginx bereits installiert haben, kannst Du die Installation mit folgendem Befehl wieder entfernen:
$ sudo apt remove nginx
Jetzt installieren wir zunächst einige Voraussetzungen für nginx:
$ sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
Wir wollen die aktuelle Stable-Version von nginx installieren. Dazu musst Du zunächst das apt-Repository von nginx in Deinem Ubuntu-Server registrieren:
$ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
Mit diesem Befehl stellen wir sicher, dass die von nginx bereitgestellten Installationspakete genutzt werden und nicht die von Ubuntu:
$ echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" | sudo tee /etc/apt/preferences.d/99nginx
Als nächstes musst Du den offiziellen nginx-Signaturschlüssel importieren. Dieser wird für die Überprüfung des Installationspakets aus dem soeben registrierten apt-Repository benötigt.
$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
Ist es auch der richtige Signaturschlüssel?
$ gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
Das Ergebnis sollte so aussehen:
pub rsa4096 2024-05-29 [SC]
8540A6F18833A80E9C1653A42FD21310B49F6B46
uid nginx signing key <signing-key-2@nginx.com>
pub rsa2048 2011-08-19 [SC] [expires: 2027-05-24]
573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
uid nginx signing key <signing-key@nginx.com>
pub rsa4096 2024-05-29 [SC]
9E9BE90EACBCDE69FE9B204CBCDCD8A38D88A2B3
uid nginx signing key <signing-key-3@nginx.com>
Jetzt kannst Du nginx installieren:
$ sudo apt update && sudo apt install nginx
Der erste Befehl aktualisiert die Paketlisten auf unserem Ubuntu-Server, der zweite Befehl installiert nginx mit all seinen Abhängigkeiten.
Zum Starten von nginx tippe folgendes ein:
$ sudo systemctl start nginx
Für einen Autostart beim Booten Deines Servers tippe folgendes ein:
$ sudo systemctl enable nginx
nginx testen
nginx installiert eine Standard-Webseite, die auf alle HTTP-Anfragen reagiert.
Überprüfe dies zunächst lokal:
$ wget -S --spider localhost
Läuft nginx, dann bekommst Du eine Meldung wie diese hier:
Spider mode enabled. Check if remote file exists.
--2024-09-05 12:00:00-- http://localhost/
Resolving localhost (localhost)... 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:80... connected.
HTTP request sent, awaiting response...
HTTP/1.1 200 OK
Server: nginx/1.26.2
Date: Thu, 05 Sep 2024 12:00:00 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Mon, 12 Aug 2024 14:28:31 GMT
Connection: keep-alive
ETag: "66ba1c0f-267"
Accept-Ranges: bytes
Length: 615 [text/html]
Remote file exists and could contain further links,
but recursion is disabled -- not retrieving.
Für einen externen Test öffne die URL http://www.beispiel.de
in Deinen Web-Browser. Das Ergebnis sollte wie folgt aussehen:
Eine neue Webseite anlegen
Schauen wir uns zunächst die Installation von nginx genauer an:
-
Alle Konfigurationsdateien liegen standardmäßig unter
/etc/nginx/
. -
Die Standardkonfigurationsdatei lautet
/etc/nginx/nginx.conf
. -
Alle Konfigurationsdateien mit der Dateiendung
.conf
, die im Unterverzeichnis/etc/nginx/conf.d/
liegen, werden automatisch unterhalb deshttp
-Blocks in die Standardkonfigurationsdatei/etc/nginx/nginx.conf
eingebettet. Mit anderen Worten, für jede neue Webseite sollte man im Unterverzeichnis/etc/nginx/conf.d/
eine extra Konfigurationsdatei anlegen. -
Die Konfiguration der Standard-Webseite aus dem vorherigen Abschnitt ist in der Datei
/etc/nginx/conf.d/default.conf
gespeichert. -
Die Log-Datei für die Zugriffsanalyse liegt unter
/var/log/nginx/access.log
. Nginx schreibt dort Informationen über jede Client-Anfragen rein, unmittelbar nachdem die Anfrage verarbeitet wurde. -
Die Log-Datei für die Fehleranalyse liegt unter
/var/log/nginx/error.log
. Nginx schreibt dort Informationen über aufgetretene Probleme rein.
Um einen Blick auf die Log-Einträge zu werfen, kannst Du den tail-Befehl nutzen.
-
Mit
sudo tail -f /var/log/nginx/access.log
bekommst Du beispielsweise einen Live-Blick auf die letzten Einträge im Zugriffs-Log. -
Mit
sudo tail -f /var/log/nginx/error.log
bekommst Du beispielsweise einen Live-Blick auf die letzten Einträge im Fehler-Log.
Wir möchten jetzt unsere eigene Webseite mit der Bindung http://www.beispiel.de
anlegen. Die Standardwebseite von nginx besitzt ja eine Catch-All-Konfiguration, und die lässt sich nicht wirklich auf https
umstellen.
Zunächst kopierst Du die Standard-Webseite:
$ sudo cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/de.beispiel.conf
Anschließend öffnest Du die Datei:
$ sudo nano /etc/nginx/conf.d/de.beispiel.conf
Dort änderst Du den folgenden Bereich
server {
listen 80;
server_name localhost;
wie folgt ab:
server {
listen 80;
server_name www.beispiel.de;
Speichere Deine Änderung und starte nginx neu:
$ sudo systemctl restart nginx
Wir haben jetzt einen neuen Webseite (einen sogenannten Virtual Host) für die Domäne www.beispiel.de
angelegt. Da wir faul sind, haben wir dieselbe HTML-Seite verwendet, wie die Standard-Webseite von nginx. Ein erneuter Test mit http://www.beispiel.de
in Deinen Web-Browser sollte also wieder die Standardausgabe von nginx zeigen.
Certbot installieren
Damit unsere Webseite auch unter https://www.beispiel.de
erreichbar ist, benötigen wir jetzt ein weiteres Werkzeug namens Certbot. Certbot ist ein Open Source Werkzeug zum automatisierten Erzeugen von TLS-Zertifikaten durch Let’s Encrypt.
Eine Installation unter Ubuntu geht wie folgt:
$ sudo apt install certbot python3-certbot-nginx
Und dann kann es auch schon losgehen. Mit dem folgenden Befehl können wir das HTTPS-Protokoll für unsere Beispielseite aktivieren:
$ sudo certbot --nginx
Beim aller ersten Einsatz von Certbot musst Du zunächst ein paar Fragen beantworten. Certbot fragt Dich nach Deiner E-Mail-Adresse zur Registrierung bei Let’s Encrypt. Bei Problemen (z.B. bei nicht durchgeführter Erneuerung eines Zertifikats) oder Missbrauch wirst Du automatisch von Let’s Encrypt per E-Mail benachrichtigt.
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
(Enter 'c' to cancel):
Anschließend möchte Certbot, dass Du Dir die Nutzungsbedingungen (Terms of Service) von Let’s Encrypt durchliest und diesen zustimmst.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.4-April-3-2024.pdf. You must agree in
order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y
Die nächste Frage kann man getrost mit No
beantworten.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: n
Und jetzt kommt der interessante Teil. Certbot listet nun alle Webseiten unter nginx auf und Du musst entscheiden, bei welchen Du HTTPS aktivieren möchtest. In unserem Beispiel wird nur eine Webseite angezeigt, nämlich unsere zuvor eingerichtete Seite www.beispiel.de
:
Which names would you like to activate HTTPS for?
We recommend selecting either all domains, or all domains in a VirtualHost/server block.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: www.beispiel.de
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel):
Bestätige mit der Eingabetaste und Certbot beginnt damit, ein neues TLS-Zertifikat von Let’s Encrypt zu erfragen. Das sieht dann in etwa so aus.
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for www.beispiel.de
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/conf.d/de.beispiel.conf
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel):
Während des Konfigurationsvorgangs wirst Du gefragt, ob Du eine automatische Umleitung von http
auf https
einrichten möchtest. In der Regel kann man hier mit 2
antworten.
Die Konfiguration schließt mit folgenden Meldungen ab:
Requesting a certificate for www.beispiel.de
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/www.beispiel.de/fullchain.pem
Key is saved at: /etc/letsencrypt/live/www.beispiel.de/privkey.pem
This certificate expires on 2024-12-04.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
Deploying certificate
Successfully deployed certificate for test.stueber.de to /etc/nginx/conf.d/de.beispiel.conf
Congratulations! You have successfully enabled HTTPS on https://www.beispiel.de
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
* Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
* Donating to EFF: https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Certbot hat folgendes gemacht:
-
Eine neue Datei
/etc/letsencrypt/options-ssl-nginx.conf
angelegt, in der globale TLS-Einstellungen für potentiell alle Webseiten hinterlegt sind. -
Die TLS-Konfiguration für unsere Beispielseite in der Datei
/etc/nginx/conf.d/de.beispiel.conf
hinterlegt. Dort sind auch Verweise auf die TLS-Zertifikate sowie ein Verweis auf die globale TLS-Einstellungen definiert. -
Einen CronJob unter
/etc/cron.d/certbot
eingerichtet, der zweimal am Tag die TLS-Zertifikate überprüft. Liegt das Ablaufdatum für ein TLS-Zertifikat weniger als 30 Tage in der Zukunft, wird es automatisch erneuert.
Ein erster Test mit https://www.beispiel.de in Deinem Web-Browser sollte die gewohnte Standard-Webseite von nginx anzeigen. Ein zweiter Test mit http://www.beispiel.de sollte erfolgreich auf https://www.beispiel.de umleiten.
TLS absichern
TLS kann unterschiedlich sicher konfiguriert werden. Typische Probleme sind:
-
Uralte TLS-Versionen 1.0 und 1.1. Diese sollten dringend deaktiviert werden.
-
Zahlreiche veraltete kryptographische Verfahren, die als unsicher (weak) gelten.
Wir schauen uns daher unsere Webseite mal genauer an. SSL Labs ist eine Webseite, welche die TLS-Konfiguration für eine beliebige öffentliche Webseite überprüfen kann.
Für unsere Beispielseite www.beispiel.de
gibt SSL Labs folgendes Ergebnis aus:
Auch die zusammenfassende Bewertung von SSL Lab sieht richtig gut aus:
Die Standardkonfiguration von TLS ist also schon sehr gut, es gibt erst einmal keinen dringenden Bedarf, daran etwas zu ändern. Wer sich die Konfiguration im Detail anschauen möchte, der tippt folgendes sein:
$ sudo nano /etc/letsencrypt/options-ssl-nginx.conf
Damit öffnen wir die globale TLS-Konfigurationsdatei. Wer mit den Konfigurationsparametern rumspielen möchte, der sei auf das Mozilla-Projekt verwiesen. Unter der folgenden Webseite
https://ssl-config.mozilla.org/
findest Du einen SSL Configuration Generator für nginx (und andere Web-Server).
HTTP/2
Die Konfiguration von HTTPS unter nginx hat noch einen weiteren angenehmen Nebeneffekt. nginx unterstützt in diesem Fall das HTTP/2-Protokoll. Alle modernen Web-Browser haben diesen Protokollstandard bereits implementiert und können daher ab sofort per HTTP/2 mit deiner Webseite kommunizieren. Allerdings muss Du dafür Deine Konfiguration noch einmal anpassen, da das nginx-Plugin von Certbot HTTP/2 noch nicht unterstützt:
$ sudo nano /etc/nginx/conf.d/de.beispiel.conf
Dort fügst Du im Server-Block folgenden Eintrag hinzu:
http2 on;
Speichere Deine Änderung und starte nginx neu:
$ sudo systemctl restart nginx
Voilà. Deine Webseite sollte jetzt auch auf http/2-Anfragen antworten.
Artikelhistorie
- 25.02.2021
- Erstveröffentlichung
- 02.07.2021
- Zusätzlicher Hinweis auf
sites-available
undsites-enabled
.
- Zusätzlicher Hinweis auf
- 08.12.2021
- Update auf Ubuntu Server 20.04 LTS
- Einige zusätzliche Infos und kleinere Korrekturen
- 06.09.2024
- Update auf Ubuntu Server 24.04 LTS und nginx 1.26.2