Nginx

Updated 7 May 2021

Nginx

Installing and setting up Nginx

First install Nginx:

emerge -a www-servers/nginx

Nginx configuration

All Nginx settings are stored in /etc/nginx/nginx.conf. Specific web site settings are stored in /etc/nginx/sites-enabled.

Run Nginx:

/etc/init.d/nginx start

Add Nginx to autostart:

rc-update add nginx

Examples of Nginx configuration

Create a config file for localhost:

/etc/nginx/sites-enabled/local.conf
server {
    listen 80;
    server_name localhost;
    access_log /var/log/nginx/localhost.access_log main;
    error_log /var/log/nginx/localhost.error_log info;
    root /var/calculate/www/localhost/htdocs;
}

Create an index file to check the health of the server:

mkdir -p /var/calculate/www/localhost/htdocs

echo 'Hello!' > /var/calculate/www/localhost/htdocs/index.html

Settings checkup

Before restarting Nginx, always make a checkup with nginx -t

If everything is correct, the following will be displayed:

nginx -t

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

If this was successful, reread the Nginx configuration:

/etc/init.d/nginx reload

To make sure that Nginx is up and running, use the curl web console client:

curl http://localhost

Hello!

Configuring HTTPS for Nginx

Create a DH key:

openssl dhparam -out /etc/nginx/ssl-dhparams.pem 4096
Generating DH parameters, 4096 bit long safe prime, generator 2
This is going to take a long time

Create a file describing the general SSL parameters:

/etc/nginx/ssl.conf
# This file contains important security parameters. If you modify this file
# manually, Certbot will be unable to automatically provide future security
# updates. Instead, Certbot will print and log an error message with a path to
# the up-to-date file that you will need to refer to when manually updating
# this file.

ssl_session_cache shared:le_nginx_SSL:1m;
ssl_session_timeout 1440m;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;

ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS";

ssl_dhparam /etc/nginx/ssl-dhparams.pem;

Getting a Let's Encrypt certificate

Get the www.example.org and example.org~ domain certificates for Nginx, as described in the manual.

Example of HTTPS configuration

Add HTTPS settings for example.org:

/etc/nginx/sites-enabled/example.org.conf
server {
    listen 80;
    listen 443 ssl;
    server_name www.example.org example.org;

    include ssl.conf;
    ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem;

    access_log /var/log/nginx/example.org.access_log main;
    error_log /var/log/nginx/example.org.error_log info;

    include acme.conf;

    root /var/calculate/www/example.org/htdocs;
}

Redirecting from HTTP to HTTPS

Add the rule for redirecting from http://example.org to https://example.org:

/etc/nginx/sites-enabled/example.org.conf
server {
    listen 80;
    listen 443 ssl;
    server_name www.example.org example.org;

    include ssl.conf;
    ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem;

    access_log /var/log/nginx/example.org.access_log main;
    error_log /var/log/nginx/example.org.error_log info;

    include acme.conf;

    if ($scheme = http) {
        return 301 https://$server_name$request_uri;
    }

    root /var/calculate/www/example.org/htdocs;
}

Installing and configuring PHP-FPM

PHP-FPM (FastCGI Process Manager) is a high-performance and scalable interface for interaction between a web server and a web application, a further development of the CGI technology.
The main advantage of FastCGI is the separation between the dynamic language and the web server. This technology allows you to run Web servers and CGI processes on multiple hosts, thus improving scalability and security without noticeable loss of performance.

To install PHP-FPM, run:

emerge -a dev-lang/php

Once all the relevant information is displayed for installation, you must accept the default version of PHP. You can cancel the installation and specify the required version of PHP at the next installation try. Use php -m to display all available and running extensions.

Использование UNIX-сокета для взаимодействия Nginx c PHP является предпочтительным и рекомендуемым вариантом!

Edit the configuration file to specify the timezone:

/etc/php/fpm-php7.4/php.ini
[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = "Europe/Moscow"

Note

In this example, the path is for PHP 7.4. Edit the path if you use a different version of PHP.

Start the PHP-FPM service:

/etc/init.d/php-fpm start

Add PHP-FPM to autostart:

rc-update add php-fpm

Example of Nginx configuration with PHP code

To provide PHP support, add the following to the configuration of the site running under Nginx. In the example below, Nginx exchanges information with the PHP process via a UNIX socket. In the server block, add the location block, which will contain the rules for working with PHP.

Apply the settings:

/etc/nginx/sites-enabled/example.org.conf
# localhost
server {
    listen 80;
    server_name www.example.org example.org;
    access_log /var/log/nginx/example.org.access_log main;
    error_log /var/log/nginx/example.org.error_log info;
    root /var/calculate/www/localhost/htdocs;
    location ~ \.php$ {
        # Checking for nonexistent scripts or 404 error
        # Without this line, nginx will send to php-fpm immediately all requests ending by .php
        try_files $uri =404;
        include /etc/nginx/fastcgi.conf;
        fastcgi_pass unix:/run/php-fpm.socket;
        }
}

Create a file and put the code for outputting information about PHP in it:

echo '<?php phpinfo(); ?>' > /var/calculate/www/localhost/htdocs/info.php

Edit access rights for all files in the root folder of the site:

chown -R nginx:nginx /var/calculate/www/localhost/htdocs

Add the corresponding entry to DNS. In the absence of DNS, you can add the entry to the static table of names of the computer from which the site will be accessed.

For Linux based systems, edit the list of domain names:

/etc/hosts
192.168.0.1  www.example.org example.org

Check that Nginx has been configured correctly and re-read the file:

nginx -t && /etc/init.d/nginx reload

Run PHP-FPM:

/etc/init.d/php-fpm start

Type http://example.org/info.php in your Web browser. If everything is OK, you will see a page with complete info on PHP.

Configuring reverse proxy on Nginx

A reverse proxy is usually understood as a server that receives a request from a client but does not process it independently, but sends it in whole or in part to other (upstream) servers for processing. In other words, it does not redirect the client, but sends a request on its own and then sends back the answer to the client.

Configure a reverse proxy, example.org~ communicating with an internal HTTP service via port 8080~:

/etc/nginx/sites-enables/example.org.conf
server {
  listen 80;
  server_name www.example.org example.org;
  access_log /var/log/nginx/proxy.log;

  location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $http_host;

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Nginx-Proxy true;

    proxy_redirect off;
  }
}

Do not process undescribed sites

In some cases, you may need Nginx to deny requests with random domain names. Tell Nginx to send no answer and break the connection with undescribed sites:

/etc/nginx/sites-enabled/_noname.conf
server {
    listen  80 default_server;
    server_name _;
    access_log /var/log/nginx/noname_80.access_log main;
    return      444;
}
server {
    listen 443 ssl default_server;
    ssl_ciphers aNULL;
    ssl_certificate /etc/nginx/ssl/nginx.crt;
    ssl_certificate_key /etc/nginx/ssl/nginx.key;
    ssl_session_tickets off;
    server_name _;
    access_log /var/log/nginx/noname_443.access_log main;
    return      444;
}

Reload Nginx settings:

/etc/init.d/nginx reload