Nginx configuré avec http2 ne fournit pas HTTP / 2

33

J'ai un problème avec ma configuration Nginx. Je suis passé à nginx 1.9.6 pour tester http / 2 mais cela ne fonctionne pas sur mon serveur.

J'ai utilisé Ubuntu 14.04.2 LTS

Voici la sortie de 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

Et voici ma confostive:

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;

/...

Si je navigue sur mon site avec la dernière version de chrome, celui-ci est uniquement diffusé via http / 1.1.

throrin19
la source
1
Avez-vous vérifié la section des mises en garde sur nginx.com/blog/nginx-1-9-5
Drifter104
Avez-vous nettoyé le cache de votre navigateur? Essayez depuis une fenêtre de navigation privée.
JayMcTee
La fenêtre de navigation privée ne change rien. J'ai lu la section de mise en garde et la seule partie est la ssl_prefer_server_ciphersmais je n'ai pas d'erreur de poignée de main
throrin19
Ceci est dû à l'en-tête envoyé par le serveur Web. Votre serveur Web est-il configuré pour envoyer HTTP / 2.0?
Martin Barker

Réponses:

50

Je viens de rencontrer le même problème, mais je pense savoir pourquoi cela se produit. nginx 1.9.6 n’est pas un paquet standard sur Ubuntu 14.04, vous l’obtenez probablement d’un PPA nginx . C'est bien, mais ces paquets sont construits avec les bibliothèques de stock à partir de 14.04, c'est-à-dire OpenSSL 1.0.1f. Malheureusement , cette version de OpenSSL ne contient pas RFC7301 ALPN soutien qui est nécessaire pour la négociation HTTP / 2 appropriée; il ne prend en charge que le NPN maintenant obsolète. Il semble que Chrome ait déjà supprimé la prise en charge de NPN. Il est donc incapable de négocier une connexion HTTP / 2 sans ALPN. Par contre, Firefox 41 a toujours le support NPN et vous devriez pouvoir utiliser HTTP / 2 avec ça.

Vous pouvez tester votre serveur comme ceci - vous aurez besoin d'OpenSSL 1.0.2d installé sur votre client (exécutez openssl versionpour vérifier):

Test avec ALPN:

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

Si ALPN fonctionne, vous devriez voir:

ALPN protocol: h2

sinon vous aurez:

No ALPN negotiated

Test avec NPN:

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

Si cela fonctionne, vous obtiendrez:

Next protocol: (1) h2
No ALPN negotiated

Cela signifie qu’il négocie avec succès une connexion HTTP / 2 via NPN, comme le fait Firefox.

Alors, comment résoudre ça? Le seul moyen que je vois consiste à installer une version plus récente d’openssl à partir d’un PPA (j’utilise celui-ci pour PHP, qui contient également openssl) et de créer votre propre nginx qui y est lié. Vous pouvez trouver les paramètres de configuration de votre construction nginx existante en les exécutant nginx -V, et vous devriez pouvoir les utiliser pour créer votre propre version.

Mise à jour : j'ai découvert que la raison pour laquelle Chrome ne prend pas en charge HTTP / 2 avec NPN n'est pas due à l'absence de prise en charge de NPN (bien qu'il soit abandonné à un moment donné), mais spécifiquement à la prise en charge de h2 avec NPN, comme indiqué sur la page chrome: // net-internals / # http2:

Chrome HTTP / 2 info

Synchro
la source
Je viens de remarquer que vous utilisez déjà openssl 1.0.2d - mais les tests peuvent encore s'avérer utiles.
Synchro
Mon paquet nginx est compilé avec la dernière version de openssl, mais Ubuntu 14.04 a une version obsolète. Si je me souviens bien, c'est le 1.0.1f
throrin19
Oui, c'est ce que j'ai dit.
Synchro
Pour la première commande, j'ai eu une erreur unknown option -alpnet la deuxième commande fonctionne bien
throrin19
2
Quel est le statut de cette situation en ce début d'année 2016? Je vois encore que nginx ne sert pas les fichiers en HTTP2
vsync
3

Version courte.

J'ai constaté que l'antivirus ESET peut empêcher HTTP / 2 de fonctionner lorsque le filtrage SSL / TLS est activé sur l'ordinateur de navigation. Vérifiez que votre antivirus ne filtre pas le protocole SSL / TLS.


Version TLDR

J'ai rencontré le même problème que l'affiche, mais avec une tournure intéressante. J'ai mis à niveau la configuration de mon serveur vers nginx 1.12.1. compilé avec OpenSSL 1.0.2.g et lors de l’inspection initiale, il avait «résolu» le problème du non fonctionnement de HTTP / 2. Dans mon navigateur, je pouvais voir que le certificat du serveur avait été vérifié par Let's Encrypt. Le contenu était également servi avec HTTP / 2.

Quelque temps plus tard, j'ai constaté que la même page et les mêmes ressources n'étaient plus servies via HTTP / 2. Par coïncidence, le site n'a plus été vérifié par Let's Encrypt, mais par Eset? !!?! À mon grand étonnement, le nouveau problème http2 n'a rien à voir avec la configuration de mon serveur. Il s'est avéré que le filtre SSL / TLS était activé dans mon antivirus sur mon ordinateur local, ce qui était à l'origine du problème. La solution consistait à désactiver le filtrage SSL / TLS dans l'antivirus. Une fois que je l'avais éteint (et redémarré l'ordinateur), HTTP / 2 a fonctionné à nouveau et le certificat a été vérifié à nouveau par Let's Encrypt.

Pour savoir comment désactiver SSL / TLS dans ESET, consultez la page http://support.eset.com/kb3126/?locale=en_US.

TryHarder
la source
C'était le problème dans mon cas. M'a sauvé de la folie car il fonctionnait dans un navigateur (qui n'a pas été filtré par un pare-feu) mais pas dans un autre
Dev
Tu es un super génie. C'était ESET et j'avais passé mes 4 jours à trouver le problème. Je viens d'essayer tout ce qui est possible dans ce monde de Linux. Je ne peux tout simplement pas croire que c'était ESET et je martelais mon VPS.
Abdul Jabbar WebBestow
1
J'ai ouvert un ticket de support sur forum.eset.com/topic/…
Abdul Jabbar WebBestow
1

Comme le dit Synchro dans sa réponse, le problème est que la plupart des paquets nginx ne sont pas construits avec OpenSSL 1.0.2. La compilation d’ALPN requiert que les symboles ne soient présents que dans la source de développement OpenSSL appropriée.

Vous pouvez essayer d’utiliser la distribution officielle de nginx en sélectionnant xenial plutôt que fidèle. Cela fonctionne pour moi avec Debian Jessie et jessie-backports OpenSSL 1.0.2 - cela peut fonctionner pour vous. Cependant, sachez qu'il s'agit d'une configuration non prise en charge - la reconstruire est la "bonne" réponse.

GreenReaper
la source