Webserver.tips

Nginx auf EC2 mit Amazon Linux selbst kompilieren

Warum eigentlich?

Requests stehen Schlange

Im März 2016 hat Google die Unterstützung für SPDY aus Chrome entfernt. Damit wollen sie das HTTP/2 Protokoll unterstützen. Das ist an sich lobenswert, allerdings müssen Seiten, die nginx einsetzen, aktiv werden und HTTP/2 auch anbieten.

Die stable-Version 1.8.1 von nginx unterstützt nämlich nur das SPDY Protokoll, nicht HTTP/2. Das bedeutet, das Seiten, die auf dieser nginx-Version laufen, auf HTTP 1.1 zurückfallen. Auf Serverseite ist kaum zu bemerken, dass die Requests wieder Schlange stehen - die längeren Ladezeiten fallen hauptsächlich den Bemtuzern auf.

Wer seinen nginx auf einer AWS EC2 Instanz unter Amazon Linux betreibt, ist besonders betroffen, denn dort ist derzeit keine neuere Version von nginx verfügbar.

Da es scheinbar auch bei nginx.org kein passendes Paket für Amazon Linux mit einer neueren Version gibt, muss man selbst Hand anlegen und nginx selbst kompilieren.

Die OpenSSL-Falle

Das ist an sich keine große Sache, wer damit aber denkt, das Problem gelöst zu haben, wird spätestens bei einem Test mit Chrome eines besseren belehrt. Chrome zeigt noch immer an, dass HTTP 1.1 verwendet wird.

Das liegt an der OpenSSL Version. Amazon stellt hier OpenSSL 1.0.1k bereit, allerdings unterstützt diese Version noch kein ALPN, so dass Chrome kein HTTP/2 aushandelt. Nginx benötigt mindestens OpenSSL 1.0.2, damit ALPN funktioniert.

So geht es

Vorbereitung:

# pwd
/home/ec2-user/

# mkdir software

# cd software

Zuerst die korrekte OpenSSL-Version holen und entpacken:

# curl -O https://www.openssl.org/source/openssl-1.0.2h.tar.gz
# tar -xvf openssl-1.0.2h.tar.gz

Tatsächlich muss diese Version von OpenSSL nicht installiert werden, nginx benötigt nur die Quellen.

Dann die neue nginx-Version holen:

# curl -O http://nginx.org/download/nginx-1.10.1.tar.gz
# tar -xvf nginx-1.10.1.tar.gz
# cd nginx-1.10.1

Nun nginx konfigurieren und kompilieren.

Dem Binary geben wir einen eindeutigen Namen, damit wir zur ursprünglich installierten Version zurückkönnen, wenn etwas nicht funktioniert. Die Optionen können angepasst werden, allerdings kommt es bei den SSL-Optionen auf die Reihenfolge an.

# ./configure --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx-1.10 --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/lock/subsys/nginx --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-pcre --with-pcre-jit --with-debug --with-http_auth_request_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' --with-ld-opt=' -Wl,-E' --with-openssl=/home/ec2-user/software/openssl-1.0.2h --with-http_ssl_module

# make

# sudo make install

Achtung: Gegenüber der nginx Konfiguration im Amazon Linux Paket fehlen hier diese Optionen:

--with-http_xslt_module
--with-http_image_filter_module
--with-http_perl_module
--with-http_geoip_module
--with-google_perftools_module

Wer sie benötigt, kann sie ergänzen, muss dann aber evtl. noch weitere Pakete installieren.

Für den neuen nginx sollte man eine entsprechende Service-Datei anlegen. Die bestehende wird bei nginx-Updates durch den Package-Manager überschrieben. Dabei kann man die bestehende als Vorlage nehmen:

sudo cp /etc/init.d/nginx /etc/init.d/nginx-1.10

Und in der Service-Datei auf das neue Binary umstellen:

# sudo vi /etc/init.d/nginx-1.10

In dieser Datei müssen zwei Zeilen angepasst werden:

pidfile="/var/run/${prog}.pid" -> pidfile="/var/run/nginx.pid"
nginx="/usr/sbin/nginx" -> nginx="/usr/sbin/nginx-1.10"

Bevor man jetzt nginx neu startet, sollten zuerst alle "spdy" Parameter aus der Konfigurationsdatei entfernt werden, denn die funktionieren nach dem Update nicht mehr, und durch den "http2"-Parameter ersetzen.

Jetzt den "alten" nginx anhalten:

# sudo service nginx stop

Und den "neuen" nginx starten:

# sudo service nginx-1.10 start

Und damit sollte dann auch Chrome das korrekte Protokoll anzeigen.

Anzeige des HTTP/2 Protokolls in der Chrome-Konsole
@Digitalkapitaen

Ein Projekt von Digital Sailors