Hinweis: Diese Inhalte wurden mit Unterstützung von Künstlicher Intelligenz erstellt und redaktionell überprüft (Transparenzhinweis gemäß Art. 50 EU AI Act).
nginx auf dem Produktionsserver
Hinweis: Diese Inhalte wurden mit Unterstützung von Künstlicher Intelligenz erstellt und redaktionell überprüft (Transparenzhinweis gemäß Art. 50 EU AI Act).
Auf einem Server im Internet liefert nginx Websites dauerhaft und verschlüsselt an Besucher aus. Diese Anleitung richtet nginx auf einem frischen Ubuntu-Server für den echten Betrieb ein: mit Firewall, automatischen Sicherheitsupdates, Wildcard-Zertifikat von Let's Encrypt und einer abgesicherten Grundkonfiguration. Als Beispiel dient die Domain wissen-ahrensburg.de.
Vorbemerkungen
- Unterschied zur Anleitung nginx: Dort läuft nginx auf dem eigenen Rechner zum Testen. Hier ist der Server aus dem Internet erreichbar. Deshalb kommen Firewall, HTTPS und Schutz vor fremden Anfragen dazu.
- Voraussetzungen:
- Ein Server mit Ubuntu 26.04 LTS, auf den du per SSH mit einem Benutzer mit
sudo-Rechten zugreifst. - Die Domain
wissen-ahrensburg.dezeigt perA-Eintrag (IPv4) und, falls vorhanden,AAAA-Eintrag (IPv6) auf den Server. Dasselbe gilt fürwwwoder für*, wenn beliebige Subdomains auf den Server zeigen sollen.
- Ein Server mit Ubuntu 26.04 LTS, auf den du per SSH mit einem Benutzer mit
- Eigene Domain: Ersetze
wissen-ahrensburg.dein allen Befehlen und Dateien durch deine Domain. - apt statt Snap: Certbot gibt es auch als Snap-Paket. Ubuntu 26.04 bringt Certbot aber selbst mit. Das
apt-Paket bekommt Sicherheitsupdates zusammen mit dem restlichen System, undsnapdwird dafür nicht gebraucht. - Alle Befehle laufen auf dem Server, also in der SSH-Sitzung, nicht auf deinem eigenen Rechner.
System vorbereiten
1. Paketlisten aktualisieren
Damit apt die aktuellen Versionen aller Pakete kennt.
sudo apt update
2. Installierte Pakete aktualisieren
Ein Server im Internet sollte vor der Einrichtung auf dem neuesten Stand sein, damit keine bekannten Sicherheitslücken offen sind.
sudo apt upgrade
Prüfen: Die Frage nach der Installation mit J bzw. Y bestätigen. Meldet apt danach, dass ein Neustart nötig ist (Datei /var/run/reboot-required existiert), starte den Server mit sudo reboot neu und melde dich wieder an.
3. Automatische Sicherheitsupdates installieren
unattended-upgrades spielt Sicherheitsupdates jeden Tag von selbst ein, auch für nginx und Certbot. Auf Ubuntu-Servern ist das Paket meist schon vorhanden, der Befehl schadet dann nicht.
sudo apt install unattended-upgrades
4. Automatische Updates einschalten
Der Dialog fragt, ob Updates automatisch installiert werden sollen. Wähle Ja.
sudo dpkg-reconfigure -plow unattended-upgrades
Prüfen: Die Datei enthält zwei Zeilen, die beide mit "1"; enden.
cat /etc/apt/apt.conf.d/20auto-upgrades
nginx installieren
5. nginx installieren
Installiert nginx aus den Ubuntu-Paketquellen. Der Dienst startet sofort und beim Hochfahren des Servers automatisch.
sudo apt install nginx
Prüfen: Die Versionsnummer wird angezeigt.
nginx -v
6. Autostart prüfen
Auf einem Produktionsserver muss nginx nach jedem Neustart von selbst laufen.
systemctl is-enabled nginx
Prüfen: Die Ausgabe lautet enabled. Steht dort disabled, schalte den Autostart mit sudo systemctl enable nginx ein.
7. Standardseite ausschalten
Die mitgelieferte Seite „Welcome to nginx!“ würde sonst jedem angezeigt, der die IP-Adresse des Servers aufruft. Gelöscht wird nur der Link in sites-enabled. Das Original in sites-available bleibt als Vorlage erhalten.
sudo rm /etc/nginx/sites-enabled/default
Firewall einrichten
8. SSH in der Firewall erlauben
Wichtig: Dieser Schritt muss vor dem Einschalten der Firewall kommen. Sonst sperrt ufw die laufende SSH-Verbindung, und du kommst nicht mehr auf den Server.
sudo ufw allow OpenSSH
9. HTTP und HTTPS in der Firewall erlauben
Das Profil Nginx Full wurde mit nginx installiert und öffnet Port 80 (HTTP) und Port 443 (HTTPS).
sudo ufw allow 'Nginx Full'
10. Firewall einschalten
Ab jetzt sind nur noch SSH, HTTP und HTTPS von außen erreichbar. Die Rückfrage mit y bestätigen.
sudo ufw enable
Prüfen: Die Liste enthält OpenSSH und Nginx Full, jeweils mit ALLOW.
sudo ufw status
Grundkonfiguration absichern
11. Eigene Einstellungen für alle Websites anlegen
Dateien in /etc/nginx/conf.d/ gelten für alle Websites auf dem Server. Eine eigene Datei ist besser, als nginx.conf direkt zu ändern, weil ein Update von nginx sie nicht anfasst.
server_tokens offblendet die Versionsnummer von nginx in Fehlerseiten und im HeaderServeraus. Angreifer sehen so nicht sofort, welche Version läuft.client_max_body_sizebegrenzt, wie groß hochgeladene Daten sein dürfen.10mreicht für Formulare und kleine Uploads.- Die
gzip-Zeilen komprimieren Text, CSS, JavaScript und JSON. Seiten laden dadurch schneller.gzip onsteht bei Ubuntu schon innginx.confund fehlt deshalb hier.
sudo nano /etc/nginx/conf.d/produktion.conf
Füge diesen Inhalt ein (im Terminal mit Strg+Umschalt+V), speichere mit Strg+O und Enter und beende nano mit Strg+X:
# Gilt für alle Websites auf diesem Server
server_tokens off;
client_max_body_size 10m;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_types text/plain text/css text/xml application/json application/javascript application/xml image/svg+xml;
12. Konfiguration testen
sudo nginx -t
Prüfen: Die Ausgabe endet mit test is successful. Meldet nginx "gzip_types" directive is duplicate (oder eine andere gzip-Zeile), ist diese Zeile in /etc/nginx/nginx.conf schon aktiv. Lösche sie dann in produktion.conf.
Wildcard-Zertifikat holen
Die Einzelheiten zum Nachweis über DNS stehen in der Anleitung Wildcard-Zertifikat mit Certbot. Hier folgt die Kurzfassung für den Server.
13. Certbot installieren
certbot beantragt das Zertifikat, bind9-dnsutils liefert den Befehl dig zum Prüfen der DNS-Einträge.
sudo apt install certbot bind9-dnsutils
Prüfen: Die Version wird angezeigt.
certbot --version
14. Zertifikat anfordern
nginx muss dafür nicht gestoppt werden. Der Nachweis läuft über TXT-Einträge im DNS und nicht über den Webserver. Anhalten müsste man nginx nur beim Verfahren --standalone, bei dem Certbot selbst Port 80 belegt.
--cert-namelegt den Ordner fest:/etc/letsencrypt/live/wissen-ahrensburg.de/.'*.wissen-ahrensburg.de'steht in einfachen Anführungszeichen, damit die Shell den Stern nicht als Dateimuster auswertet.
sudo certbot certonly --manual --preferred-challenges dns --cert-name wissen-ahrensburg.de -d wissen-ahrensburg.de -d '*.wissen-ahrensburg.de'
Beim ersten Aufruf fragt Certbot nach einer E-Mail-Adresse und den Nutzungsbedingungen (mit Y zustimmen).
15. Die beiden TXT-Einträge anlegen
Certbot zeigt nacheinander zwei Werte für den Namen _acme-challenge.wissen-ahrensburg.de. Lege beim Domain-Anbieter für jeden Wert einen eigenen TXT-Eintrag mit dem Namen _acme-challenge an. Beide Einträge müssen gleichzeitig bestehen. Drücke nach dem zweiten Wert noch nicht Enter.
16. TXT-Einträge prüfen
In einem zweiten Terminal (zweite SSH-Sitzung) fragst du einen öffentlichen DNS-Server, ob die Einträge schon sichtbar sind.
dig +short TXT _acme-challenge.wissen-ahrensburg.de @1.1.1.1
Prüfen: Beide Werte erscheinen. Wenn nicht, einige Minuten warten und erneut fragen. Danach im ersten Terminal Enter drücken.
Prüfen: Certbot meldet Successfully received certificate. Die TXT-Einträge kannst du danach beim Anbieter wieder löschen.
17. Zertifikat als Baustein anlegen
Die Pfade zum Zertifikat kommen in eine eigene Datei. Jede Website unter der Domain bindet sie mit einer Zeile ein.
sudo nano /etc/nginx/snippets/ssl-wissen-ahrensburg.de.conf
Füge diesen Inhalt ein, speichere mit Strg+O und Enter und beende nano mit Strg+X:
# Wildcard-Zertifikat für wissen-ahrensburg.de und *.wissen-ahrensburg.de
ssl_certificate /etc/letsencrypt/live/wissen-ahrensburg.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/wissen-ahrensburg.de/privkey.pem;
18. Sicherheits-Header als Baustein anlegen
Diese Header weisen den Browser an, sich vorsichtiger zu verhalten:
Strict-Transport-Security(HSTS): Der Browser ruft die Domain ein Jahr lang nur noch über HTTPS auf, auch wenn jemandhttp://eintippt. Achtung: Diese Zusage lässt sich nicht einfach zurücknehmen. Lass den Header weg, solange HTTPS noch nicht zuverlässig läuft.X-Content-Type-Options: Der Browser hält sich an den angegebenen Dateityp und rät nicht selbst.X-Frame-Options: Fremde Seiten dürfen deine Seite nicht in einem Rahmen einbetten (Schutz vor untergeschobenen Klicks).Referrer-Policy: Beim Klick auf fremde Links wird nur die Domain weitergegeben, nicht die ganze Adresse.
always sorgt dafür, dass die Header auch bei Fehlerseiten mitgeschickt werden.
sudo nano /etc/nginx/snippets/sicherheitsheader.conf
Füge diesen Inhalt ein, speichere mit Strg+O und Enter und beende nano mit Strg+X:
add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Hinweis: Steht in einem
location-Block eine eigeneadd_header-Zeile, gelten dort die Header aus demserver-Block nicht mehr. Binde den Baustein dann zusätzlich in diesemlocation-Block ein.
Fremde Anfragen abweisen
19. Standard-Server anlegen
Viele automatische Scanner rufen Server nur über die IP-Adresse oder mit erfundenen Domainnamen auf. Ohne passenden Eintrag würde nginx ihnen die erste Website zeigen. Dieser Standard-Server fängt alle Anfragen ab, deren Name zu keiner deiner Websites passt:
- Auf Port 80 beendet
return 444die Verbindung ohne Antwort. - Auf Port 443 lehnt
ssl_reject_handshake ondie verschlüsselte Verbindung ab, bevor ein Zertifikat gezeigt wird. So verrät der Server nicht, welche Domains auf ihm liegen.
Die 000 am Anfang des Dateinamens sorgt dafür, dass die Datei als Erstes geladen wird und leicht zu finden ist.
sudo nano /etc/nginx/sites-available/000-standard
Füge diesen Inhalt ein, speichere mit Strg+O und Enter und beende nano mit Strg+X:
# Anfragen ohne bekannten Domainnamen abweisen
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 444;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name _;
ssl_reject_handshake on;
}
20. Standard-Server einschalten
sudo ln -s /etc/nginx/sites-available/000-standard /etc/nginx/sites-enabled/000-standard
Website einrichten
21. Ordner für die Website anlegen
Die Dateien der Website liegen im Unterordner html. Der Ordner gehört deinem Benutzer, damit du ohne sudo Dateien hochladen kannst. nginx braucht nur Leserechte.
sudo mkdir -p /var/www/wissen-ahrensburg.de/html
sudo chown -R "$USER":"$USER" /var/www/wissen-ahrensburg.de
22. Startseite anlegen
Eine einfache Seite zum Testen. Später ersetzt du sie durch die echte Website.
nano /var/www/wissen-ahrensburg.de/html/index.html
Füge diese Zeile ein, speichere mit Strg+O und Enter und beende nano mit Strg+X:
<h1>wissen-ahrensburg.de läuft</h1>
23. Konfiguration der Website anlegen
Die Datei enthält drei server-Blöcke:
- Der erste leitet alle HTTP-Anfragen für die Domain und jede Subdomain dauerhaft auf HTTPS um.
- Der zweite leitet
www.wissen-ahrensburg.deauf die Adresse ohnewwwum. So hat jede Seite genau eine Adresse, was auch Suchmaschinen bevorzugen. - Der dritte ist die eigentliche Website.
http2 onschaltet das schnellere Protokoll HTTP/2 ein. Eigene Log-Dateien pro Website erleichtern die Fehlersuche.
sudo nano /etc/nginx/sites-available/wissen-ahrensburg.de
Füge diesen Inhalt ein, speichere mit Strg+O und Enter und beende nano mit Strg+X:
# HTTP: alles auf HTTPS umleiten
server {
listen 80;
listen [::]:80;
server_name wissen-ahrensburg.de *.wissen-ahrensburg.de;
return 301 https://$host$request_uri;
}
# HTTPS: www auf die Adresse ohne www umleiten
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name www.wissen-ahrensburg.de;
include snippets/ssl-wissen-ahrensburg.de.conf;
return 301 https://wissen-ahrensburg.de$request_uri;
}
# HTTPS: die Website
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name wissen-ahrensburg.de;
include snippets/ssl-wissen-ahrensburg.de.conf;
include snippets/sicherheitsheader.conf;
root /var/www/wissen-ahrensburg.de/html;
index index.html;
access_log /var/log/nginx/wissen-ahrensburg.de.access.log;
error_log /var/log/nginx/wissen-ahrensburg.de.error.log;
location / {
try_files $uri $uri/ =404;
}
# Versteckte Dateien wie .git oder .env nie ausliefern
location ~ /\. {
deny all;
}
}
24. Website einschalten
sudo ln -s /etc/nginx/sites-available/wissen-ahrensburg.de /etc/nginx/sites-enabled/wissen-ahrensburg.de
25. Konfiguration testen und nginx neu laden
&& sorgt dafür, dass nginx nur neu geladen wird, wenn der Test erfolgreich war. Eine fehlerhafte Konfiguration legt die laufenden Websites so nicht lahm.
sudo nginx -t && sudo systemctl reload nginx
Prüfen: Die Ausgabe enthält test is successful. Meldet nginx cannot load certificate, stimmt der Pfad in Schritt 17 nicht mit dem Ordner unter /etc/letsencrypt/live/ überein.
Testen
Diese Befehle funktionieren auf dem Server und auf jedem anderen Rechner mit Internetzugang.
26. Umleitung auf HTTPS prüfen
curl -sI http://wissen-ahrensburg.de/ | grep -E '^HTTP|^Location'
Prüfen: Die Ausgabe lautet HTTP/1.1 301 Moved Permanently und Location: https://wissen-ahrensburg.de/.
27. Umleitung von www prüfen
curl -sI https://www.wissen-ahrensburg.de/ | grep -E '^HTTP|^location'
Prüfen: Die Ausgabe lautet HTTP/2 301 und location: https://wissen-ahrensburg.de/.
28. Website und Header prüfen
curl -sI https://wissen-ahrensburg.de/
Prüfen: Die erste Zeile lautet HTTP/2 200. Die Zeile server: zeigt nur nginx ohne Versionsnummer. Außerdem stehen dort die vier Header aus Schritt 18, z. B. strict-transport-security: max-age=31536000.
29. Abweisung über die IP-Adresse prüfen
Ersetze 203.0.113.10 durch die IPv4-Adresse deines Servers.
curl -sI http://203.0.113.10/
Prüfen: Es kommt keine Ausgabe. Ohne -s meldet curl Empty reply from server. Der Standard-Server aus Schritt 19 hat die Verbindung beendet.
30. Log-Dateien ansehen
Hier siehst du jeden Aufruf der Website. Mit Strg+C beendest du die Anzeige. Die Log-Dateien werden von logrotate täglich gewechselt und nach 14 Tagen gelöscht, damit die Festplatte nicht voll läuft.
sudo tail -f /var/log/nginx/wissen-ahrensburg.de.access.log
Zertifikat verlängern
Ein manuell beantragtes Zertifikat verlängert sich nicht von selbst. Es gilt derzeit 90 Tage. Trage dir etwa 30 Tage vor Ablauf einen Termin ein. Das genaue Vorgehen steht in der Anleitung Wildcard-Zertifikat mit Certbot im Abschnitt „Verlängern“: Schritt 14 wiederholen, neue TXT-Einträge setzen und danach nginx neu laden.
sudo systemctl reload nginx
Prüfen: Das Ablaufdatum steht bei Expiry Date.
sudo certbot certificates
Prüfen der Installation
nginx -v
systemctl is-active nginx
sudo ufw status
Prüfen: Der erste Befehl zeigt die Version, der zweite active, der dritte OpenSSH und Nginx Full mit ALLOW.
Deinstallieren
1. Websites ausschalten und Konfiguration löschen
sudo rm /etc/nginx/sites-enabled/wissen-ahrensburg.de /etc/nginx/sites-available/wissen-ahrensburg.de
sudo rm /etc/nginx/sites-enabled/000-standard /etc/nginx/sites-available/000-standard
2. Bausteine und eigene Einstellungen löschen
sudo rm /etc/nginx/snippets/ssl-wissen-ahrensburg.de.conf /etc/nginx/snippets/sicherheitsheader.conf /etc/nginx/conf.d/produktion.conf
3. Dateien der Website löschen
Achtung: Alles in /var/www/wissen-ahrensburg.de geht verloren. Sichere die Website vorher, wenn du sie noch brauchst.
sudo rm -r /var/www/wissen-ahrensburg.de
4. Zertifikat löschen
Entfernt Zertifikat und Schlüssel unter /etc/letsencrypt. Certbot fragt zur Sicherheit nach.
sudo certbot delete --cert-name wissen-ahrensburg.de
5. HTTP und HTTPS in der Firewall schließen
Die Regel für SSH bleibt bestehen, sonst sperrst du dich aus.
sudo ufw delete allow 'Nginx Full'
6. nginx und Certbot entfernen
purge entfernt auch die Konfigurationsdateien unter /etc/nginx.
sudo apt purge nginx nginx-common certbot
7. Nicht mehr benötigte Pakete entfernen
sudo apt autoremove
Prüfen: Der Befehl wird nicht mehr gefunden.
nginx -v
Hinweis: Diese Inhalte wurden mit Unterstützung von Künstlicher Intelligenz erstellt und redaktionell überprüft (Transparenzhinweis gemäß Art. 50 EU AI Act).
Open Knowledge (Freies Wissen): Alle Texte stehen unter der freien Lizenz Creative Commons Namensnennung – Weitergabe unter gleichen Bedingungen 4.0 International (CC BY-SA 4.0) und können frei gelesen, geteilt und weiterverarbeitet werden.