Published: October 25, 2019

Exploring nginx configuration - Part 1

A walk-through on the automatically generated settings in nginx configuration files


This is Part 1 of a multipart series exploring nginx configurations.

Walking through an nginx configuration

I’ve deployed many websites served up with an nginx webserver and always try to follow best practices. Sites like Mozilla SSL Configuration Generator and Digitalocean’s https://nginxconfig.io/ provide a great way to create stable, secure nginx configuration files. It’s always worried me that I’m blindly copying settings (even from reputable) sources, without actually knowing what I’m setting. This series is an attempt to demystify the options in nginx configuration files so you can more easily, and securely, automate webserver configuration.

Why?

Part of the challenge in securing webservers is the application riding on top of the server. If said application has vulnerabilities, the impact of these can slide down the stack into the webserver. Providing a hardened, resilient server configuration is crucial to a “defense-in-depth” approach to security.

Additionally, I’m always worried that there is some obscure setting implemented that doesn’t quite align with what I’m doing.

Does this setting apply even though I’m not using a PHP web application? Is this setting appropriate for the resources available on my host?

So, for starters, let’s walk through the different default options within the base group and examine what each setting does.

Get a baseline template

When you first generate a file on https://nginxconfig.io HTTPS and PHP are enabled. For this first use case, let’s disable them and create some very baseline configuration files.

Here is what the (abbreviated) generated configuration file looks like:

# Generated by nginxconfig.io
# https://nginxconfig.io/?0.https=false&0.php=false

user www-data;
pid /run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 65535;

nginx.conf base group

  • user www-data: This is the user that nginx will run as. The nginx installation process will create the user www-data, or you can set the user yourself. Just remember, if the web application is compromised, there is a chance an attacker may be able to execute as the user specified here. So try to minimize the privileges for the specified user.

  • pid /run/nginx.pid: This specifies the file which will contain the process ID for the running nginx instance. See this Stack Overflow thread for a more detailed explanation on PIDs.

  • worker_process auto: This specifies the number of “worker processes” (a single threaded process). This can be set to a specific number, or set to the auto value to automatically detect available CPU cores. Setting this to a number other than auto could be dependent on the tasks required (for example SSL processing).

  • worker_rlimit_nofile 65535: This specifies the number of files each process can have open. Normally, this is limited by the ulimit setting on the host. According to reference 2 below, you can safely increase this number (as indicated by the generated value).

    • Note: this is NOT set as part of the default nginx configuration during install.

Follow on

Check out the series to see the settings inside the event and http groups!

References

  1. https://nginx.org/en/docs/ngx_core_module.html
  2. https://blog.martinfjordvald.com/2011/04/optimizing-nginx-for-high-traffic-loads/