Nginx skonfigurowany z http2 nie dostarcza HTTP / 2

33

Mam problem z moją konfiguracją Nginx. Uaktualniłem do wersji Nginx 1.9.6, aby przetestować http / 2, ale to nie działa na moim serwerze.

Użyłem ubuntu 14.04.2 LTS

To jest wyjście nginx -V:

nginx version: nginx/1.9.6
built with OpenSSL 1.0.2d 9 Jul 2015
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --with-pcre-jit --with-debug --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_realip_module --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-http_xslt_module --with-http_v2_module --with-stream --with-ipv6 --with-mail --with-mail_ssl_module --with-openssl=/build/nginx-GFP362/nginx-1.9.6/debian/openssl-1.0.2d --add-module=/build/nginx-GFP362/nginx-1.9.6/debian/modules/nginx-auth-pam --add-module=/build/nginx-GFP362/nginx-1.9.6/debian/modules/nginx-echo --add-module=/build/nginx-GFP362/nginx-1.9.6/debian/modules/nginx-upstream-fair --add-module=/build/nginx-GFP362/nginx-1.9.6/debian/modules/nginx-dav-ext-module --add-module=/build/nginx-GFP362/nginx-1.9.6/debian/modules/nginx-cache-purge

A to jest moja konfiguracja vhosta:

server {
    listen         80;
    server_name    localhost;
    return         301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2; ## listen for ipv4; this line is default and implied

    root /var/www/rendez-vous;
    index index.phtml index.html index.htm;

    # Make site accessible from http://localhost/
    server_name localhost;
    ssl_certificate /etc/nginx/certificates/myeventsportal/server.crt;
    ssl_certificate_key /etc/nginx/certificates/myeventsportal/server.key;

/...

Jeśli przejdę do mojej witryny z najnowszą wersją chrome, jest ona obsługiwana tylko przez http / 1.1.

throrin19
źródło
1
Czy sprawdziłeś sekcję o zastrzeżeniach na nginx.com/blog/nginx-1-9-5
Drifter104,
Czy wyczyściłeś pamięć podręczną przeglądarki? Spróbuj z okna incognito.
JayMcTee
Okno incognito nic nie zmienia. Przeczytałem sekcję dotyczącą zastrzeżeń, a jedyną częścią jest błąd, ssl_prefer_server_ciphersale nie mam błędu uzgadniania
throrin19,
Jest to spowodowane tym, że nagłówek wysłany z serwera to Twój serwer skonfigurowany do wysyłania HTTP / 2.0
Martin Barker,

Odpowiedzi:

50

Właśnie natrafiłem na ten sam problem, ale myślę, że wiem, dlaczego tak się dzieje. nginx 1.9.6 nie jest standardowym pakietem Ubuntu 14.04, więc prawdopodobnie otrzymujesz go z PPA nginx . W porządku, ale te pakiety są budowane przy użyciu bibliotek podstawowych od 14.04, czyli OpenSSL 1.0.1f. Niestety ta wersja OpenSSL nie zawiera obsługi RFC7301 ALPN, która jest potrzebna do prawidłowej negocjacji HTTP / 2; obsługuje tylko przestarzałe NPN. Wygląda na to, że Chrome już usunął obsługę NPN, więc nie jest w stanie negocjować połączenia HTTP / 2 bez ALPN. Z drugiej strony Firefox 41 nadal obsługuje obsługę NPN i powinieneś być w stanie korzystać z HTTP / 2.

Możesz przetestować swój serwer w ten sposób - będziesz musiał zainstalować OpenSSL 1.0.2d na swoim kliencie (uruchom, openssl versionaby sprawdzić):

Test z ALPN:

echo | openssl s_client -alpn h2 -connect yourserver.example.com:443 | grep ALPN

Jeśli ALPN działa, powinieneś zobaczyć:

ALPN protocol: h2

w przeciwnym razie otrzymasz:

No ALPN negotiated

Test z NPN:

echo | openssl s_client -nextprotoneg h2 -connect yourserver.example.com:443

Jeśli to zadziała, otrzymasz:

Next protocol: (1) h2
No ALPN negotiated

Oznacza to, że pomyślnie negocjuje połączenie HTTP / 2 przez NPN, co robi Firefox.

Jak to rozwiązać? Jedyny sposób, jaki widzę, to zainstalowanie późniejszej wersji openssl z PPA (używam tego dla PHP, który również zawiera openssl) i zbudowanie własnego powiązanego z nim nginx. Możesz znaleźć parametry konfiguracji dla istniejącej kompilacji nginx, uruchamiając nginx -Vi powinieneś być w stanie użyć ich do zbudowania własnej wersji.

Aktualizacja : Odkryłem, że powodem, dla którego Chrome nie obsługuje protokołu HTTP / 2 z NPN, nie jest to, że nie obsługuje on NPN (choć w pewnym momencie zostanie usunięty), ale że w szczególności nie obsługuje h2 z NPN, jak pokazano na stronie chrome: // net-internals / # http2:

Informacje o Chrome HTTP / 2

Synchro
źródło
Właśnie zauważyłem, że już uruchamiasz openssl 1.0.2d - ale testy mogą się okazać przydatne.
Synchro,
Mój pakiet nginx jest skompilowany z najnowszą wersją openssl, ale Ubuntu 14.04 ma nieaktualną wersję. O ile pamiętam, to 1.0.1f
throrin19
Tak właśnie powiedziałem.
Synchro,
W przypadku pierwszego polecenia wystąpił błąd, unknown option -alpna drugie polecenie działa dobrze
throrin19
2
Jaki jest status tego teraz, na skraju 2016 roku? Nadal widzę, że nginx nie wyświetla plików jako HTTP2
vsync
3

Krótka wersja.

Odkryłem, że program antywirusowy ESET może uniemożliwić działanie HTTP / 2, gdy filtrowanie SSL / TLS jest włączone na komputerze przeglądającym. Sprawdź, czy Twój program antywirusowy nie filtruje SSL / TLS.


Wersja TLDR

Wpadłem na ten sam problem co plakat, ale z ciekawym zwrotem akcji. Zaktualizowałem konfigurację serwera do wersji Nginx 1.12.1. skompilowany z OpenSSL 1.0.2.g i przy wstępnej inspekcji „rozwiązał” problem niedziałania HTTP / 2. W mojej przeglądarce widziałem, że certyfikat serwera został zweryfikowany przez Let's Encrypt. Treści były również dostarczane z HTTP / 2.

Jakiś czas później odkryłem, że ta sama strona i te same zasoby nie były już obsługiwane przez HTTP / 2. Przypadkowo strona nie była już weryfikowana przez Let's Encrypt, ale przez Eset? !!?! Ku mojemu zdziwieniu, nowy problem http2 nie miał nic wspólnego z konfiguracją mojego serwera. Okazało się, że miałem filtrowanie SSL / TLS w moim programie antywirusowym na moim komputerze lokalnym i to było przyczyną problemu. Rozwiązaniem było wyłączenie filtrowania SSL / TLS w programie antywirusowym. Po jego wyłączeniu (i ponownym uruchomieniu komputera) HTTP / 2 znów działało i certyfikat został ponownie zweryfikowany przez Let's Encrypt.

Aby dowiedzieć się, jak wyłączyć SSL / TLS w ESET, sprawdź http://support.eset.com/kb3126/?locale=en_US

Próbuj dalej
źródło
To był problem w moim przypadku. Uratował mnie od szaleństwa, ponieważ działał w jednej przeglądarce (która nie była filtrowana przez zaporę ogniową), ale nie w żadnej innej
Dev
Jesteś super geniuszem. To był ESET i spędziłem 4 dni na znalezieniu problemu. Właśnie próbowałem wszystkiego, co możliwe w tym świecie Linuksa. Po prostu nie mogę uwierzyć, że to był ESET i wbijałem swój VPS.
Abdul Jabbar WebBestow
1
Otworzyłem bilet pomocy technicznej na forum.eset.com/topic/…
Abdul Jabbar WebBestow
1

Jak mówi Synchro w swojej odpowiedzi, problem polega na tym, że większość pakietów nginx nie jest zbudowanych z OpenSSL 1.0.2. Kompilacja ALPN wymaga symboli obecnych tylko w odpowiednim źródle programowania OpenSSL.

Możesz spróbować użyć oficjalnej dystrybucji nginx , wybierając xenial zamiast zaufanego. Działa to dla mnie z Debianem Jessie i jessie-backports OpenSSL 1.0.2 - może działać dla ciebie. Należy jednak pamiętać, że jest to konfiguracja nieobsługiwana - przebudowanie jest odpowiedzią „właściwą”.

GreenReaper
źródło