TUTORIAL HOWTO build nginx with HTTP 2 support

Gizmo

Well-known member
Joined
Jun 8, 2021
Messages
524
Awards
4
Offline

HOWTO build nginx with HTTP 2 support​

Again not mine and a bit old but helpfully none the less
September 29, 2015
UPDATE 02-29-2016 a reader had issues getting this working, and after reproducing his issue I found that thessl_cipers HIGH:!aNULL:!MD5;no longer works. Apparently sometime after I wrote this, the HTTP/2 specs were updated, and browsers followed suit. This blog post tells us, “According to the HTTP/2 specification, over TLS 1.2 HTTP/2 SHOULD NOT use any of the cipher suites that are listed in the cipher suite black list, found here” So now, we have to call out another cipher before the blacklisted onesssl_ciphers AESGCM:HIGH:!aNULL:!MD5Thanks for the note Elias!
Last week nginx relased mainline version 1.9.5 which features experimental HTTP/2 module. According to the Internet Engineering Task ForceHTTP/2 enables a more efficient use of network resources and a reduced perception of latency by introducing header field compression and allowing multiple concurrent exchanges on the same connection. It also introduces unsolicited push of representations from servers to clients. This specification is an alternative to, but does not obsolete, the HTTP/1.1 message syntax. HTTP’s existing semantics remain unchanged.” You can get an idea of how HTTP/2 is better and faster on this demo page which shows the multiple connections making a significant difference.
TL;DR it’s faster, backwards compatible and the new hotness (obviously).

Start​

Install required software​

OpenSSL​

Like the SPDY project from Google (which they will deprecate in 2016), HTTP/2 runs over SSL only. To accept connections over TLS it uses the Application-Layer Protocol Negotiation (ALPN) TLS extension which is available only since OpenSSL version 1.0.2. So the first thing is that you need a (very) current version of OpenSSL installed. This was my first snag, as my server was running Squeeze, which was only running a 1.0.1 varient. My soltion was to upgrade to Stretch, after that, updating SSL gave me 1.0.2d, and we were ready to move on
# cat /etc/issue.net
Debian GNU/Linux stretch/sid
# openssl version
OpenSSL 1.0.2d 9 Jul 2015

Build and app software​

To build nginx from source we’re going to need some general build software, Debian is awesome about that by packing the general ones inbuild-essential. There’s a few other things we need, so we’ll get it done with the following line.
apt-get -y install build-essential zlib1g-dev libpcre3 libpcre3-dev libbz2-dev libssl-dev tar unzip curl

nginx​

Now on to the star of the show, nginx, with the latest release of the mainline branch, 1.9.5.
wget http://nginx.org/download/nginx-1.9.5.tar.gz
tar -xzvf nginx-1.9.5.tar.gz
cd nginx-1.9.5

Now we’ll configure the code, I used the basic Debian settings, but noticed I enable HTTP/2 with the flag--with-http_v2_module
./configure \
--prefix=/usr/share/nginx \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--user=www-data \
--group=www-data \
--without-mail_pop3_module \
--without-mail_imap_module \
--without-mail_smtp_module \
--without-http_fastcgi_module \
--without-http_uwsgi_module \
--without-http_scgi_module \
--without-http_memcached_module \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-http_v2_module

~30 seconds
Next, we can compile the source:
make

~ 3 minutes
And finally, install:
make install

Check and ensure we have the right version installed, and the http v2 module enabled:
root@scw-4d84f1:/etc/nginx# nginx -V
nginx version: nginx/1.9.5
built by gcc 5.2.1 20150911 (Debian 5.2.1-17)
built with OpenSSL 1.0.2d 9 Jul 2015
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --pid-path=/var/run/nginx.pid --lock-path=/var/lock/nginx.lock --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --user=www-data --group=www-data --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module --without-http_fastcgi_module --without-http_uwsgi_module --without-http_scgi_module --without-http_memcached_module --with-http_ssl_module --with-http_stub_status_module --with-http_gzip_static_module --with-http_v2_module

OpenSSL​

To setup OpenSSL I didn’t want to reinent the wheel, so here I take a good howto from Digital Ocean. Change anything you don’t like, but the condensed steps are:
mkdir /etc/nginx/ssl
cd /etc/nginx/ssl
openssl genrsa -des3 -out server.key 2048
openssl req -new -key server.key -out server.csr
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

nginx config​

Next configure nginx so it knows to use HTTP/2:
cd /etc/nginx
vi nginx.conf

By adding the follwoing block to the end of the file (but still before the})
# HTTPS server
#
server {
listen 443 ssl http2;
server_name localhost;

ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;

ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;

ssl_ciphers AESGCM:HIGH:!aNULL:!MD5
ssl_prefer_server_ciphers on;

location / {
root /var/www/html;
index index.html index.htm;
}
}

Test that the configs and paths are all good to go:
nginx -t

If there aren’t any issues, start it up (we installed from source so there’s no init or systemd scripts yet):
nginx

Default webpage​

Let’s put up a test webpage on the server, might as well pull an HTTP/2 spec page for that:
curl http://http2.github.io/http2-spec/index.html -o /var/www/html/index.html
chown -R www-data:www-data /var/www/html/index.html

Testing​

Time test things out, hit the site in a browser by pulling uphttps://XXX.XXX.XXX.XXX, if you’re watching the logs on the webserver you’ll see something like this:
YYY.YYY.YYY.YYY - - [30/Sep/2015:03:02:08 +0000] "GET / HTTP/2.0" 200 357616 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:40.0) Gecko/20100101 Firefox/40.0"
 
Top