HSTS verstehen und konform einrichten

HSTS Header nur über sichere Verbindungen senden

Für eine konforme HSTS Implementierung ist es wichtig, dass der Header nur über gesicherte Verbindungen, wie HTTPS, propagiert wird. Ein Response über unsicheres HTTP, darf nicht den HSTS Header gesetzt haben.

Diese Anforderung ist mit Nginx leicht einzuhalten, wenn für HTTP und HTTPS getrennte Serverblöcke in der Konfiguration aufsetzt werden. Dann wird der der HSTS Header mit einem Kommando nur in dem Serverblock HTTPS hinzugefügt und fertig.

Konfigurationsplattformen konfigurieren Web-Server aus Anwendungssicht und fragen daher meist nur ab, auf welchen Ports die Anwendung erreichbar und welche Protokolle genutzt werden sollen. Nginx bietet hierfür die Möglichkeit, beide Protokolle in einem Serverblock gemeinsam zu konfigurieren. Dies vereinfacht die Konfiguration und Wartung enorm, führt aber häufig dazu, dass der HSTS Header für HTTP und HTTPS gesetzt wird.

Synology DSM 6.2

Synology bietet mit der Applikation ‚Web Station‘ eine einfache Konfigurationsmöglichkeit für virtuelle Hosts und Webserver. Allerdings legt auch ‚Web Station‘ nur einen Serverblock für die Anwendung an. Aktiviert man in ‚Web Station‘ den Schalter HSTS, wird der HSTS Header für sichere und unsichere Verbindungen eingefügt.

Für eine konforme HSTS Implementierung auf der Synology NAS, kenne ich zwei Lösungen, die ich nachfolgend bechreibe.

Serverblock für HTTP und HTTPS trennen

Die erste Lösung trennt die HTTP und HTTPS Konfiguration, indem man in Nginx einen zweiten Serverblock anlegt und mit ‚Web Station‘ nur noch den Serverblock für HTTPS konfiguriert. Somit kann man wichtige Funktionen vom DSM der Synology weiternutzen. Beispielsweise funktioniert die Zertifikatsverwaltung der DSM uneingeschränkt weiter.

So sieht in Web Station eine typische Konfiguration für einen vHost mit Web-Site aus:

DSM Web-Station für Port 80/443

Im oberen Teil kann man erkennen, dass die Site sowohl über Port 80 und Port 443 erreichbar ist. Weiter unten ist der Schalter für HSTS gesetzt.

Im ersten Schritt ändern wie die Konfiguration so, dass der nginx Server nur noch für HTTPS genutzt wird. Der Haken für Port 80 /443 wird entfernt und für der Haken bei HTTPS gesetzt und ein freier Port eingetragen:

 

DSM Web-Station nur für HTTPS

Leider kann man in den aktuellen DSM Versionen nicht mehr den HTTPS Port 443 alleine setzen. Ich habe daher den Port 1443 gewählt. Damit die Seite wieder unter dem Port 443 erreicht wird, muss man das Port Forwarding oder die Firewall im Router oder im NAS anpassen.

Virtueller Host nur auf Port 443

Wer dies nicht kann oder wie ich nicht möchte, kann den Port per SSH ändern. Dazu loggen wir uns per SSH auf der NAS ein und editieren die Datei ‚VirtualHost.json‘:

$ cd /var/packages/WebStation/etc/
$ sudo vi VirtualHost.json

Im Editor suchen wir die Zeile “fqdn” : “demo.allius.de” und haben damit den Block für unseren vHost gefunden:

   "e4fbe7fa-b229-4ce1-84c5-5b4ebd6201a0" : {
      "backend" : 0,
      "fqdn" : "demo.allius.de",
      "https" : {
         "compatibility" : 1,
         "compression" : false,
         "hsts" : true,
         "http2" : true,
         "redirect" : false
      },
      "index" : [ "index.html", "index.htm", "index.cgi", "index.php", "index.php5" ],
      "php" : "46a4c4d9-8dc1-4b69-849f-1013184a7a76",
      "port" : {
         "https" : [ 1443 ]
      },
      "root" : "/volume1/vhost_demo/demo_allius_de/www"
   },

Ein paar Zeilen tiefer finden wir den Block „port“ mit der Zeile ‚“https“ : [ 1443 ]‘. Hier können wir einfach den Port 1443 durch 443 ersetzen und generieren die nginx Konfiguration neu:

$ sudo /usr/syno/etc.defaults/rc.sysv/nginx-conf-generator.sh
$ 

In der Applikation ‚Web Station‘ können wir die Änderung auch kontrollieren:

DSM Web-Station nur Port 443

Der Port 443 wird hier als Fehler makiert. Dies ist eine Einschränkung der Applikation ‚Web Station‘ ab DSM 6.0. Die Nginx Konfiguration funktioniert auch auf Port 443 und auch die Konfiguration andere vHost über ‚Web Station‘ funktioniert weiterhin. Setzt man den HTTPS Port wieder ungleich 443 kann auch der modifizierte vHost wieder aus ‚Web Station‘ geändert werden.

Hoffentlich wird dies durch Synology in einer später DSM Version gefixt, sodass man nicht den Umweg über das PortForwarding oder über SSH mehr gehen muss.

HSTS Header abhängig vom Protokoll setzen

Eine andere Lösung basiert auf der Tatsache, dass das nginx Kommando ‚add_header‘ keinen  Header einfügt, wenn kein Wert für den Header angegeben wurde. Wir müssen daher nur ein Variable definieren, die ausschließlich für HTTPS Requests gesetzt wird und diese dann im ‚add_header‘ Kommando verwenden. Nginx setzt die Variable $scheme mit den Werten ‚http‘ oder ‚https‘, je nach dem  über welches Protokoll der Request übertragen wurde.

Mit dem nachfolgenden ‚map‘ Kommando wird die Variable $hsts_header nur gesetzt, wenn $scheme den Wert ‚https‘ hat:

map $scheme $hsts_header { 
  https "max-age=31536000; includeSubDomains; preload"; 
}

Und so wird die neue Variable $hsts_header angewendet:

add_header Strict-Transport-Security $hsts_header always;

Das ‚map‘ Kommando kann nicht im Serverblock sondern nur im übergeordneten HTTP Block gesetzt werden. In der Praxis befinden sich die beiden Blöcke oft in verschiedenen Config Files, die über symbolische Links in die Konfiguration eingebunden werden.

Ein Praxisbeispiel dieser Methode habe ich hier beschrieben: wordpress-installation-auf-synology-nas. . Dort zeige ich auch, wie mit symbolischen Links eine bestehende Nginx Konfiguration, um eigene Server- und HTTP Blöcke erweitert werden kann.