Use Nginx + SPDY, without compiling Nginx and without a recent OpenSSL
We use the SPDY network protocol extensively to improve the performance of our websites. SPDY — pronounced “speedy” — is a new-ish protocol from Google with the goal of reducing latency, improving throughput and improving pipelining. Many articles have been written about the advantages of SPDY. We have observed 20%-30% better loading time on www.phusionpassenger.com by switching from plain HTTP to SPDY, mostly because of the better pipelining that SPDY offers over plain HTTP.
SPDY is built on top of TLS. Nginx has supported SPDY through external patches for a while. Since version 1.4.0, Nginx has SPDY support builtin, with two caveats:
- SPDY support must be enabled by compiling Nginx with
--with-http_spdy_module
. - It requires OpenSSL 1.0.1+, because SPDY requires the Next Protocol Negotiation TLS extension.
Many users prefer to use the Nginx binary provided by their distribution. But not all of the currently widely used distributions provide OpenSSL 1.0.1, and of those that do, very few of them have Nginx with SPDY enabled.
We started providing prebuilt Nginx binaries since Phusion Passenger 4.0.13 (learn more at “No more compiling Phusion Passenger”). These Nginx binaries not only have Phusion Passenger support enabled, but also SPDY support! Furthermore, we’ve spent great effort on ensuring that these binaries are compatible with a wide range of Linux distributions, whether they’re running on x86 or x86_64. Best of all: you can use these Nginx binaries without Phusion Passenger, and as a drop-in replacement for your distribution’s Nginx binary! This means:
- You install Nginx using your distribution’s preferred method (e.g.
apt-get install nginx
). - You overwrite the Nginx binary with the one that we provide.
- You get to keep all the nice things that your distribution package offers, such as init scripts, conf.d directories, etc.
- No compilation is necessary.
Getting started on Debian or Ubuntu
This guide is taylored for Debian and Ubuntu. The instructions may also work on other distributions, but the paths may be different, and the init script format may also be different. You can use this guide as a starting point for figuring out how to achieve the same for your specific distribution.
Install Nginx using apt:
sudo apt-get install nginx
Next, download our Nginx binary. There are multiple versions of Nginx and of Phusion Passenger. You can find all available versions at the Phusion download server, indexed by Phusion Passenger version. At the time of writing, Nginx 1.4.2 and Phusion Passenger 4.0.13 are the most recent versions:
# 32-bit systems
curl -O https://oss-binaries.phusionpassenger.com/binaries/passenger/by_release/4.0.13/nginx-1.4.2-x86-linux.tar.gz
# 64-bit systems
curl -O https://oss-binaries.phusionpassenger.com/binaries/passenger/by_release/4.0.13/nginx-1.4.2-x86_64-linux.tar.gz
Extract the downloaded tarball:
tar xzvf nginx-*.tar.gz
Update April 9 2014: the tarball and the binary have been renamed. It’s called “webhelper” now. So if you want Nginx 1.4.7 from Phusion Passenger 4.0.41, run:
# 32-bit systems curl -O https://oss-binaries.phusionpassenger.com/binaries/passenger/by_release/4.0.41/webhelper-1.4.2-x86-linux.tar.gz # 64-bit systems curl -O https://oss-binaries.phusionpassenger.com/binaries/passenger/by_release/4.0.41/webhelper-1.4.2-x86_64-linux.tar.gz # Then rename the tarball and the binary: tar xzvf webhelper-*.tar.gz mv PassengerWebHelper nginx
The next steps are a little more complicated, although not difficult. The Nginx binary that we provide is compiled with the prefix /tmp
. This is because Nginx requires several data directories (e.g. client_body_temp_path
) to properly operate. Since our Nginx binary is designed to be portable, we can’t assume any specific directory structure, which is why we use the /tmp
prefix.
Luckily, there is a way to tell the Nginx binary during runtime to a different directory structure, and that’s exactly what we’re going to do.
Overwrite the original Nginx binary and create a bunch of symlinks:
sudo cp nginx /usr/sbin/
sudo ln -s /etc/nginx /var/lib/nginx/conf
sudo ln -s /var/log/nginx /var/lib/nginx/logs
Then edit /etc/default/nginx and add:
DAEMON_OPTS="$DAEMON_OPTS -p /var/lib/nginx"
Next, edit /etc/nginx/nginx.conf, and set the following options:
pid /var/run/nginx.pid;
lock_file /var/lock/nginx.lock;
Finally, restart Nginx using your distribution’s Nginx init script:
sudo /etc/init.d/nginx restart
Testing SPDY
To test SPDY, you need an SSL certificate for your domain name. There are many cheap SSL certificate providers our there, which you can easily find through Google. Once you have an SSL certificate, create a virtual host entry:
sudo tee /etc/nginx/conf.d/spdy_test.conf <<EOF
server {
listen 443 ssl spdy;
server_name your_domain_name.com;
ssl on;
ssl_certificate /path-to-your-cert.crt;
ssl_certificate_key /path-to-your-key.key;
root /tmp/spdy_test;
}
EOF
Then create a web directory with a test document:
mkdir /tmp/spdy_test
echo it works > /tmp/spdy_test/index.html
Restart Nginx:
sudo /etc/init.d/nginx restart
Finally, use SPDYCheck to check your website at https://your_domain_name.com.
Distribution updates
Whenever the distribution has an update for Nginx, you must replace the Nginx binary after the distribution’s update tool has installed the update. For example, suppose that Ubuntu releases Nginx 1.4.3 tomorrow:
$ sudo apt-get upgrade
[some error messages will appear during restarting of Nginx]
apt-get upgrade
will probably fail to restart Nginx, but this is normal! This is because you will probably have SPDY-specific configuration options, but the distribution’s Nginx doesn’t support that.
Ignore the error, and download the latest version of the Phusion Nginx binary from the Phusion download server:
curl -O https://oss-binaries.phusionpassenger.com/binaries/passenger/by_release/<SOME VERSION>/nginx-1.4.3-<SOME ARCHITECTURE>-linux.tar.gz
Next, extract the Nginx binary and overwrite the distribution’s binary:
tar xzvf nginx-*.tar.gz
sudo cp nginx /usr/sbin/
Finally, finalize the apt-get upgrade and restart Nginx:
sudo apt-get upgrade
sudo /etc/init.d/nginx restart
What about security?
Downloading random binaries from the Internet is very dangerous. If an attacker intercepts and modifies the communication channel, anything goes. To combat this problem, we’ve employed two security measures:
- All our binaries are hosted on HTTPS.
- All our binaries are signed with PGP. The PGP key is Phusion Automated Software Signing (software-signing@phusion.nl), fingerprint
1637 8A33 A6EF 1676 2922 526E 561F 9B9C AC40 B2F7
.
Reinstalling Nginx if something goes wrong
If our binary doesn’t work for some reason, then reverting to the original Nginx binary is easy:
sudo apt-get remove nginx
sudo apt-get install nginx
Conclusion
Installing Nginx with SPDY support through our prebuilt binaries is quite easy and requires just a few config file changes. We’ve love to know whether it works well for you. Please leave feedback at the comment form below. Thank you for reading.