Nginx configurado con http2 no entrega HTTP / 2

33

Tengo un problema con mi configuración de Nginx. Actualicé a nginx 1.9.6 para probar http / 2 pero no funciona en mi servidor.

Usé ubuntu 14.04.2 LTS

Esta es la salida 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

Y esta es mi configuración de vhost:

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 navego a mi sitio con la última versión de Chrome, solo se sirve a través de http / 1.1.

throrin19
fuente
1
¿Ha revisado la sección de advertencias en nginx.com/blog/nginx-1-9-5
Drifter104
¿Borraste la caché de tu navegador? Probar desde una ventana de incógnito.
JayMcTee
La ventana de incógnito no cambia nada. Leí la sección de advertencia y la única parte es el ssl_prefer_server_cipherserror
throrin19
Esto es causado por el encabezado enviado desde el servidor web si su servidor web está configurado para enviar HTTP / 2.0
Martin Barker

Respuestas:

50

Acabo de encontrarme con el mismo problema, pero creo que sé por qué sucede. nginx 1.9.6 no es un paquete estándar en Ubuntu 14.04, por lo que probablemente lo obtenga de un PPA nginx . Está bien, pero esos paquetes están construidos con las bibliotecas de valores de 14.04, es decir OpenSSL 1.0.1f. Desafortunadamente, esa versión de OpenSSL no contiene el soporte RFC7301 ALPN que se necesita para una negociación HTTP / 2 adecuada; solo es compatible con la NPN ahora en desuso. Parece que Chrome ya ha eliminado el soporte para NPN, por lo que es incapaz de negociar una conexión HTTP / 2 sin ALPN. Firefox 41, por otro lado, todavía tiene soporte NPN y debería poder usar HTTP / 2 con eso.

Puede probar su servidor de esta manera: necesitará OpenSSL 1.0.2d instalado en su cliente (ejecutar openssl versionpara verificar):

Prueba con ALPN:

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

Si ALPN está funcionando, debería ver:

ALPN protocol: h2

de lo contrario obtendrá:

No ALPN negotiated

Prueba con NPN:

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

Si eso funciona, obtendrá:

Next protocol: (1) h2
No ALPN negotiated

Eso significa que está negociando con éxito una conexión HTTP / 2 a través de NPN, que es lo que hace Firefox.

Entonces, ¿cómo resolver esto? La única forma en que puedo ver es instalar una compilación posterior de openssl desde un PPA (uso esta para PHP, que también contiene openssl) y construir su propio nginx vinculado a él. Puede encontrar los parámetros de configuración para su compilación nginx existente ejecutando nginx -V, y debería poder usarlos para construir su propia versión.

Actualización : descubrí que la razón por la que Chrome no es compatible con HTTP / 2 con NPN no es que no sea compatible con NPN (aunque se eliminará en algún momento), sino que específicamente no es compatible con h2 con NPN, como se muestra en la página chrome: // net-internals / # http2:

Información de HTTP / 2 de Chrome

Synchro
fuente
Acabo de notar que ya está ejecutando openssl 1.0.2d, pero las pruebas aún pueden resultar útiles.
Sincronización
Mi paquete nginx está compilado con la última versión de openssl, pero ubuntu 14.04 tiene una versión desactualizada. Si no recuerdo
mal
Sí, eso es lo que dije.
Synchro
Para el primer comando, recibí un error unknown option -alpny el segundo comando funciona bien
throrin19
2
¿Cuál es el estado de esto ahora, a finales de 2016? Todavía veo que nginx no sirve archivos como HTTP2
vsync
3

Version corta.

Descubrí que el antivirus ESET puede evitar que HTTP / 2 funcione cuando el filtrado SSL / TLS está activado en la computadora de navegación. Verifique que su antivirus no esté filtrando SSL / TLS.


Versión TLDR

Me encontré con el mismo problema que el póster, pero con un giro interesante. Actualicé la configuración de mi servidor a nginx 1.12.1. compilado con OpenSSL 1.0.2.g y en la inspección inicial había "resuelto" el problema de HTTP / 2 no funcionaba. En mi navegador, pude ver que Let's Encrypt verificó el certificado del servidor. El contenido también se estaba sirviendo con HTTP / 2.

Algún tiempo después, descubrí que la misma página y los mismos recursos ya no se servían a través de HTTP / 2. Casualmente, el sitio ya no fue verificado por Let's Encrypt, sino por Eset? !!?! Para mi sorpresa, el nuevo problema http2 no tuvo nada que ver con la configuración de mi servidor. Resultó que tenía filtrado SSL / TLS en mi antivirus en mi computadora local y esto estaba causando el problema. La solución fue desactivar el filtrado SSL / TLS en el antivirus. Una vez que lo apagué (y reinicié la computadora) HTTP / 2 funcionó nuevamente y Let's Encrypt volvió a verificar el certificado.

Para obtener instrucciones sobre cómo desactivar SSL / TLS en ESET, consulte http://support.eset.com/kb3126/?locale=en_US

Esforzarse más
fuente
Este fue el problema en mi caso. Me salvó de la locura, ya que funcionaba en un navegador (que no fue filtrado por el firewall) pero no en ningún otro
Dev
Eres un super genio. Era ESET y había pasado mis 4 días buscando el problema. Acabo de probar todo lo posible en este mundo de Linux. Simplemente no puedo creer que fue ESET y estaba golpeando mi VPS.
Abdul Jabbar WebBestow
1
He abierto un ticket de soporte en forum.eset.com/topic/…
Abdul Jabbar WebBestow
1

Como Synchro dice en su respuesta, el problema es que la mayoría de los paquetes nginx no están construidos con OpenSSL 1.0.2. La compilación de ALPN requiere símbolos solo presentes en la fuente de desarrollo de OpenSSL relevante.

Puede intentar usar la distribución oficial nginx , seleccionando xenial en lugar de confiable. Esto funciona para mí con Debian Jessie y jessie-backports OpenSSL 1.0.2, puede funcionar para usted. Sin embargo, tenga en cuenta que es una configuración no admitida: reconstruirla es la respuesta "correcta".

GreenReaper
fuente