Moving to nginx

Several years ago I tried an introduction to nginx, to see whether this alternative to Apache offered any advantages. At the time I wasn’t convinced, particularly as nginx had some major limitations such as a lack of support for dynamic modules. Certainly the advantages didn’t outweigh the downsides and the time it would take me to learn another piece of software. Apache was doing a reasonable job and there was no pressing reason to migrate.

Recently though I’ve been setting up new servers and decided that this was an opportunity to try nginx again. A lot has changed in three years, and the nginx developers have now addressed some of the issues I experienced, including adding support for dynamic modules.

I still encountered some issues, mostly around enabling TLS support:

  • The default for Diffie-Hellman key exchange is 1024 bits, whereas a minimum of 2048 bits is recommended. Easily fixed by generating a new file (using openssl dhparam).
  • Telling nginx to listen on port 443 doesn’t make HTTPS work by itself. You have to state listen 443 ssl instead.
  • Using PHP-FPM instead of mod_php meant I had to specify some extra configuration options, although for the most part I could simply include a file which ships with nginx.

None of these issues were particularly difficult to work around, and now that I’m aware of them any future nginx installations will be easier. Effectively things which were enabled by default in Apache, and therefore I had taken for granted, needed to be explicitly configured in nginx.

On the plus side, the following things were much easier than their Apache equivalent:

  • Redirecting from HTTP to HTTPS is as simple as: return 301 https://$host$request_uri;
  • Configuration files are much cleaner as they don’t have XML-like tags.
  • nginx appears to use less RAM and CPU, although I haven’t performed extensive benchmarking to confirm this and quantify the difference.

Overall, once I had got my head around the differences in configuration, nginx is an improvement over Apache. I don’t think I’ll be replacing Apache on all my existing infrastructure, but I will be using it for all new deployments.

4 thoughts on “Moving to nginx

  1. TIm Bannister

    It’s definitely a good idea to switch to FastCGI rather than use mod_php. The choice between Apache httpd and nginx isn’t as clear cut, both have their strengths and shortcomings. nginx is easy to configure for performance and works well out of the box.

    Recent industry thinking on Diffie-Hellman parameters has shifted towards using standardised groups – see https://wiki.mozilla.org/Security/Server_Side_TLS#Pre-defined_DHE_groups
    This means the client can be assured that the selected group is resistant to certain attacks. If the server presents a group chosen at random, the client can’t easily verify the strength of the server’s selected group. Checking an arbitrary group is expensive in terms of computation, and that’s why it helps the client if the server uses a public group that has already been checked.

  2. Paul Post author

    I wasn’t aware of the standardised groups, it’s something I’ll have to look into. There are a few other TLS tweaks I’d like to make to try and get a A+ grade on SSL Labs too.

  3. David

    Welcome to the nginx club 🙂

    Here’s what I tend to use for SSL config in Nginx (gets me an A+ on SSL Labs)

    # ssl setup
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_dhparam /etc/ssl/private/dhparam2048.pem;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ‘ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!3DES:!DES:!MD5:!PSK:!RC4:!RSA’;

    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 10s;
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /path/to/cert;

  4. Paul Post author

    Thanks David, I think quite a lot of that is already included by the configuration overrides which ship with LetsEncrypt as I get A on SSL Labs now. I’ll have a play round soon though to see if I can bump that to the elusive A+. 🙂

Comments are closed.