Nginx (pronounced "engine-x") is a fast and lightweight web server, http load balancer, reverse proxy and http cache server. The main characteristics are efficiency and scalability which makes Nginx suited for both the small and the busiest servers on the Internet.
Find more documentation at [[1]].
Installation
For Fedora 22 and later versions use DNF:
$ su # dnf install nginx
Or for older releases use YUM:
$ su # yum install nginx
To start the server at each boot:
# systemctl enable nginx.service
To start the server now:
# systemctl start nginx.service
Configuration
The main configuration file is located in /etc/nginx/nginx.conf
and is structured in the following way. First, there are some very general configuration options about nginx itself and an events block. Notice you should use a semicolon (;) after each option, except for the blocks themselves.
user nginx; worker_processes 1; error_log /var/log/nginx/error.log; #error_log /var/log/nginx/error.log notice; #error_log /var/log/nginx/error.log info; pid /var/run/nginx.pid; events { worker_connections 1024; }
The advised number of processes is the number of cores/threads your cpu has.
Second, there is one big http block that contains the general configuration related to this protocol. Notice that inside this block there is the following line:
include /etc/nginx/conf.d/*.conf;
which tells us that the rest of the configuration files are going to be in the configuration directory /etc/nginx/conf.d/
and are going to have a .conf extension.
And inside this http block, either in nginx.conf
file or included from the configuration directory /etc/nginx/conf.d/
there is one server block per virtual host. The http block provides the server_name
and document root.
Note that the default document root from nginx.conf
is /usr/share/nginx/html
. If you have questions regarding file permissions, directory permissions or SELinux contexts, you can examine them using the default.
Best practice is to provide one configuration file for each site. For example, if you are serving for example.com
, then you would create /etc/nginx/conf.d/example.com.conf
for the site.
Webserver
Nginx was designed to be a webserver. All you need to create a virtual host is to create a new file in the /etc/nginx/conf.d/
directory with a .conf extension and a server block in it. The server block will be automatically included in the http block.
For example, /etc/nginx/conf.d/example.com.conf
server { listen 80; server_name example.com; root /var/www/example.com/public_html; index index.php index.html; }
You can also specify multiple server names in the server_name
option:
server { listen 80; server_name example.com www.example.com; root /var/www/example.com/public_html; index index.php index.html; }
And you can listen for IPv6 using multiple listen options:
server { listen 80; listen [::]:80; server_name example.com www.example.com; root /var/www/example.com/public_html; index index.php index.html; }
SSL/TLS Configuration
Nginx uses ngx_http_ssl_module
to provide secure sockets. You can modify SSL/TLS parameters, like protocol versions and cipher suites.
ngx_http_ssl_module
relies on OpenSSL. At the moment there are no alternatives to OpenSSL.
Install an existing certificate
If you already have a certificate generated on another computer, move the certificate and the key file to the correct folder, and ensure their SELinux contexts, ownerships and permissions are correct:
# mv key_file.key /etc/pki/tls/private/example.com.key # restorecon /etc/pki/tls/private/example.com.key # chown root:root /etc/pki/tls/private/example.com.key # chmod 0600 /etc/pki/tls/private/example.com.key # mv certificate.crt /etc/pki/tls/certs/example.com.crt # restorecon /etc/pki/tls/private/example.com.crt # chown root:root /etc/pki/tls/private/example.com.crt # chmod 0600 /etc/pki/tls/private/example.com.crt
After this set it up
Generate a new certificate
How to generate a new certificate
Configuring TLS/SSL keys
Modify inside the server block of a particular virtual host the following lines or add them, so it looks like this:
listen 443 ssl; ssl_certificate /etc/pki/tls/certs/example.com.crt ssl_certificate_key /etc/pki/tls/private/example.com.key
Strict Transport Security
The http Strict-Transport-Security response header (HSTS) tells user agents the site should only be accessed using https. You can add the header using the following option.
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains;";
Permanent HTTPS Redirect
A 301 redirect is a permanent server-side redirect that automatically sends users to a new URL when they request an old one. You can provide a permanent redirect from http to https using the following option.
if ($scheme = "http") { return 301 https://$server_name$request_uri; }
Other Hardening
To further harden the SSL/TLS stack, you should disable session caching, session tickets and early data. Do so with the following options:
ssl_session_cache off; ssl_session_tickets off; ssl_early_data off;
Also see OpenSSL's TLS Client example for more information on the options
File Permissions
Nginx runs on top of Fedora Linux. The webserver is bound by both traditional Unix & Linux permissions, like user and group with read/write/execute access; and SELinux contexts, like system_u
and httpd_sys_content_t
. You have to manage both for a secure system, and you should follow Principle of Least Privilege to minimize risk.
Note that the first permission checks happen using Unix & Linux permissions. If the checks succeed, then the operation system will use SELinux checks to verify object access. If you have trouble, then first examine Unix & Linux permissions. If the traditional permissions are Ok, then move to SELinux contexts.
(Please do not perform a chmod -R 0777 /var/www
like you find at places like Stack Overflow).
Unix & Linux permissions
After you install Nginx, the scriptlets create a nginx
user and a nginx
group. You can use the group to provide traditional Unix & Linux permissions, like read-only or read-write access to the files on the webserver.
The configuration shown below follows the Principle of Least Privilege. root
owns the documents, and root
has read-write access. The group nginx
has read access to the documents. And other
users have no access to the documents.
# ls -l /var/www drwxr-x---. 5 root nginx 4096 Nov 18 15:15 html # ls -l /var/www/html -rw-r-----. 1 root nginx 1633 Nov 18 15:15 index.html
You should use the owner root:nginx
and resist the urge to use nginx:nginx
. nginx:nginx
gives the web server write access to the documents, and there is usually no reason for the web server to have write access to static html files.
SELinux Contexts
Traditional Unix & Linux permissions are only half the recipe. You must also manage SELinux contexts or risk a 403 - the "Forbidden" error.
Continuing with the /var/www/html
example, you have to set the SELinux context. To learn the context set by the Fedora maintainers, check /usr/share/nginx/html
:
# ls -Z /usr/share/nginx/html system_u:object_r:httpd_sys_content_t:s0 index.html system_u:object_r:httpd_sys_content_t:s0 nginx-logo.png ...
So the final task is to change the context to system_u:object_r:httpd_sys_content_t:s0
:
# restorecon /var/www/html # ls -Z /var/www/html/ system_u:object_r:httpd_sys_content_t:s0 index.html system_u:object_r:httpd_sys_content_t:s0 nginx-logo.png ...
If you are using an unusual directory for server storage, like /opt/www/html
, then you may not be able to use restorecon
to automatically fix the SELinux context. In this case, set the context and save it so it is permanent:
# chcon -R system_u:object_r:httpd_sys_content_t:s0 /opt/www # semanage fcontext -a -t httpd_sys_content_t "/opt/www(/.*)?"