Nginx HTTP2 aktivieren & Troubleshooting

Nginx unterstützt seit Version 1.9.5 das HTTP2 Protokoll (https://nginx.org/en/docs/http/ngx_http_v2_module.html). Dies kann dazu beitragen Webseiten deutlich schneller aufzurufen. Hierbei können über eine Verbindung mehrere Anfragen gestellt und beantwortet werden. Es ist also nicht nötig pro HTTP-Request eine dedizierte Verbindung herzustellen.
Dabei ist wichtig zu wissen, dass auf einem Bind HTTP2 aktiviert, oder deaktiviert sein kann. Eine Mischkonfiguration pro vHost (server-Kontext) ist nicht möglich (Stand heute). Hierbei versteht man unter einem Bind die Konfigurationsdirektive "listen $IP:$PORT".
Aktiviert man HTTP2 auf einem vHost, gilt diese Einstellung auch für die anderen Seiten die auf dem selben Port lauschen.
In diesem stark vereinfachten Beispiel würde auf my.host2.com mit HTTP2 arbeiten:
# nginx.conf
http {
server {
server_name my.host.com;
listen 1.2.3.4:443 ssl http2;
}
server {
server_name my.host2.com;
listen 1.2.3.4:443 ssl;
}
}
Die Aktivierung von HTTP2 geschieht einfach über den http2 Parameter hinter listen. Mehr ist prinzipiell nicht nötig, weitere Hinweise und Stolpersteine möchte ich hier aber trotzdem nennen.
Sporadische Verbindungsabbrüche in Chrome
In den neueren Versionen von nginx wird die Einstellung keepalive_timeout für HTTP2 Verbindungen angewendet. In der Dokumentation wird dies wie folgt gekennzeichnet:
This directive is obsolete since version 1.19.7.
The keepalive_timeout directive should be used instead.
Bei der Migration von älteren Nginx-Konfigurationen wo zum Beispiel Keepalive deaktiviert war,, kann dies zu unvorgesehenen Abbrüchen der HTTP2 Verbindung führen. In Chrome werden dann vermehrt sporadische ERR_HTTP2_SERVER_REFUSED_STREAM Fehler im Debugger angezeigt.
Firefox baut dazu im Gegensatz neue Verbindungen auf, sodass dieser Fehler nicht direkt zum Abbruch führt.
Es ist also ratsam bei Verwendung von HTTP2 den Keepalive Wert nicht zu deaktivieren, oder zu niedrig zu wählen!
Verbindungsprobleme (falsche Cipher)
Wird der Parameter ssl_prefer_server_ciphers=On gesetzt, ist es wichtig, möglichst sichere, aber auch kompatible Cipher zu wählen, denn der Server gibt vor, welche gesprochen werden können.
Es ist hilfreich den Konfig-Generator von Mozilla zu verwenden, welcher für eine Vielzahl von Serveranwendungen passende Konfigurationen bereitstellt:
https://ssl-config.mozilla.org/
Lässt man Klienten selbst wählen (ssl_prefer_server_ciphers=Off), kann dies die Kompatibilität und Verbindungen eher zulassen. Gerade ältere Systeme unterstützten ggf. neuere Cipher nicht und können keine Verbindung aufbauen.