Настройка Nginx, создание тестового хоста

Чтобы протестировать работоспособность сервера, необходимо придумать какой-нибудь хост и зарегистрировать его в файле hosts. Windows-пользователи могут найти этот файл по адресу C:\Windows\System32\drivers\etc\hosts. Необходимо открыть этот файл от имени администратора с помощью текстового редактора, затем добавить в его конец запись, в которой будет содержаться имя хоста и IP адрес, с которым она будет ассоциирована, то есть IP адрес вашего сервера:

11.222.333.44        server.dev
11.222.333.44        www.server.dev

Где server.dev — имя нашего тестового хоста, www.server.dev — его псевдоним, 11.222.333.44 — пример IP адреса, который необходимо заменить на IP адрес вашего сервера. После добавления записи и сохранения файла, при переходе в браузере по адресу http://server.dev вы попадёте на ваш сервер. Разумеется, это применимо только к вашему рабочему компьютеру. Никто из интернета на ваш сервер зайти пока не может. Чтобы сервер был доступен для интернет-аудитории, для него нужно делегировать настоящий домен. Однако в этом нет ничего сложного, домены делегируются по такому же принципу: пользователи направляются на IP адрес сервера по A-записи, прописанной в биллинге — в личном кабинете, который предоставляется регистратором доменных имён.

Для того, чтобы вывести наш тестовый файл, необходимо сконфигурировать HTTP сервер Nginx. Конфигурационные файлы, как уже было отмечено выше, можно найти в каталоге /etc/nginx. В этом каталоге можно найти файл основной конфигурации nginx.conf. В изначальном варианте этот файл имеет следующее содержимое (комментарии опущены):

user                        nginx;
worker_processes            1;

error_log                   /var/log/nginx/error.log warn;
pid                         /var/run/nginx.pid;

events {
    worker_connections      1024;
}

http {
    include                 /etc/nginx/mime.types;
    default_type            application/octet-stream;
	
    log_format     main     '$remote_addr - $remote_user [$time_local] "$request" '
                            '$status $body_bytes_sent "$http_referer" '
                            '"$http_user_agent" "$http_x_forwarded_for"';

    access_log              /var/log/nginx/access.log  main;
    sendfile                on;
    keepalive_timeout       65;
    include                 /etc/nginx/conf.d/*.conf;
}

Конфигурация по умолчанию вполне пригодна для использования, однако чтобы сервер заработал для web, в его настройки всё же необходимо внести некоторые изменения (выделено красным):

user                        www-data;
worker_processes            1;

error_log                   /var/log/nginx/error.log warn;
pid                         /var/run/nginx.pid;

events {
    worker_connections      1024;
}

http {
    include                 /etc/nginx/mime.types;
    default_type            application/octet-stream;
    
    client_max_body_size    100m;
    charset                 utf-8;
    index                   index.php index.html index.htm;
	
    log_format     main     '$remote_addr - $remote_user [$time_local] "$request" '
                            '$status $body_bytes_sent "$http_referer" '
                            '"$http_user_agent" "$http_x_forwarded_for"';

    access_log              /var/log/nginx/access.log  main;
    sendfile                on;
    keepalive_timeout       65;
    include                 /etc/nginx/conf.d/*.conf;
}

Мы изменили пользователя, от которого запускается сервер, максимальный размер тела запроса, кодировку и индекс. Самое важное из изменений — последнее. Индекс — это файл, который будет открыт при корневых запросах или запросах к директориям, например http://site.com/, http://site.com/contents. Директива index может иметь несколько значений. При отсутствии первого индексного файла сервер проверит существование второго и откроет его, если он существует. Если файла с таким именем нет в каталоге, то сервер попытается открыть третий и т.д. При отсутствии индекса директория будет раскрыта в листинге, в котором будет находится список вложенных файлов. Так как мы создали файл index.html, то он и будет открыт при переходе в корневой каталог хоста http://server.dev.

Обратите внимание на последнюю строку главного конфигурационного файла include /etc/nginx/conf.d/*.conf; — эта директива подключает к конфигурации все файлы, находящиеся в каталоге conf.d, то есть объявленные хосты. После инсталляции в этом каталоге присутствует всего один файл default.conf — в нём находятся параметры конфигурации хоста по умолчанию. Общепринятой практикой считается создание для каждого хоста отдельного файла *.conf, однако в режиме тестирования можно обойтись без создания дополнительных файлов. По сути, конфигурация хостов — это продолжение главной конфигурации. Для подключения тестового хоста server.dev необходимо привести файл /etc/nginx/conf.d/default.conf к следующему виду:

server {
    listen        80;
    server_name   _;
    return        403;
}

server {
    listen        80;
    server_name   server.dev www.server.dev;
    root          /var/www/localhost;
}

Вы видите два серверных блока. Главные параметры, определяющие хосты, — это порт и имя хоста. Порт задаётся директивой listen. Nginx устроен так, что тот блок, в котором порт встречается в первый раз (то есть верхний) является блоком по умолчанию. Nginx отрабатывает его в том случае, если в конфигурации больше нет дальнейших совпадений хостов для этого порта. То есть независимо от того, какой домен будет подан на обработку, например aaa.bbb.ccc.ddd.server.dev, если он подан на 80-ый порт, то он будет отрабатываться в блоке по умолчанию. Обычно такой блок выключают из конфигурации — при попадании в него возвращается ошибка 403 с помощью директивы return

Второй серверный блок — это блок нашего тестового хоста. В нём так же задан 80-ый порт, используемый браузером для протокола http://, однако в отличие от серверного блока по умолчанию нижний блок идентифицируется именем сервера и его алиасом при помощи директивы server_name. Алиасов может быть сколько угодно (они могут также отсутствовать). Алиасы обычно разделяются пробелами. Третья важная директива — root, она определяет путь файловой системы до корневого каталога хоста. После изменения конфигурации сервера для вступления изменений в силу требуется его перезагрузка. На Debian перезагрузка процессов устроена хитро. Есть 2 основных команды:

service nginx restart
/etc/init.d/nginx restart

Первая команда просто пытается перезагрузить сервер и не выводит никакого результата в случае успеха или неуспеха, вторая команда выводит положительный результат в случае успеха и уведомление об ошибке, если что-то пошло не так. Вторая команда — это путь до загрузчика процесса, ей мы вызываем загрузчик напрямую. Существуют также и другие важные команды, о которых необходимо знать: о назначении первых двух вы можете догадаться исходя из их названий, последняя команда показывает статус процесса (он может быть активным или неактивным):

/etc/init.d/nginx stop
/etc/init.d/nginx start
/etc/init.d/nginx status

После перезагрузки сервера перейдите на тестовый хост http://server.dev — браузер должен отобразить проверочную фразу Hello Universe!. Если вы её видите, значит всё получилось, и можно приступить к подключению PHP интерпретатора.

Создадим индексный файл index.php и поместим его в корневой каталог нашего сервера. Новый файл будет иметь более высокий приоритет, так как в главной конфигурации мы определили его на первое место, и при конкуренции между индексными файлами index.html и index.php, находящимися в одном каталоге, сервер выведет index.php. Для создания нового файла мы воспользуемся более продвинутой командой printf, которая в отличие от echo позволяет записывать в файлы специальные символы, например переносы строк:

touch /var/www/localhost/index.php
printf "<?php \n echo phpinfo(); \n ?>" > /var/www/localhost/index.php

Теперь перейдите на тестовый хост. Обратите внимание на то, что браузер ничего не отображает, при этом файл index.php вывелся на загрузку. Если вы его откроете, то увидите содержимое, которое мы в него записали. Зафиксируйте для себя этот очень важный ньюанс безопасности: при неправильной конфигурации сервера PHP файлы не исполняются, а просто выводятся браузером на скачивание как есть. Таким образом можно легко получить конфиденциальную информацию, например пароли. Учитывайте этот момент в будущем. А чтобы интерпретатор заработал, необходимо указать серверу, чтобы все запросы к файлам PHP он передавал на исполнение интерпретатору. Добавьте к конфигурации тестового сервера блок локации, который по регулярному выражению будет обслуживать файлы PHP (выделено):

server {
    listen       80;
    server_name  _;
    return 403;
}

server {
    listen 80;
    server_name server.dev;
    root /var/www/localhost;
    location ~ \.php($|/) {
	
        # Важный ньюанс безопасности. Nginx не должен обрабатывать запросы к несуществующим файлам PHP. 
        # Это критическая уязвимость, которую обязательно необходимо устранить. Другой вариант решения 
        # этой проблемы — установка параметра cgi.fix_pathinfo в значение 0 в php.ini, однако изменение 
        # параметра cgi.fix_pathinfo может привести к неработоспособности сайтов при определённой конфигурации.
        if (!-f $document_root$fastcgi_script_name) {
            return 404;
        }
		
        # определение и установка переменных сервера
        fastcgi_split_path_info          ^(.+?\.php)(/.*)$;
        fastcgi_param                    PATH_INFO            $fastcgi_path_info;
        fastcgi_param                    SCRIPT_FILENAME      $document_root$fastcgi_script_name;
		
        # определение и установка переменных сервера объявленных в файле /etc/nginx/fastcgi_params
        include                          fastcgi_params;
        
        # связь с FastCGI сервером PHP-FPM через UNIX-сокет
        fastcgi_pass                     unix:/var/run/php/php7.0-fpm.sock;
		
        # перехват и логирование ошибок php-fpm
        fastcgi_intercept_errors         on;
		
    }
}

Настройки PHP-FPM по умолчанию, как правило, выставлены правильно. Откройте файл /etc/php/7.0/fpm/pool.d/www и проследите, чтобы следующие параметры были установлены корректно:

user = www-data
group = www-data
listen = /var/run/php/php7.0-fpm.sock
listen.owner = www-data
listen.group = www-data

После изменения конфигурации перезагрузите Nginx:

/etc/init.d/nginx restart

Если вы изменили конфигурацию PHP, то перезагрузите также и PHP:

/etc/init.d/php7.0-fpm restart

Перейдите на тестовый хост. Если всё прошло успешно, то сервер должен вывести исполненный индексный файл index.php.