Nginx: SPDY SSL Installation and Configuration On a Debian / Ubuntu Linux

Google Chrome/Chromium, Firefox and Opera browser support SPDY networking protocol. It enables faster browsing on supported sites. SPDY is similar to HTTP, with particular goals to reduce web page load latency and improve web security. SPDY achieves reduced latency through compression, multiplexing, and prioritization. How do I enable nginx SPDY support running on Debian or Ubuntu Linux server?

SPDY (pronounced as speedy) is an open networking protocol developed primarily at Google for transporting web content. Nginx version 1.4.x+ supports SPDY out of the box. You need openssl version 1.0.1 or above to compile and use nginx.

Required softwares

  1. Openssl and Openssl development (libssl) libs version 1.0.1+. Please note that CentOS/RHEL v6.x.x comes with OpenSSL version 1.0.0 only. This is needed in order to accept both HTTPS and SPDY connections simultaneously on the same port, OpenSSL library used should support “Next Protocol Negotiation” TLS extension, available since OpenSSL version 1.0.1. If you are using RHEL / CentOS version 6.x or older, you need to install OpenSSL v1.0.1. The latest version of RHEL/CentOS 6.5 comes with OpenSSL 1.0.1e-fips i.e. you can compile nginx on CentOS/RHEL version 6.5. See this guide for more information.
  2. GNU C compiler and build tools.
  3. Libpcre version 3 and libpcre3-dev.
  4. Latest stable nginx version 1.4.x+.
  5. One of the following web-browser:
    1. Google Chrome or Chromium (cross platform)
    2. Mozilla Firefox (cross platform)Opera (cross platform)
    3. Opera (cross platform)

Please note that both IE or Safari does not supports SPDY. See this compatibility table for support of SPDY networking protocol in desktop and mobile browsers.

Install required softwares

Open a terminal and/or login using the ssh client, type:
$ sudo apt-get install libssl-dev libpcre3 libpcre3-dev
Install compilers and build tools on Debian or Ubuntu Linux:
$ sudo apt-get install build-essential

Verify version

Type the following command:

gcc --version
make --version
openssl versio

Sample outputs:

Fig.01: Finding out installed version of gcc/make/openssl and operating systems.

Fig.01: Finding out installed version of gcc/make/openssl and operating systems.

Download latest nginx

Use the wget command to download nginx, type:
$ cd /tmp
$ wget

Sample outputs:

--2013-05-19 16:22:53--
Resolving (
Connecting to (||:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 767107 (749K) [application/octet-stream]
Saving to: `nginx-1.6.0.tar.gz'
100%[======================================>] 7,67,107     154K/s   in 4.9s
2013-05-19 16:22:59 (154 KB/s) - `nginx-1.6.0.tar.gz' saved [767107/767107]

To untar a tar ball called nginx-1.6.0.tar.gz, enter:
$ tar xvf nginx-1.6.0.tar.gz

Configure nginx with spdy support

Cd into nginx-1.6.0 directory:
$ cd nginx-1.6.0
Configure nginx command, enter:
$ ./configure --with-http_spdy_module --with-http_ssl_module
You may need to pass the additional options to the ./configure such as:
$ ./configure --prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--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/ \
--lock-path=/var/run/nginx.lock \
--http-client-body-temp-path=/var/lib/nginx/body \
--http-proxy-temp-path=/var/lib/nginx/proxy \
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi \
--http-uwsgi-temp-path=/var/lib/nginx/uwsgi \
--http-scgi-temp-path=/var/lib/nginx/scgi \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_spdy_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-mail \
--with-mail_ssl_module \
--with-file-aio \
--with-ipv6 \
--with-debug \
'--with-cc-opt=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic '

Sample outputs:

checking for OS
 + Linux 3.5.0-30-generic x86_64
checking for C compiler ... found
 + using GNU C compiler
 + gcc version: 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
checking for gcc -pipe switch ... found
checking for gcc builtin atomic operations ... found
checking for C99 variadic macros ... found
checking for gcc variadic macros ... found
checking for unistd.h ... found
...Configuration summary
  + using system PCRE library
  + using system OpenSSL library
  + md5: using OpenSSL library
  + sha1: using OpenSSL library
  + using system zlib library
  nginx path prefix: "/etc/nginx"
  nginx binary file: "/usr/sbin/nginx"
  nginx configuration prefix: "/etc/nginx"
  nginx configuration file: "/etc/nginx/nginx.conf"
  nginx pid file: "/var/run/"
  nginx error log file: "/var/log/nginx/error.log"
  nginx http access log file: "/var/log/nginx/access.log"
  nginx http client request body temporary files: "/var/lib/nginx/body"
  nginx http proxy temporary files: "/var/lib/nginx/proxy"
  nginx http fastcgi temporary files: "/var/lib/nginx/fastcgi"
  nginx http uwsgi temporary files: "/var/lib/nginx/uwsgi"
  nginx http scgi temporary files: "/var/lib/nginx/scgi"

Compile and install nginx

Type the following command:
$ make
Sample outputs:

make -f objs/Makefile
make[1]: Entering directory `/tmp/nginx-1.6.0'
cc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic  -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
		-o objs/src/core/nginx.o \
cc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic  -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
		-o objs/src/core/ngx_log.o \
	objs/src/mail/ngx_mail_smtp_module.o \
	objs/src/mail/ngx_mail_smtp_handler.o \
	objs/src/mail/ngx_mail_auth_http_module.o \
	objs/src/mail/ngx_mail_proxy_module.o \
	objs/ngx_modules.o \
	-lpthread -lcrypt -lpcre -lssl -lcrypto -ldl -lz
make[1]: Leaving directory `/tmp/nginx-1.6.0'
make -f objs/Makefile manpage
make[1]: Entering directory `/tmp/nginx-1.6.0'
sed -e "s|%%PREFIX%%|/etc/nginx|" \
		-e "s|%%PID_PATH%%|/var/run/|" \
		-e "s|%%CONF_PATH%%|/etc/nginx/nginx.conf|" \
		-e "s|%%ERROR_LOG_PATH%%|/var/log/nginx/error.log|" \
		< man/nginx.8 > objs/nginx.8
make[1]: Leaving directory `/tmp/nginx-1.6.0'

You need to remove existing nginx packages:
$ dpkg -l | grep nginx
$ dpkg -l '*nginx*'
Sample outputs:

Fig.02: Find and delete nginx-full and nginx-common version 1.1.19 packages

Fig.02: Find and delete nginx-full and nginx-common version 1.1.19 packages

To delete nginx-full and nginx-comman, enter:

## backup config files, just in case ##
sudo mkdir -p /root/old.nginx/etc_nginx/
sudo cp -avr /etc/nginx/* /root/old.nginx/etc_nginx/
## delete it ##
sudo apt-get remove nginx-full nginx-common

Sample outputs:

Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages will be REMOVED:
  nginx-common nginx-full
0 upgraded, 0 newly installed, 2 to remove and 0 not upgraded.
After this operation, 1,140 kB disk space will be freed.
Do you want to continue [Y/n]? y
(Reading database ... 258710 files and directories currently installed.)
Removing nginx-full ...
Stopping nginx: nginx.
Removing nginx-common ...
Processing triggers for ufw ...
Processing triggers for ureadahead ...
Processing triggers for man-db ...

Finally, install nginx, enter:
$ sudo make install
Sample outputs:

make -f objs/Makefile install
make[1]: Entering directory `/tmp/nginx-1.6.0'
test -d '/etc/nginx' || mkdir -p '/etc/nginx'
test -d '/usr/sbin' 		|| mkdir -p '/usr/sbin'
test ! -f '/usr/sbin/nginx' 		|| mv '/usr/sbin/nginx' 		'/usr/sbin/nginx.old'
cp objs/nginx '/usr/sbin/nginx'
test -d '/etc/nginx' 		|| mkdir -p '/etc/nginx'
cp conf/koi-win '/etc/nginx'
cp conf/koi-utf '/etc/nginx'
cp conf/win-utf '/etc/nginx'
test -f '/etc/nginx/mime.types' 		|| cp conf/mime.types '/etc/nginx'
cp conf/mime.types '/etc/nginx/mime.types.default'
test -f '/etc/nginx/fastcgi_params' 		|| cp conf/fastcgi_params '/etc/nginx'
cp conf/fastcgi_params 		'/etc/nginx/fastcgi_params.default'
test -f '/etc/nginx/fastcgi.conf' 		|| cp conf/fastcgi.conf '/etc/nginx'
cp conf/fastcgi.conf '/etc/nginx/fastcgi.conf.default'
test -f '/etc/nginx/uwsgi_params' 		|| cp conf/uwsgi_params '/etc/nginx'
cp conf/uwsgi_params 		'/etc/nginx/uwsgi_params.default'
test -f '/etc/nginx/scgi_params' 		|| cp conf/scgi_params '/etc/nginx'
cp conf/scgi_params 		'/etc/nginx/scgi_params.default'
test -f '/etc/nginx/nginx.conf' 		|| cp conf/nginx.conf '/etc/nginx/nginx.conf'
cp conf/nginx.conf '/etc/nginx/nginx.conf.default'
test -d '/var/run' 		|| mkdir -p '/var/run'
test -d '/var/log/nginx' || 		mkdir -p '/var/log/nginx'
test -d '/etc/nginx/html' 		|| cp -R html '/etc/nginx'
test -d '/var/log/nginx' || 		mkdir -p '/var/log/nginx'
make[1]: Leaving directory `/tmp/nginx-1.6.0'

Nginx SPDY configuration

First, you need to generate and install SSL certificates for Nginx. See how to setup SSL reverse proxy / load balanced SSL proxy using nginx for more information. Next, edit nginx.conf, type:
$ sudo vi /usr/local/ngnix/conf/nginx.conf
$ sudo vi /etc/nginx/nginx.conf
Find line that read as follows:

listen ssl;

Update it as follows

listen ssl spdy;

Save and close the file. Here is complete file:

server {
	### server port and name ###
        listen ssl spdy;
	### SSL log files ###
        access_log      logs/ssl-access.log;
        error_log       logs/ssl-error.log;
	### SSL cert files ###
        ssl_certificate      ssl/;
        ssl_certificate_key  ssl/;
	### Add SSL specific settings here ###
	ssl_protocols        SSLv3 TLSv1 TLSv1.1 TLSv1.2;
	ssl_ciphers RC4:HIGH:!aNULL:!MD5;
     	ssl_prefer_server_ciphers on;
     	keepalive_timeout    60;
	ssl_session_cache    shared:SSL:10m;
     	ssl_session_timeout  10m;
	### We want full access to SSL via backend ###
     	location / {
	        proxy_pass  http://nixcraft;
		### force timeouts if one of backend is died ##
        	proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
		### Set headers ####
                proxy_set_header        Accept-Encoding   "";
	        proxy_set_header        Host            $host;
	        proxy_set_header        X-Real-IP       $remote_addr;
	        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
		### Most PHP, Python, Rails, Java App can use this header ###
		#proxy_set_header X-Forwarded-Proto https;##
		#This is better##
	        proxy_set_header        X-Forwarded-Proto $scheme;
		add_header              Front-End-Https   on;
 		## Let the browser know about spdy ##
		add_header        Alternate-Protocol  443:npn-spdy/2;
		### By default we don't want to redirect it ####
	        proxy_redirect     off;

Finally, reload the nginx server, type:
$ sudo /usr/sbin/nginx -s reload

How do I test spdy is working or not?

  1. Firefox user try browser SPDY indicator add-on.
  2. Google Chrome or Chromium user, try browser SPDY indicator add-on.

Alternatively, Google Chrome or Chromium user can type the following in address-bar: