Dieser Artikel zeigt Euch, wie man eine eigene Webseite unter Ubuntu Server 20.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 die Electronic Frontier Foundation (EFF), die Mozilla Foundation, Facebook, Google Chrome 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 20.04 LTS. Der Artikel Ubuntu Server 20.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 20.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 absichern, indem wir veraltete Protokolle und kryptografische Verfahren deaktivieren.
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 veraltet ist. Solltest Du nginx bereits installiert haben, kannst Du die Installation mit folgendem Befehl wieder entfernen:
$ sudo apt remove nginx nginx-common nginx-full nginx-core
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 http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
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.
$ wget http://nginx.org/keys/nginx_signing.key | sudo apt-key add nginx_signing.key
Ist es auch der richtige Signaturschlüssel?
$ sudo apt-key fingerprint ABF5BD827BD9BF62
Das Ergebnis sollte so aussehen:
pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14]
573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62
uid [ unknown] nginx signing key <signing-key@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 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.
--2021-12-08 16:39:00-- http://localhost/
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:80... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:80... connected.
HTTP request sent, awaiting response...
HTTP/1.1 200 OK
Server: nginx/1.20.2
Date: Wed, 08 Dec 2021 15:39:00 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 16 Nov 2021 14:44:02 GMT
Connection: keep-alive
ETag: "6193c3b2-264"
Accept-Ranges: bytes
Length: 612 [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:

nginx Standard-Webseite
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 Fehleranalyse liegt unter
/var/log/nginx/error.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
Plugins selected: Authenticator nginx, Installer nginx
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.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel:
Die nächste Frage kann man getrost mit No
beantworten.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing 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?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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:
Redirecting all traffic on port 80 to ssl in /etc/nginx/conf.d/de.beispiel.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://www.beispiel.de
You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=www.beispiel.de
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/www.beispiel.de/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/www.beispiel.de/privkey.pem
Your cert will expire on 2021-05-25. To obtain a new or tweaked
version of this certificate in the future, simply run certbot again
with the "certonly" option. To non-interactively renew *all* of
your certificates, run "certbot renew"
- Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
- 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
Wer sich die Ausgabe von Certbot genau anschaut, entdeckt die folgende Infozeile:
You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=www.beispiel.de
Und genau das machen wir jetzt auch. 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:

nginx frisch installiert
Das sieht natürlich nicht so prickelnd aus. Die Probleme hier sind:
-
Uralte TLS-Versionen 1.0 und 1.1. Diese sollten dringend deaktiviert werden.
-
Zahlreiche veraltete kryptographische Verfahren, die von SSL Lab als unsicher (weak) markiert werden.
Wir müssen also nocheinmal ran an die nginx-Konfiguration, um unseren Web-Server besser zu schützen.
$ sudo nano /etc/letsencrypt/options-ssl-nginx.conf
Damit öffnen wir die globale TLS-Konfigurationsdatei. Die Frage ist nun, was genau müssen wir denn jetzt ändern? Hier kann uns das Mozilla-Projekt helfen. Unter der folgenden Webseite
https://ssl-config.mozilla.org/
findest Du einen SSL Configuration Generator für nginx (und andere Web-Server).
Wir wählen für unser Beispiel die Konfiguration nginx
und Intermediate
aus und kopieren die relevanten Teile der generierten Konfiguration in unsere bereits geöffnete Konfigurationsdatei. Das könnte dann so aussehen:
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;
# intermediate configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000" always;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
Speichere die Datei options-ssl-nginx.conf
und starte nginx neu:
$ sudo systemctl restart nginx
Ein abschließender Test unter SSL Labs ergibt nun folgendes Bild:

nginx abgesichert
Auch die zusammenfassende Bewertung von SSL Lab sieht jetzt richtig gut aus:

Ein A+ Rating für unsere Webseite
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 änderst Du folgende Einstellung
listen 443 ssl;
wie folgt ab:
listen 443 ssl http2;
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