30

I have a problem with my Nginx configuration. I upgraded to nginx 1.9.6 to test http/2 but it does not work on my server.

I used ubuntu 14.04.2 LTS

This is the nginx -V output :

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

And this is my vhost config :

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;

/...

If I navigate to my site with the latest version of chrome, it is only served over http/1.1.

  • 1
    Have you checked the caveats section on nginx.com/blog/nginx-1-9-5 – Drifter104 Oct 29 '15 at 12:00
  • Did you wipe your browser cache? Try from an Incognito Window. – JayMcTee Oct 29 '15 at 13:58
  • The incognito Window change nothing. I read the caveat section and the only part is the ssl_prefer_server_ciphers but i have not handshake error – throrin19 Oct 29 '15 at 15:52
  • This is caused by the header sent from the web server is your web server configured to send HTTP/2.0 – Martin Barker Nov 2 '15 at 17:14
48
+50

I've just run into the same problem, but I think I know why it happens. nginx 1.9.6 is not a stock package on Ubuntu 14.04, so you're probably getting it from an nginx PPA. That's fine, but those packages are built with the stock libraries from 14.04, which is to say OpenSSL 1.0.1f. Unfortunately that version of OpenSSL does not contain RFC7301 ALPN support which is needed for proper HTTP/2 negotiation; it only supports the now-deprecated NPN. It looks like Chrome has already removed support for NPN, so it's incapable of negotiating an HTTP/2 connection without ALPN. Firefox 41 on the other hand, still has NPN support and you should be able to use HTTP/2 with that.

You can test your server like this - you will need OpenSSL 1.0.2d installed on your client (run openssl version to check):

Test with ALPN:

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

If ALPN is working, you should see:

ALPN protocol: h2

otherwise you'll get:

No ALPN negotiated

Test with NPN:

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

If that works, you will get:

Next protocol: (1) h2
No ALPN negotiated

That means that it's successfully negotiating an HTTP/2 connection via NPN, which is what Firefox does.

So how to solve this? The only way I can see is to install a later build of openssl from a PPA (I use this one for PHP, which also contains openssl) and build your own nginx linked to it. You can find the config params for your existing nginx build by running nginx -V, and you should be able to use that to build your own version.

Update: I've discovered that the reason that Chrome doesn't support HTTP/2 with NPN is not that it doesn't support NPN (though it will be dropped at some point), but that it specifically doesn't support h2 with NPN, as shown on the chrome://net-internals/#http2 page:

Chrome HTTP/2 info

  • I just noticed that you are already running openssl 1.0.2d - but the tests may still prove useful. – Synchro Nov 3 '15 at 12:59
  • My nginx package is compiled with the latest openssl version but ubuntu 14.04 has an outdated version. If i remember, it's the 1.0.1f – throrin19 Nov 3 '15 at 13:56
  • Yes, that's what I said. – Synchro Nov 3 '15 at 13:57
  • For the first command, i got an error unknown option -alpn and the second command works fine – throrin19 Nov 3 '15 at 14:09
  • 2
    What's the status of this now, at the edge of 2016? I still see nginx not serving files as HTTP2 – vsync Dec 30 '16 at 21:31
3

Short version.

I found that ESET antivirus can prevent HTTP/2 from working when SSL/TLS filtering is turned on, on the browsing computer. Check to see that your antivirus is not filtering the SSL/TLS.


TLDR version

I ran into the same problem as the poster, but with an interesting twist. I upgraded my server configuration to nginx 1.12.1. compiled with OpenSSL 1.0.2.g and on initial inspection it had “solved” the problem of HTTP/2 not working. In my browser, I could see that the server certificate was verified by Let’s Encrypt. Content was also being served with HTTP/2.

Some time later, I found that the very same page and same resources were no longer being served over HTTP/2. Coincidentally, the site was no longer verified by Let’s Encrypt, but by Eset?!!?! To my amazement, the new http2 problem had nothing to do with my server configuration at all. It turned out that I had SSL/TLS filtering on in my antivirus on my local computer and this was causing the issue. The solution was to turn off SSL/TLS filtering in the antivirus. Once I had turned it off (and rebooted the computer) HTTP/2 worked again and the certificate was verified by Let’s Encrypt again.

For instructions on how to turn off SSL/TLS in ESET, check out http://support.eset.com/kb3126/?locale=en_US

  • This was the issue in my case. Saved me from insanity as it was working in one browser(which was not filtered by firewall) but not in any other – Dev Sep 21 '18 at 11:42
  • You are a super genius. It was ESET and I had spent my 4 days in finding the problem. I just tried everything possible in this world of Linux. I just can't believe it was ESET and I was hammering my VPS. – Abdul Jabbar WebBestow Nov 20 '18 at 20:30
  • 1
    I have opened a support ticket at forum.eset.com/topic/… – Abdul Jabbar WebBestow Nov 22 '18 at 11:28
1

As Synchro says in his answer, the issue is most nginx packages are not built with OpenSSL 1.0.2. Compilation of ALPN requires symbols only present in the relevant OpenSSL development source.

You could try using the official nginx distribution, selecting xenial rather than trusty. This works for me with Debian Jessie and jessie-backports OpenSSL 1.0.2 - it may work for you. However, be aware that it is an unsupported configuration - rebuilding it is the "right" answer.

-4

I'm sure the use OF HTTP has nothing major to do with nginx but the web servers it's self if your using apache2 i would recommend you read this site. https://www.gatherdigital.co.uk/blog/how-to-setup-http-2-support/527

It has all the information about HTTP/2 adoption and shows what i thought was correct apache2 does not support HTTP/2 by default yet and you require a module for it so please read that article and check your web server is configured.

  • i think you have not read the problem – throrin19 Nov 2 '15 at 20:50
  • i have you have provided all information for ngix nothing about how your web server is configured. Turn ngix off localhost and connect to your web server on localhost and see if HTTP/2 is being used if not your server is not serving http/2 – Martin Barker Nov 3 '15 at 11:49

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.