11

I'm currently running a Ubuntu 16.04.1 LTS server using NGINX 1.11.9 and openssl 1.0.2g.

According to everything I've read, these versions should support ALPN, yet when I run a test on KeyCDN's HTTP/2 Test tool, I get "ALPN is not supported"screen capture of keycdn test report

And when I execute echo | openssl s_client -alpn h2 -connect example.com:443 | grep ALPN, I get:

depth=3 C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root
verify return:1
depth=2 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
verify return:1
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Domain Validation Secure Server CA
verify return:1
depth=0 OU = Domain Control Validated, OU = EssentialSSL Wildcard, CN = *.example.com
verify return:1
No ALPN negotiated
DONE

Not having ALPN enabled disables HTTP2 from being fully enabled. How do I enable ALPN?

EDIT

nginx -V shows:

nginx version: nginx/1.11.9
built by gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3)
built with OpenSSL 1.0.1f 6 Jan 2014 (running with OpenSSL 1.0.2g  1 Mar 2016)
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'

EDIT #2

openssl version -a output:

OpenSSL 1.0.2h  3 May 2016
built on: reproducible build, date unspecified
platform: linux-x86_64
options:  bn(64,64) rc4(16x,int) des(idx,cisc,16,int) idea(int) blowfish(idx)
compiler: gcc -I. -I.. -I../include  -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -Wa,--noexecstack -m64 -DL_ENDIAN -O3 -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM
OPENSSLDIR: "/usr/local/ssl"
Godwin
  • 401
  • 1
  • 4
  • 14
  • 1
    `built with OpenSSL 1.0.1f` — guess that's the answer – Alexey Ten Feb 09 '17 at 07:36
  • Where did you get your nginx? Probably you should stick with one that is in official ubuntu repo. It would be 1.10.0, but at least it would be built against right version of openssl – Alexey Ten Feb 09 '17 at 07:40
  • NGINX came with the Unbuntu distro I installed from my host, Digitalocean, it's also possible that this is due to the upgrade I performed from 14.04 to 16.04. It looks as though I need to rebuild NGINX somehow in order to solve this. – Godwin Feb 09 '17 at 15:52
  • Could you also add the output of `openssl version -a`, so that we can see if your OpenSSL was built with any unexpected flags/options? – Castaglia Feb 09 '17 at 17:36
  • @Castaglia, sure, I updated the question. – Godwin Feb 09 '17 at 17:59
  • nginx needs to be _built with_ OpenSSL 1.0.2 or higher, not simply _running_ with, in order to support ALPN. – Michael Hampton Feb 09 '17 at 18:57
  • Thanks @MichaelHampton, that's the conclusion we reached in the comments above, I now need to find out how to do that. – Godwin Feb 09 '17 at 19:02
  • I'd reinstall nginx or yell at the packager. – Michael Hampton Feb 09 '17 at 19:02

3 Answers3

11

As @AlexyTen pointed out, the root cause was that, although I had OpenSSL 1.0.2g installed, NGINX needed to be built with OpenSSL and it was built with 1.0.1f which does not support ALPN.

NGINX needs to be rebuilt with OpenSSL 1.0.2 or above and re-installed. I found a few tutorials online but because I am using a Digital Ocean server, I used this help topic to solve the issue for me: https://www.digitalocean.com/community/questions/how-to-get-already-installed-nginx-to-use-openssl-1-0-2-for-alpn

I first needed to install a few new libraries:

apt-get install libgeoip-dev libgd2-xpm-dev libperl-dev

I then just ran this script: https://gist.github.com/AJMaxwell/f6793605068813aae888216b02364d85

I restarted using sudo shutdown -r now and ran nginx -V again. This time it gave me:

nginx version: nginx/1.11.0
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)
built with OpenSSL 1.0.2h  3 May 2016
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_perl_module=dynamic --with-threads --with-stream --with-stream_ssl_module --with-http_slice_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6 --with-http_v2_module --with-openssl=/root/openssl-1.0.2h --add-module=/root/ngx_pagespeed-release-1.11.33.2-beta

I also ran keycdn's http2 test again and it passed.

Godwin
  • 401
  • 1
  • 4
  • 14
2

I have created a bash script that automatically downloads, compiles and installs Nginx with OpenSSL on Debian/Ubuntu, RHEL/CentOS and other distros. The resulting binary is exactly the same as the one that distributes Nginx through its official repository except that it comes with the latest version of OpenSSL.

The script does not modify the OpenSSL installation, only the Nginx binary. It is a good option if you don't want to rely on packages built and distributed by unofficial sources.

https://github.com/victordzmr/nginx-compiler

  • Why not rely on packages you build yourself instead of installing untracked binaries? – chicks Apr 29 '17 at 21:54
  • 1
    @chicks It is a script that builds Nginx, not a binary. Downloading binaries from unknown sources may be dangerous, hence I have created it. – Víctor Díaz May 02 '17 at 11:18
1

Install the nginx ppa and it will support ALPN:

sudo add-apt-repository ppa:nginx/stable
sudo apt update
sudo apt dist-upgrade -y
Nicolay77
  • 151
  • 2