HTTP auf HTTPS in Nginx umleiten: Best Practices
Richten Sie eine zuverlässige HTTP-zu-HTTPS-Weiterleitung in Nginx mit einem dedizierten Port-80-Block ein, vermeiden Sie Weiterleitungsschleifen, wählen Sie den richtigen Weiterleitungscode und fügen Sie HSTS hinzu, wenn Sie bereit sind.
HTTP auf HTTPS in Nginx umleiten: Best Practices
Die Umleitung von HTTP auf HTTPS in Nginx stellt sicher, dass Besucher die verschlüsselte Version Ihrer Website verwenden, selbst wenn sie die alte http://-URL eingeben oder einem veralteten Link folgen. Eine saubere Weiterleitungseinrichtung verbessert die Sicherheit, vermeidet doppelte URLs und bietet Benutzern einen konsistenten Einstiegspunkt.
Der beste Ansatz ist in der Regel einfach: Halten Sie Port 80 nur lange genug offen, um den Datenverkehr umzuleiten, und bedienen Sie die eigentliche Website auf Port 443 mit einem gültigen TLS-Zertifikat.
Die Details sind wichtig, weil Weiterleitungen leicht fast richtig gemacht werden können. Eine Weiterleitung, die den Pfad verwirft, zerstört Lesezeichen. Eine Weiterleitung, die den falschen Hostnamen beibehält, kann doppelte kanonische URLs erzeugen. Eine Weiterleitung hinter einem Load Balancer kann sich endlos wiederholen, wenn Nginx nicht versteht, wo TLS terminiert wird.
Betrachten Sie die Weiterleitung als Teil Ihrer öffentlichen API. Leute fügen Links in Chats ein, Suchmaschinen crawlen sie, Überwachungssysteme greifen auf sie zu, und alte E-Mails halten sie jahrelang am Leben. Wenn die Weiterleitung stabil ist, bemerkt es niemand. Wenn sie schlampig ist, sehen Benutzer Zertifikatswarnungen, defekte Pfade oder Fehler wegen zu vieler Weiterleitungen, bevor Ihre Anwendung überhaupt eine Anfrage erhält.
Warum HTTPS-Weiterleitungen wichtig sind
HTTPS schützt den Datenverkehr zwischen dem Browser und Ihrem Server durch TLS-Verschlüsselung. Ohne sie können Daten von Netzwerken zwischen dem Benutzer und Ihrer Website eingesehen oder verändert werden. Das ist wichtig für Logins, Formulare, Cookies, Admin-Bereiche, APIs und sogar normales Surfen.
Weiterleitungen helfen auch bei der Konsistenz. Suchmaschinen und Benutzer sollten http://example.com/page und https://example.com/page nicht als zwei separate Ziele sehen. Eine permanente Weiterleitung teilt Clients mit, dass HTTPS die bevorzugte Version ist.
Das Standard-Nginx-Muster ist ein dedizierter Port-80-Serverblock:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
Dann behandelt Ihr HTTPS-Serverblock die eigentliche Website:
server {
listen 443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
root /var/www/example.com;
index index.html;
}
Die Direktive return 301 ist effizient und klar. Sie teilt Nginx mit, eine permanente Weiterleitung zu senden, ohne zusätzliche Location-Verarbeitung durchzuführen. $request_uri bewahrt den Pfad und die Query-String, sodass /docs?page=2 zu https://example.com/docs?page=2 wird.
Für eine vollständige TLS-Einrichtung siehe Nginx mit HTTPS absichern.
Für die meisten Websites vermeiden Sie es, Anwendungslogik in den Port-80-Block zu legen. Er sollte keine statischen Dateien ausliefern, keinen Proxy zur App darstellen oder eine große Anzahl von Locations enthalten. Halten Sie ihn langweilig:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
Dieser kleine Block ist einfacher zu prüfen und weicht weniger wahrscheinlich von der HTTPS-Konfiguration ab.
Wahl zwischen 301- und 302-Weiterleitungen
Verwenden Sie 301 für eine permanente HTTP-zu-HTTPS-Weiterleitung auf einer Produktionswebsite. Browser und Suchmaschinen verstehen, dass die HTTPS-URL die HTTP-URL ersetzen soll.
Verwenden Sie 302 oder 307 nur, wenn die Weiterleitung temporär ist. Beispielsweise könnten Sie während des Testens eine temporäre Weiterleitung verwenden, bevor Zertifikate und Hostnamen endgültig sind. Sobald die HTTPS-Website bereit ist, wechseln Sie zu einer permanenten Weiterleitung.
Seien Sie vorsichtig während der frühen Einrichtung. Browser können 301-Weiterleitungen aggressiv cachen. Wenn Sie versehentlich auf den falschen Hostnamen umleiten, kann der Browser die falsche Weiterleitung beibehalten, selbst nachdem Sie Nginx korrigiert haben. Testen Sie nach Möglichkeit mit curl, privaten Browserfenstern und Nicht-Produktions-Hostnamen.
Ein praktischer Bereitstellungsablauf sieht wie folgt aus:
- Bestätigen Sie, dass der HTTPS-Serverblock direkt funktioniert.
- Bestätigen Sie, dass das Zertifikat mit jedem Hostnamen übereinstimmt.
- Fügen Sie den HTTP-Weiterleitungs-Serverblock hinzu.
- Testen Sie mehrere Pfade und Query-Strings.
- Ändern Sie temporäre Weiterleitungen nur dann in permanente, wenn das Verhalten korrekt ist.
Sie sollten sich auch für den kanonischen Hostnamen entscheiden. Wenn sowohl example.com als auch www.example.com funktionieren, wählen Sie einen als bevorzugten öffentlichen Hostnamen. Andernfalls könnten Benutzer zwischen Hostnamen hin- und herspringen oder Suchmaschinen beide indizieren.
Um beispielsweise den gesamten HTTP-Datenverkehr auf den Nicht-www-HTTPS-Hostnamen umzuleiten:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
Das unterscheidet sich von https://$host$request_uri, das den vom Benutzer angeforderten Host beibehält.
Sie können Hostnamen-Weiterleitungen auch von Schema-Weiterleitungen trennen, wenn das Verhalten explizit sein soll:
server {
listen 80;
server_name www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
Dies ist ausführlicher, macht aber das endgültige Ziel offensichtlich. Bei einer kleinen Website ist jeder Stil in Ordnung. Bei einer größeren Website mit vielen Aliasen können explizite Serverblöcke Verwirrung bei späteren Änderungen reduzieren.
Vermeidung von Weiterleitungsschleifen und Zertifikatsproblemen
Weiterleitungsschleifen treten auf, wenn Nginx, ein Load Balancer oder eine Anwendung eine Anfrage immer wieder an eine URL sendet, die eine weitere Weiterleitung auslöst. Dies ist häufig der Fall, wenn TLS vor Nginx terminiert wird, z. B. bei einem Cloud-Load-Balancer oder CDN.
In einer einfachen Einzelserver-Einrichtung empfängt Nginx HTTPS direkt, sodass die Weiterleitung unkompliziert ist. In einer Proxy-Kette kann Nginx einfaches HTTP vom Load Balancer empfangen, obwohl der Benutzer eine HTTPS-Verbindung hergestellt hat. Wenn Ihre Anwendung dann versucht, HTTPS basierend auf dem lokalen Verbindungsschema zu erzwingen, kann dies zu einer Schleife führen.
Die Lösung hängt von Ihrer Architektur ab. Normalerweise sollte der Load Balancer Header wie X-Forwarded-Proto übergeben, und die Anwendung oder Nginx-Konfiguration sollte ihnen nur von bekannten Proxy-Adressen vertrauen.
Wenn Nginx beispielsweise hinter einem vertrauenswürdigen Load Balancer sitzt und nur internes HTTP empfängt, möchten Sie möglicherweise nicht, dass Nginx jede lokale HTTP-Anfrage umleitet. Stattdessen kann der Load Balancer die öffentliche HTTP-zu-HTTPS-Weiterleitung übernehmen, während Nginx den Datenverkehr aus dem privaten Netzwerk bedient. Wenn Nginx die Entscheidung treffen muss, benötigt es zuverlässige Informationen zum weitergeleiteten Protokoll vom vorgeschalteten Proxy. Vertrauen Sie X-Forwarded-Proto nicht von beliebigen Internet-Clients.
Stellen Sie außerdem sicher, dass Zertifikate jeden umgeleiteten Hostnamen abdecken. Wenn ein Benutzer http://www.example.com besucht und Sie auf https://www.example.com umleiten, muss das Zertifikat für www.example.com gültig sein. Wenn Sie alles auf https://example.com umleiten, muss das Zertifikat für die endgültige Website example.com abdecken.
Testen Sie mit:
curl -I http://example.com/some/path?x=1
Achten Sie auf:
HTTP/1.1 301 Moved Permanently
Location: https://example.com/some/path?x=1
Testen Sie dann die HTTPS-URL:
curl -I https://example.com/some/path?x=1
Die HTTPS-Antwort sollte den tatsächlichen Status für die Seite zurückgeben, nicht eine weitere Weiterleitung zurück zu HTTP.
Testen Sie auch beide Hostnamen, falls beide existieren:
curl -I http://www.example.com/
curl -I https://www.example.com/
curl -I http://example.com/
curl -I https://example.com/
Sie suchen nach einer kurzen, vorhersagbaren Kette. Eine Weiterleitung von HTTP zur kanonischen HTTPS-URL ist gut. Mehrere Sprünge, wie HTTP-nicht-www zu HTTPS-nicht-www zu HTTPS-www und zurück, sind ein Zeichen dafür, dass Nginx, die App, CDN-Regeln oder DNS-Weiterleitung gegeneinander arbeiten.
Sie können die gesamte Kette überprüfen mit:
curl -IL http://www.example.com/some/path
Das Flag -L folgt Weiterleitungen. In einer sauberen Einrichtung sollte die Ausgabe die anfängliche HTTP-Antwort und dann die endgültige HTTPS-Antwort zeigen. Wenn Sie drei oder vier Location-Header sehen, vereinfachen Sie die Regeln, bis es eine klare Route zur kanonischen URL gibt.
HSTS und andere Best Practices
Nachdem Ihre HTTPS-Einrichtung stabil ist, können Sie HTTP Strict Transport Security (HSTS) in Betracht ziehen. HSTS teilt Browsern mit, bei zukünftigen Besuchen automatisch HTTPS zu verwenden.
Ein üblicher Header sieht so aus:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Fügen Sie dies nicht leichtfertig hinzu. Wenn Sie Subdomains einschließen, muss jede Subdomain HTTPS unterstützen. Wenn Sie später HTTPS unterbrechen, können Browser, die den HSTS-Header gesehen haben, möglicherweise nicht auf die HTTP-Version zugreifen. Beginnen Sie während des Testens mit einer kürzeren max-age und erhöhen Sie sie, sobald Sie sicher sind.
Weitere Best Practices:
- Halten Sie den Port-80-Block einfach.
- Bewahren Sie Pfade und Query-Strings auf, es sei denn, Sie haben einen Grund, dies nicht zu tun.
- Wählen Sie einen kanonischen Hostnamen.
- Testen Sie Weiterleitungen mit
curl, nicht nur mit einem Browser. - Verlängern Sie Zertifikate automatisch und überwachen Sie Verlängerungsfehler.
- Behalten Sie die Weiterleitungslogik nach Möglichkeit in Nginx, anstatt sie in der App zu duplizieren.
Einfache Weiterleitungsregeln sind leichter nachvollziehbar und weniger anfällig für Fehler bei späteren Website-Änderungen.
Häufige Fehler
Der häufigste Fehler ist die Verwendung von rewrite für eine einfache Weiterleitung:
rewrite ^ https://example.com$request_uri permanent;
Das kann funktionieren, aber return 301 ... ist klarer und vermeidet zusätzliche Rewrite-Verarbeitung. Verwenden Sie rewrite, wenn Sie wirklich Mustervergleiche benötigen, nicht für eine grundlegende Schema-Weiterleitung.
Ein weiterer Fehler ist die Weiterleitung auf $server_name, ohne zu verstehen, was es enthält. $host stammt aus dem Host-Header der Anfrage, während $server_name auf dem übereinstimmenden Nginx-Servernamen basiert. Für kanonische Weiterleitungen ist ein literaler Hostname oft die am wenigsten überraschende Option:
return 301 https://example.com$request_uri;
Sie sollten auch vermeiden, ACME-HTTP-Challenge-Pfade umzuleiten, wenn Ihre Zertifikatstools sie auf Port 80 benötigen. Viele Let's-Encrypt-Einrichtungen erledigen dies automatisch, aber benutzerdefinierte Konfigurationen benötigen möglicherweise eine Ausnahme:
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt;
}
location / {
return 301 https://example.com$request_uri;
}
Fügen Sie diese Ausnahme nur hinzu, wenn Ihr Zertifikatsclient sie verwendet. Wenn Ihre Zertifikate durch DNS-Validierung oder einen toolverwalteten temporären Server verlängert werden, halten Sie den Weiterleitungsblock einfach.
Ein sicheres Rollout-Muster
Für eine Produktionswebsite führen Sie die Änderung in Phasen durch:
- Bestätigen Sie, dass der HTTPS-Serverblock die Website korrekt bedient.
- Bestätigen Sie, dass die Zertifikatsverlängerung funktioniert oder überwacht wird.
- Fügen Sie eine temporäre Weiterleitung auf Port 80 hinzu, wenn Sie noch Hostnamen testen.
- Testen Sie häufige URLs mit
curl -Iundcurl -IL. - Wechseln Sie zu
301, sobald das Weiterleitungsziel endgültig ist. - Warten Sie, bevor Sie langlebiges HSTS aktivieren.
Diese Wartezeit ist nützlich. Sie gibt Ihnen Zeit, vergessene Subdomains, alte Webhook-URLs, hartcodierte http://-Links oder eine CDN-Regel zu finden, die von Ihrem ersten Testrechner aus nicht sichtbar war.
Behalten Sie auch die Überwachung im Auge. Wenn Ihr Uptime-Check immer noch auf http://example.com zeigt, entscheiden Sie, ob er einen 301 erwarten oder Weiterleitungen folgen und die endgültige HTTPS-Seite überprüfen soll. Beides kann gültig sein, aber der Monitor sollte dem Verhalten entsprechen, das Sie tatsächlich wünschen.
Beispiel: Statische Website und Reverse Proxy
Für eine statische Website kann der HTTPS-Block nur ein Dokumentenstammverzeichnis sein:
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
root /var/www/example.com;
index index.html;
}
Für eine Anwendung hinter Nginx bleibt der Weiterleitungsblock gleich, aber der HTTPS-Block leitet den Datenverkehr weiter:
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Der wichtige Punkt ist die Trennung. Port 80 entscheidet, wohin der Browser gehen soll. Port 443 bedient die Website. Diese Aufgaben zu vermischen, macht das Weiterleitungsverhalten schwerer nachvollziehbar, insbesondere wenn später ein weiterer Proxy oder ein CDN hinzugefügt wird.
Führen Sie nach der Bearbeitung immer aus:
sudo nginx -t
sudo systemctl reload nginx
Wenn der Test fehlschlägt, laden Sie nicht neu. Beheben Sie zuerst den Syntaxfehler und testen Sie dann erneut.
Eine letzte Überprüfung ist von außerhalb des Servers sinnvoll, nicht nur per SSH auf dem Host. Eine Firewall, ein CDN oder ein Load Balancer können das ändern, was echte Benutzer sehen. Führen Sie dieselben curl -I-Prüfungen von Ihrem Laptop, einem Überwachungsstandort oder einer temporären Cloud-Instanz aus durch. Wenn das externe Ergebnis von localhost abweicht, liegt das Weiterleitungsproblem wahrscheinlich in der Netzwerkschicht vor Nginx, nicht im Serverblock selbst. Überprüfen Sie dies, bevor Sie eine funktionierende Konfiguration neu schreiben.
Wann Sie Hilfe holen sollten
Holen Sie sich Hilfe von einem DevOps-Ingenieur, wenn Ihre Website hinter einem CDN, Cloud-Load-Balancer, Kubernetes-Ingress oder mehreren Reverse-Proxys sitzt. HTTPS-Weiterleitungen in geschichteter Infrastruktur hängen davon ab, wo TLS terminiert wird und welchen Headern vertraut wird.
Sie sollten auch um Hilfe bitten, bevor Sie langfristiges HSTS über viele Subdomains hinweg aktivieren. Eine falsche Einstellung kann Benutzer von Diensten aussperren, die nicht für HTTPS bereit sind.
Die Umleitung von HTTP auf HTTPS in Nginx ist eine kleine Konfigurationsänderung mit großen Auswirkungen auf die Sicherheit. Verwenden Sie einen dedizierten Port-80-Weiterleitungsblock, bewahren Sie die Request-URI auf, überprüfen Sie Zertifikate und testen Sie auf Schleifen, bevor Sie die Arbeit als erledigt betrachten.