Enable HTTP/2 Support for Nginx on Debian Jessie

When I was tried to enable HTTP/2 for www.admon.org, I noticed that there is not much resource on how to enable HTTP/2 on Debian Jessie. I think the point is that there are some dependencies on HTTP/2, which are kinda difficult to fix on an relatively old distribution.

HTTP/2 Dependencies:

  • ALPN – OpenSSL 1.0.2+ (or LibreSSL 2.1.3+, or Google’s BoringSSL), HTTP/2 needs ALPN to negotiate protocol between server and client.
  • Nginx – Nginx 1.9.5+

Currently Ubuntu 16.04 LTS and Debian Stretch meet these needs. But on Debian Jessie, we have to compile from scratch. Here I posted an optimised solution for rebuilding Nginx on Debian 8. The benefits are,

To optimise algorithm selection, the ssl_ciphers needs to be configed as below in Nginx,


Prepare the build environment

sudo apt-get install -y build-essential libpcre3 libpcre3-dev zlib1g-dev golang
sudo apt-get install -y cmake-data cmake libtiffxx5 libexpat1-dev libpng12-dev libfreetype6-dev pkg-config libfontconfig1-dev libjpeg62-turbo-dev libjpeg-dev xorg-sgml-doctools x11proto-core-dev libxau-dev libxdmcp-dev

Create BoringSSL library

wget [http://nginx.org/download/nginx-1.10.2.tar.gz]
git clone https://boringssl.googlesource.com/boringssl
cd boringssl && export CFLAGS="-Wno-error"
mkdir build && cd build && cmake ../ && make && cd ../
mkdir -p .openssl/lib && cd .openssl && ln -s ../include . && cd ../
cp build/crypto/libcrypto.a build/ssl/libssl.a .openssl/lib
cd ../

Compile Nginx

cd nginx-1.10.2
touch ../boringssl/.openssl/include/openssl/ssl.h && ./configure --with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-file-aio --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_secure_link_module --with-http_sub_module --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module --with-openssl=../boringssl_
make && make install

Now we are almost done.
Open your Nginx configuration file, and enable the HTTP/2 by suffixing additional parameters as this,

listen 443 ssl http2 fastopen=3 reuseport;

ssl_ciphers needs to be updated as mentioned above.
Finally restart the nginx instance to make changes take effect.

Note: If you are running Debian Jessie 8.7, you can use the binary that created days ago.

[updated@2017-02-04: Removed the statement “HTTP/2 Only supports HTTPS“, refer to mod_h2. Thanks Georgi Naplatanov]

8 thoughts on “Enable HTTP/2 Support for Nginx on Debian Jessie

  1. Hi,

    Just found you post in searching for a safe mode to activate my http2 on my nginx but huh to compile everything from zero and move stuffs … huh not really so easy way and some downtime for my 10k users. I was looking for something just to install via apt-get … without to remove other things … . Anyway I have saved your page to use it on my next VPS setup, in time have found it http://serverfault.com/questions/775298/debian-jessie-nginx-with-openssl-1-0-2-to-use-alpn-rather-than-npn an faster alternative to say, didn’t try yet, need some time to be prepaired to fix it if will be some problems.

    Nice post,

  2. Sorry,
    I’m trying to install it on the other vps, but got this error.

    root@road:~/src/nginx-1.11.10# make
    make -f objs/Makefile
    make[1]: Entering directory ‘/root/src/nginx-1.11.10’
    cd ../boringssl_ \
    && if [ -f Makefile ]; then make clean; fi \
    && ./config –prefix=/root/src/nginx-1.11.10/../boringssl_/.openssl no-shared \
    && make \
    && make install_sw LIBDIR=lib
    /bin/sh: 1: cd: can’t cd to ../boringssl_
    objs/Makefile:1778: recipe for target ‘../boringssl_/.openssl/include/openssl/ssl.h’ failed
    make[1]: *** [../boringssl_/.openssl/include/openssl/ssl.h] Error 2
    make[1]: Leaving directory ‘/root/src/nginx-1.11.10’
    Makefile:8: recipe for target ‘build’ failed
    make: *** [build] Error 2

    Everything was perfect till here. Any way to fix it ?

  3. Does the file boringssl_/.openssl/include/openssl/ssl.h exists? It looks the dir “include” does not linked well.

  4. Yes is there, but maybe you write something wrong, because in touch file you add “../boringssl/” and for –with-openssl=../boringssl_ you have used “../boringss_ .

  5. Found a fix via http://www.zhanghaijun.com/post/970/

    nano nginx-1.11.10/auto/lib/openssl/conf
    find CORE_INCS=”$CORE_INCS $OPENSSL/.openssl/include” and CORE_DEPS=”$CORE_DEPS $OPENSSL/.openssl/include/openssl/ssl.h” and remove “/.openssl” leave like this.

    CORE_DEPS=”$CORE_DEPS $OPENSSL/include/openssl/ssl.h”
    CORE_LIBS=”$CORE_LIBS $OPENSSL/.openssl/lib/libssl.a”
    CORE_LIBS=”$CORE_LIBS $OPENSSL/.openssl/lib/libcrypto.a”

    Than start again
    make clean
    touch ../boringssl/.openssl/include/openssl/ssl.h && ./configure –with-cc-opt=’-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2′ –with-ld-opt=’-Wl,-z,relro -Wl,-z,now’ –prefix=/usr/share/nginx –conf-path=/etc/nginx/nginx.conf –http-log-path=/var/log/nginx/access.log –error-log-path=/var/log/nginx/error.log –lock-path=/var/lock/nginx.lock –pid-path=/run/nginx.pid –modules-path=/usr/lib/nginx/modules –http-client-body-temp-path=/var/lib/nginx/body –http-fastcgi-temp-path=/var/lib/nginx/fastcgi –http-proxy-temp-path=/var/lib/nginx/proxy –http-scgi-temp-path=/var/lib/nginx/scgi –http-uwsgi-temp-path=/var/lib/nginx/uwsgi –with-debug –with-pcre-jit –with-http_ssl_module –with-http_stub_status_module –with-http_realip_module –with-http_auth_request_module –with-http_v2_module –with-file-aio –with-threads –with-http_addition_module –with-http_geoip_module=dynamic –with-http_gunzip_module –with-http_gzip_static_module –with-http_image_filter_module=dynamic –with-http_secure_link_module –with-http_sub_module –with-stream=dynamic –with-stream_ssl_module –with-mail=dynamic –with-mail_ssl_module –with-openssl=../boringssl
    make install

    –with-ipv6 is deprechaced in my version nginx-1.11.10

    Hope anyone else have this problem this to be their fix.

  6. does wheezy support below?

    Do not enable this feature unless the server can handle receiving the same SYN packet with data more than once.

    This currently works only on Linux 3.9+

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.