Linuxspicker

Admins kleiner Zettelkasten für die Lösung von Linuxproblemen

HTTP/3 mit Nginx - setsockopt(TCP_NODELAY) failed (9: Bad file descriptor) while reading response header from upstream

Neben der Cloudflare-Lösung für nginx 1.16.x gibt es inzwischen eine Beta-Version von nginx für die Integration von HTTP/3 (QUIC) in Nginx und damit die nächste auf UDP aufbauende Version des Hypertext Transfer Protokolls. Da Cloudflare ziemlich stark genutzt wird, blinkt, wenn man zum Beispiel die „HTTP Version Indicator“-Erweiterung nutzt, auf vielen Seiten ein grüner Blitz für die Nutzung von HTTP/3 entgegen. Das will ich auch haben!

Die Nginx-Leute haben dafür inzwischen eine Roadmap veröffentlicht und noch einmal auf die experimentielle Codebasis hingewiesen, die inzwischen an die Version 1.21.1 herangeführt wurde. Compiliert ist der Code standardmäßig wie in der Readme beschrieben recht schnell. Erforderlich ist dazu auch die BoringSSL von Google.

Folgende Befehle helfen weiter:

git clone https://boringssl.googlesource.com/boringssl
mkdir boringssl/build
cd boringssl/build
cmake ..
make

für den Nginx dann vorausgesetzt die BoringSSL-Bibliothek ist auf der gleichen Höhe in der Verzeichnishierarchie diese:

auto/configure --with-debug --with-http_v3_module --with-http_quic_module --with-stream_quic_module --with-cc-opt="-I../boringssl/include" --with-ld-opt="-L../boringssl/build/ssl -L../boringssl/build/crypto"
make
make install

Mit diversen Modulen wie Brotli und festgelegten Pfaden sieht die Chose dann so aus:

auto/configure --with-http_v2_module --with-http_gzip_static_module --with-http_ssl_module --with-http_realip_module --with-http_stub_status_module --http-proxy-temp-path=/tmp/nginx/proxy_temp --http-fastcgi-temp-path=/tmp/nginx/fastcgi_temp --http-uwsgi-temp-path=/tmp/nginx/uwsgi_temp --http-scgi-temp-path=/tmp/nginx/scgi_temp --http-client-body-temp-path=/tmp/nginx/client_body_temp --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --conf-path=/etc/nginx/nginx.conf --user=www-data --group=www-data --add-module=../ngx_brotli --add-module=../ngx_geoip2 --build=nginx-quic --with-debug --with-http_v3_module --with-http_quic_module --with-stream_quic_module --with-cc-opt=-I../boringssl/include --with-ld-opt='-L../boringssl/build/ssl -L../boringssl/build/crypto'
make
make install

aktuell erhält man dann eine nginx-Datei von 13 Megabyte und mit folgender Ausgabe von nginx -V

nginx version: nginx/1.21.1 (nginx-quic)
built with OpenSSL 1.1.1 (compatible; BoringSSL) (running with BoringSSL)
TLS SNI support enabled

In den jeweiligen Server-Abschnitt muss dann noch

listen 443 http3;
listen 443 ssl;

eingefügt werden. Der Hinweis für die Browser auf die verfügbare HTTP/3-Version erfolgt dann über einen Zusatzheader beispielsweise in location /

add_header Alt-Svc 'h3=":443"; ma=86400';
add_header QUIC-Status $quic;

Die $quic-Variable hat nur dann einen Wert, wenn wirklich eine HTTP/3-Verbindung aufgebaut wurde.

Bei meiner Standardkonfiguration wollte sich partout jedoch nach der Integration von HTTP/3 keine Verbindung aufbauen lassen. Die Errorlog-Datei gab ständig diesen Fehler aus: setsockopt(TCP_NODELAY) failed (9: Bad file descriptor) while reading response header from upstream. Eine Standardsuche ergab dazu rein gar nichts. Die Lösung versteckt sich allerdings in der Fehlermeldung selbst. TCP_NODELAY stört. Standardmäßig ist TCP_NODELAY bei Nginx aktiviert. Ein tcp_nodelay off; in der nginx.conf beseitigte die Fehlermeldung und lässt jetzt unter anderem auf dieser Seite den grünen Blitz erscheinen. Es flutscht …

Bei der Aktivierung von HTTP/3 gilt es auch zu beachten, dass der verwendete UDP-Port in der Firewall/IPTables freigeschalten werden muss.

Ein komplettes Script zum Backen von Nginx-Quic auf der Basis von BoringSSL könnte dann so aussehen:


#!/bin/bash
date=`date +%F`

mkdir /src/webserver/nginx-quic-$date
cd /src/webserver/nginx-quic-$date
git clone https://boringssl.googlesource.com/boringssl
mkdir boringssl/build
cd boringssl/build
cmake ..
make
cd ../..

hg clone https://hg.nginx.org/nginx-quic
cd nginx-quic
hg update quic
auto/configure --with-http_v2_module --with-http_gzip_static_module --with-http_ssl_module --with-http_realip_module --with-http_stub_status_module --http-proxy-temp-path=/tmp/nginx/proxy_temp --http-fastcgi-temp-path=/tmp/nginx/fastcgi_temp --http-uwsgi-temp-path=/tmp/nginx/uwsgi_temp --http-scgi-temp-path=/tmp/nginx/scgi_temp --http-client-body-temp-path=/tmp/nginx/client_body_temp --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --conf-path=/etc/nginx/nginx.conf --user=www-data --group=www-data --add-module=../../ngx_brotli --add-module=../../ngx_geoip2 --build=nginx-quic --with-debug --with-http_v3_module --with-http_quic_module --with-stream_quic_module --with-cc-opt=-I../boringssl/include --with-ld-opt='-L../boringssl/build/ssl -L../boringssl/build/crypto'
make

*Update*:
Mit der Integration von HTTP/3 in den "*Hauptentwicklungszweig ab Version 1.25.0*":https://nginx.org/en/CHANGES  ist das nginx-quic-Repository obsolet geworden. Statt _hg clone https://hg.nginx.org/nginx-quic_ ist nun ein _hg clone http://hg.nginx.org/nginx_ erforderlich. Danach läuft das Script aber wie gewohnt durch.


Stichworte: , , , , , , , ,
Kategorien: ,


Kommentare

Keine Kommentare

Kommentare

Geben Sie Ihren Kommentar hier ein. * Eingabe erforderlich. Sie müssen die Vorschau vor dem Absenden ansehen.