Nginx

Updated 24 May 2019

Nginx

Installing and setting up Nginx

First install Nginx:

emerge -a www-servers/nginx

Nginx configuration

All Nginx settings, as well as those of the sites that run on Nginx are contained in the /etc/nginx/nginx.conf file. Настройте вариант, при котором параметры для сайтов хранятся не в одном файле настройки nginx.conf.

/etc/nginx/nginx.conf
user nginx nginx;
# worker processes number
worker_processes 4;

error_log /var/log/nginx/error_log info;

events {
    worker_connections 1024;
    use epoll;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    log_format main
        '$remote_addr - $remote_user [$time_local] '
        '"$request" $status $bytes_sent '
        '"$http_referer" "$http_user_agent" '
        '"$gzip_ratio"';

    client_header_timeout 10m;
    client_body_timeout 10m;
    send_timeout 10m;

    connection_pool_size 256;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 2k;
    request_pool_size 4k;

    gzip off;

    # hide nginx version
    server_tokens off;
    output_buffers 1 32k;
    postpone_output 1460;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;

    keepalive_timeout 75 20;

    ignore_invalid_headers on;

    index index.html;

    # конфигурационные файлы сайтов
    include /etc/nginx/sites-enabled/*.conf;
}

Создайте путь для конфигурационных файлов с настройками сайтов и для ssl сертификатов:

mkdir /etc/nginx/sites-enabled

mkdir /etc/nginx/ssl

Сделайте настройку, чтобы Nginx на неописанные сайты закрывал соединение без ответа.

/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;
}

Обязательно сформируйте самоподписной сертификат для ответов на неописанные сайты:

openssl req -x509 -subj "/CN=_" -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt

Запустите Nginx:

/etc/init.d/nginx start

Add Nginx to autostart:

rc-update add nginx

Пример настройки Nginx

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

Note

Перед тем, как перезапускать службу nginx, всегда выполняйте проверку правильности сделанных изменений командой nginx -t

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

Use the command line web client curl to check that nginx is up and running:

curl http://localhost

Hello!

Настройка обратного прокси на Nginx

Под обратным проксированием обычно понимается процесс, в котором сервер, получающий запрос от клиента, не обрабатывает его полностью самостоятельно, а частично или целиком отправляет этот запрос для обработки другим (upstream) серверам. Иными словами, он не перенаправляет клиента, а самостоятельно отправляет запрос и возвращает полученный ответ обратно клиенту.

Настройте обратный прокси example.org, взаимодействующий с внутренним HTTP-сервисом, работающим на порте 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;
  }
}

Configuring HTTPS for Nginx

Сгенерируйте ключ для протокола Диффи-Хеллмана:

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

Получите сертификат доменов www.example.org и example.org для Nginx, следуя руководству.

Example of HTTPS configuration

Добавьте настройки HTTPS для example.org:

/etc/nginx/sites-enabled/example.org
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;
}

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. Эта технология позволяет запускать web-сервера и CGI-процессы на различных хостах, что улучшает масштабируемость и безопасность без заметной потери производительности.

To install PHP-FPM, run:

emerge -a dev-lang/php

После вывода всей информации для установки PHP необходимо согласиться с версией 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 pool for handling the sites for which this socket will be specified in the configuration:

/etc/php/fpm-php7.1/fpm.d/www.conf
[www]
...
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
user = nginx
group = nginx

; The address on which to accept FastCGI requests.
; Valid syntaxes are:
;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific IPv4 address on
;                            a specific port;
;   '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
;                            a specific port;
;   'port'                 - to listen on a TCP socket to all addresses
;                            (IPv6 and IPv4-mapped) on a specific port;
;   '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = /run/php-fpm.socket

; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many
; BSD-derived systems allow connections regardless of permissions.
; Default Values: user and group are set as the running user
;                 mode is set to 0660
listen.owner = nginx
listen.group = nginx
;listen.mode = 0660

; The number of child processes to be created when pm is set to 'static' and the
; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.
; This value sets the limit on the number of simultaneous requests that will be
; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
; CGI. The below defaults are based on a server without much resources. Don't
; forget to tweak pm.* to fit your needs.
; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand'
; Note: This value is mandatory.
pm.max_children = 20

Внесите необходимые изменения в файл настроек, запретив исполнение произвольного кода на сервере с правами PHP-процесса при загрузке файла и указав временную зону:

/etc/php/fpm-php7.1/php.ini
[PHP]
; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI.  PHP's
; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok
; what PATH_INFO is.  For more information on PATH_INFO, see the cgi specs.  Setting
; this to 1 will cause PHP CGI to fix its paths to conform to the spec.  A setting
; of zero causes PHP to behave as before.  Default is 1.  You should fix your scripts
; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.
; http://php.net/cgi.fix-pathinfo
cgi.fix_pathinfo=0

[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = "Europe/Moscow"

Note

В примере указан путь для версии PHP 7.1. Отредактируйте путь, если используется другая версия 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. В блок server добавьте блок location, в котором и будут описаны правила работы с PHP.

Apply the settings:

/etc/nginx/sites-enabled/local.conf
# localhost
server {
    listen 80;
    server_name lempcss.example.org;
    access_log /var/log/nginx/lempcss.example.org.access_log main;
    error_log /var/log/nginx/lempcss.example.org.error_log info;
    root /var/calculate/www/localhost/htdocs;
    location ~ \.php$ {
        # Check for non existing scripts or for error 404
        # Without this line, nginx will immediately send any requests ending with .php to php-fpm
        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  lempcss.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://lempcss.example.org/info.php in your browser. If everything is OK, you will see a page with complete info on PHP.