Installation Nginx, HTTP/2, SPDY, mit Nghttp2 und Nghttpx

HTTP/2 ist da, naja… zumindest theoretisch. 

Alle gängigen Browser unterstützen mittlerweile HTTP 2.0 oder haben es angekündigt. NGINX und Apache (um nur 2 alternative Webserver zu nennen) unterstützen HTTP/2 nicht direkt. (NGINX hat die Implementierung zu Ende 2015 angekündigt). Für Apache gibt es mittlerweile ein experimentelles Modul (mod_h2). 

Die Umsetzung von HTTP/2 mittel Nghttp2 und Nghttpx als Proxy zu Nginx gestaltet sich relativ einfach. 

HTTP/2 basiert auf dem SPDY Netzwerkprotokoll, welches von Google als Erweiterung zu HTTP/1.1 entwickelt worden ist.

Die Ziele der Erweiterung sind vor allem die Reduzierung der Latenzzeit ohne die Kompatibilität zu HTTP 1.1 aufzugeben. Im Februar 2015 wurde HTTP/2 von der IESG freigegeben.

Die Vorteile von HTTP/2
1. Jeder Request mit Stream ID
2. Stream Multiplexing
3. Anfrage mit Daten und Anweisung
4. Server-Push Funktion
5. Flusskontrolle für Request/Push
6. Kompression der Kopfzeilen
7. Reduktion der Kopfzeilen
8. Protokollwahl (auch künftige)

Und so funktioniert es...
Beim Aufbauen einer Verbindung zu einem Webserver gibt der Browser seine H2 Funktionalität bekannt. Versteht der Server diese werden weitere Inhalte über HTTP/2 angefordert. Falls nicht wird
weiterhin HTTP/1.1 genutzt.

Einige Browser, wie z.B. Firefox, implementieren H2 nur über TLS verschlüsselte HTTPS Verbindungen.

Was ist Nghttp2? Nghttp2 ist eine Implementierung von HTTP / 2 und dessen Header-Kompressionsalgorithmus HPACK in C. Implementiert sind ein http / 2 Client, Server und Proxy, welche ein breites Spektrum abdecken. Nghttp2 unterstützt die Protokolle: h2, h2-16, h2-14, spdy/3.1 und http/1.1. 


Auf dieser Seite (wenn auch sehr ungewöhnlich für den Blog-Eintrag eines Trockenfrüchte-Shop), möchte ich auf folgende Inhalte eingehen.

1. Installation von Nghttp2, deren Module wie Nghttpx zur Umsetzung als Reverse-Proxy (Debian, in meinem Fall Ubuntu 14.04)

2. Konfiguration von Nghttpx als Reverse-Proxy auf Port 443 (SSL) in Verbindung zu NGINX auf Port 4444 (hier kann natürlich auch ein anderer Port gewählt werden).

3. Überprüfung der Protokolle ( h2, h2-16, h2-14, spdy/3.1, http/1.1)mittels nghttp -nv https://fruchthof24.de (hier die eigene Domain angeben.

Installation Nghttp2

Nghttp2 kann schnell und einfach über nachfolgende Anleitung Punkt für Punkt installiert werden.

## sudo apt-get install make binutils autoconf automake autotools-dev libtool pkg-config zlib1g-dev libcunit1-dev libssl-dev libxml2-dev libev-dev libevent-dev libjansson-dev libjemalloc-dev
## python3.4-dev g++ g++-mingw-w64-i686 git python3-setuptools

## sudo easy_install3 pip
## sudo pip3.4 install -U cython # Hier bedarf es etwas Geduld, es dauert ein wenig.

## mkdir ~/src

## git clone https://github.com/tatsuhiro-t/spdylay.git ~/src/spdylay
## cd ~/src/spdylay
## autoreconf -i
## automake
## autoconf
## ./configure
## make
## sudo make install

## sudo updatedb
## locate libspdylay.so.7

## sudo ln -s /usr/local/lib/libspdylay.so.7 /lib/x86_64-linux-gnu/libspdylay.so.7
## sudo ln -s /usr/local/lib/libspdylay.so.7.2.0 /lib/x86_64-linux-gnu/libspdylay.so.7.2.0
## sudo ldconfig

## git clone https://github.com/tatsuhiro-t/nghttp2.git ~/src/nghttp2
## cd ~/src/nghttp2
## autoreconf -i
## automake
## autoconf
##./configure PYTHON=/usr/bin/python3
## make
## sudo make install

## sudo updatedb
## locate libnghttp2.so.14

## sudo ln -s /usr/local/lib/libnghttp2.so.14 /lib/x86_64-linux-gnu/libnghttp2.so.14
## sudo ln -s /usr/local/lib/libnghttp2.so.14.0.2 /lib/x86_64-linux-gnu/libnghttp2.so.14.0.2
## sudo ldconfig

Bis hier angekommen? Wunderbar, jetzt kann mit folgenden „Befehlen“ die Installation überprüft werden. Bei allen 4 Überprüfungen dürfen keine Error-Meldungen erscheinen.

## nghttp --version
## nghttpx --version
## nghttpd --version
## h2load –version

Als nächstes die Log-Dateien anlegen.

## sudo mkdir /var/log/nghttpx
## sudo touch /var/log/nghttpx/access.log
## sudo touch /var/log/nghttpx/error.log

per ## vi /etc/nghttpx/nghttpx.conf (oder einen Editor Eures Vertrauens die Datei nghttpx.conf bearbeiten und entsprechend bearbeiten).

worker= # Hier wie in der nginx.conf schon bekannte Wert für die Anzahl der Prozessorkerne (in meinem Beispiel 4

frontend=*, # Port 443, da in dieser Konfiguration der Frontendport auf Port 443 lauschen soll.

backend=localhost, # Hier der Backendport welcher an Nginx angebunden wird (localhost kann auch durch 172.0.0.1 ersetzt werden).

tls-proto-list= # Standard ist hier TLSv1.2 und TLSv1.1. Da mir mit dieser Konfiguration aber zu viele Endgeräte (z.B. Windows 7 IE-8-10) keinen Zugriff bekommen, habe ich dieses mit TLSv1.0
ergänzt, mit den zugehörigen Ciphers-Suits.

dh-param-file= # Angabe zur dhparam.pem. Wie eine dh-param-file erstellt wird:
## cd /etc/ssl/certs
## openssl dhparam -out dhparam.pem 4096

# 4096 ist die Bit-Verschlüsselung. Hier kann auch 2048 gewählt werden, sollte das Root-Zertifikat eine 2048 Bit Größe aufweist. Die Erstellung eines Zertifikates dauert sehr lange an, dieses kann auch schon mal 1 Stunde dauern, je nach Serverkapazität.

private-key-file= # Hier wird der Pfad zum Privaten Schlüssel des Zertifikats angegeben.

certificate-file= # Hier wird der Pfad zum Zertifikat, Intermedia und Root Zertifikat eingegeben.

Der Eintrag mit den Logfiles sollte selbsterklärend sein.

add-x-forwarded-for= # yes sorgt hier dafür dass die IP-Adressen weiter gegeben werden, ansonsten erscheint in den Log-Files immer 127.0.0.1.

no-host-rewrite= # Wichtig für die korrekte Umleitung zu nginx.


Hier meine Beispielkonfiguration die ich für fruchthof24.de verwende.

workers=4
frontend=*,443
backend=localhost,4444
tls-proto-list=TLSv1.2,TLSv1.1,TLSv1.0
ciphers=ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH
+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256
-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-
SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
dh-param-file=/etc/ssl/certs/dhparam.pem
private-key-file=/opt/psa/var/certificates/dein-key.key
certificate-file=/opt/psa/var/certificates/dein-certificate.crt
accesslog-file=/var/log/nghttpx/access.log
errorlog-file=/var/log/nghttpx/error.log
add-x-forwarded-for=yes
no-host-rewrite=yes


Jetzt die nghttpx-init kopieren. Für geübte User kann natürlich auch der Dienst (nghttpx) zum Serverstart oder Stopp hinzugefügt werden.

## sudo ~/src/nghttp/contrib/nghttpx-init /etc/init.d/nghttpx

Wenn es Probleme geben sollte mit dem Dienst von nghttpx folgende Datei abändern und in der Variabel –daemon hinzufügen.

## vi /etc/init.d/nghttpx
DAEMON_ARGS="--conf /etc/nghttpx/nghttpx.conf --pid-file=$PIDFILE --daemon"

Jetzt fehlt noch das Anpassen der nginx Konfiguration. In meiner Vhost hatte ich für IP4 und IP6 die Änderungen von Port 443 auf 4444 vorgenommen. Dazu folgende add_header Einträge die natürlich entsprechend Individuell angepasst werden müssen. Wichtig und für die Funktion entscheidend ist ausschließlich die entsprechende Portänderung (in meinem Fall 4444).

Hier ein Beispiel von Fruchthof24.de.

server {
listen 4444;

server_name fruchthof24.de;
server_name www.fruchthof24.de;
server_name ipv4.fruchthof24.de;


# Aktiviert HTTP Strict Transport Security (HSTS)
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
# Verhindert Frame-Einbindung außerhalb der originalen Domain
add_header X-Frame-Options SAMEORIGIN;
# Veröffentlichung des öffentlichen Keys
add_header Public-Key-Pins 'pin-sha256="47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="; max-age=5184000; includeSubdomains;';

Nach allen Änderungen können die Dienste neu gestartet werden.

## sudo service nginx restart
## sudo service nghttpx restart

OCSP stapling ist in dieser Konfiguration auch aktiviert.

## nghttp -nv https://fruchthof24.de # Ändere die Domain mit den eigenen Domainname ab und überprüfe ob alle Protokolle angegeben werden:

root@s17479520:~# nghttp -nv https://fruchthof24.de
[ 0.003] Connected
[ 0.006][NPN] server offers:
* h2
* h2-16
* h2-14
* spdy/3.1
* http/1.1
Sollte hier h2, h2-16, h2-14, spdy/3.1 und http/1.1 angezeigt werden, wunderbar, Happy. 

Anbei noch ein Hinweis zur Serversicherheit, diese kann auf https://www.ssllabs.com kontrolliert werden.

ssl-report-fruchthof24

In meiner Umgebung war die Umsetzung etwas umfangreicher, da auf meinem System auch Plesk eingesetzt wird.

Eine Dokumentation zu nghttp2 findet man unter https://nghttp2.org/documentation/

 

Bitte geben Sie die Zeichenfolge in das nachfolgende Textfeld ein.

Die mit einem * markierten Felder sind Pflichtfelder.

  • Alpha-Patch bringt HTTP/2 für Nginx

    Zuerst einmal: sehr gute Anleitung, durchaus hilfreich! Mittlerweile gibt es auch eine erste Version eines Patches, der HTTP/2 direkt in Nginx bringt - ein Proxy-Setup wie hier ist dann nicht mehr nötig, wenn man vorher bereits eine SPDY-Konfiguration hatte geht das ohne weiteres.

    Ich habe das in meinem Blog einmal zusammengefasst - und auch selbst im Einsatz, diese Seite läuft mit Nginx 1.9.4 & HTTP/2: https://www.kadder.de/2015/08/nginx-http2-ueber-alpha-patch-verfuegbar/

Kontaktformular

Der Verkauf auf Fruchthof24.de wurde eingestellt.

Die Domain wie auch dieser Shop werden zum Kauf angeboten.

Bei Interesse können Sie ein Angebot per Email abgeben.