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"
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"
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:
I then just ran this script: https://gist.github.com/AJMaxwell/f6793605068813aae888216b02364d85
I restarted using
sudo shutdown -r now
and rannginx -V
again. This time it gave me:I also ran keycdn's http2 test again and it passed.
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
Install the nginx ppa and it will support ALPN: