Веб-сервер на Debian 9: php5, php7, nginx+php-fpm, Let’s Encrypt

Dmitry Kornev
  • 9 октября, 05:57
  • 125

В статье собрано все самое важное по настройке веб-сервера. Для использования будут доступны сразу несколько версий PHP. Никакого Apache, только Nginx+php-fpm. А также Percona Server (MySQL), phpMyAdmin и автоматически обновляемые SSL-сертификаты Let’s Encrypt.


PHP 5.6, 7.1 и 7.2

Подключим источник, откуда можно установить в систему одновременно несколько версий PHP.

apt install ca-certificates apt-transport-https 
wget -q https://packages.sury.org/php/apt.gpg -O- | apt-key add -
echo "deb https://packages.sury.org/php/ stretch main" | tee /etc/apt/sources.list.d/php.list
apt update

Следующие три команды — установка трех версий PHP. Можно установить только нужное.

apt install php5.6-fpm php5.6-cli php5.6-common php5.6-curl php5.6-mbstring php5.6-mysql php5.6-xml php5.6-gd
apt install php7.1-fpm php7.1-cli php7.1-common php7.1-curl php7.1-mbstring php7.1-mysql php7.1-xml php7.1-gd
apt install php7.2-fpm php7.2-cli php7.2-common php7.2-curl php7.2-mbstring php7.2-mysql php7.2-xml php7.2-gd

Установка специально с указанием конкретных компонентов, чтобы не ставить Apache.

Конфиги располагаются здесь /etc/php/версия/fpm/php.ini.

После их настройки перезагрузка, соответственно:

service php5.6-fpm reload
service php7.1-fpm reload
service php7.2-fpm reload

Nginx

Установка:

apt install nginx

Простой пример конфига для сайта:

server {
    listen 80;
    listen [::]:80;
    server_name pctuner.club;
    root /var/www/pctuner.club;
    index index.php;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        # Используем PHP нужной версии.
        # fastcgi_pass unix:/var/run/php/php5.6-fpm.sock;
        # fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    }

    access_log /var/log/nginx/pctuner_access.log;
    error_log /var/log/nginx/pctuner_error.log;
}

Конфиг записывается в файл с произвольным именем, но в определенный каталог, например /etc/nginx/sites-available/pctuner.club. После этого его необходимо активировать и перезагрузить Nginx:

ln -s /etc/nginx/sites-available/pctuner.club /etc/nginx/sites-enabled/pctuner.club
service nginx reload

Когда вносятся изменения в конфиг работающего сайта, то, чтобы избежать неудачного перезапуска Nginx и остановки работы сайта, полезно вначале выполнить тестирование:

nginx -t

HTTPS

Использовать будем Let’s Encrypt. Бесплатные SSL-сертификаты и автоматическое обновление, что еще надо? Достаточно один раз настроить и можно забыть.

Установка необходимого:

apt install python-certbot-nginx -t stretch-backports

Регистрация в Let’s Encrypt, для нового сервера это нужно сделать лишь один раз:

certbot register --email ваша@эл.почта

Конфиг /etc/letsencrypt/cli.ini:

authenticator = webroot
webroot-path = /var/www/letsencrypt
post-hook = service nginx reload
text = True

Каталог /var/www/letsencrypt необходимо создать. Чтобы с правами доступа точно все было в порядке:

chown -R www-data /var/www/letsencrypt && chmod -R 750 /var/www/letsencrypt

Для удобства настройки Nginx создадим пару файлов. Будем их подключать потом в нужных местах конфигов, чтобы не писать одно и тоже сто раз. Первый /etc/nginx/inc_letsencrypt — необходим для обновления SSL-сертификатов:

location ~ /.well-known {
    location ~ /.well-known/acme-challenge/(.*) {
        auth_basic off;
        default_type "text/plain";
        root /var/www/letsencrypt;
    }
}

Второй — /etc/nginx/inc_ssl_pctuner — включает все необходимое для работы https на доменах сайта pctuner.club:

ssl on;
ssl_certificate /etc/letsencrypt/live/pctuner.club/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/pctuner.club/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;

ssl_dhparam /etc/letsencrypt/live/pctuner.club/dh.pem;

ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_prefer_server_ciphers on;

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/pctuner.club/chain.pem;
resolver 8.8.8.8;

Почитать подробнее про задействованные параметры можно здесь. Правда там на немецком, но онлайн-переводчик в помощь, это самая толковая инструкция, что удалось найти в свое время.

Немного расширенный конфиг сайта /etc/nginx/sites-available/pctuner.club:

# Вспомогательный блок.
server {
    listen 80;
    listen [::]:80;
    server_name pctuner.club www.pctuner.club pctuner.ru www.pctuner.ru;

    # Для обновления сертификатов.
    include inc_letsencrypt;

    # Редирект с http на https.
    location / {
        return 301 https://pctuner.club$request_uri;
    }
}

# Блок для редиректа с дополнительных доменов.
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name www.pctuner.club pctuner.ru www.pctuner.ru;

    # Подключаем все необходимое для ssl.
    include inc_ssl_pctuner;

    # Редирект на основной домен.
    return 301 https://pctuner.club$request_uri;
}

# Основной блок.
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name pctuner.club;

    # Подключаем все необходимое для ssl.
    include inc_ssl_pctuner;

    root /var/www/pctuner.club/;
    index index.php;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header x-xss-protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        # Используем PHP нужной версии.
        # fastcgi_pass unix:/var/run/php/php5.6-fpm.sock;
        # fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    }

    access_log /var/log/nginx/pctuner_access.log;
    error_log /var/log/nginx/pctuner_error.log;
}

Изначально нужные сертификаты (файлы) отсутствуют, поэтому Nginx не примет конфиг в таком виде. До того момента пока сертификаты не будут получены необходимо закоментировать подключение файла inc_ssl_pctuner:

# include inc_ssl_pctuner;

Пример теста получения сертификата:

certbot certonly --dry-run -d pctuner.club -d www.pctuner.club

Один сертификат будет на 2 домена.

В одном сертификате имеет смысл объединять все домены, имеющие отношение к одному и тому же сайту. Больше доменов добавляются аналогично:

certbot certonly --dry-run -d pctuner.club -d www.pctuner.club -d pctuner.ru -d www.pctuner.ru

Здесь параметр --dry-run отвечает за запуск в тестовом режиме. Так можно убедиться, что с настройкой сервера все хорошо и сертификат точно будет получен. Есть ограничение количество полученных сертификатов за какой-то промежуток времени, поэтому обязательно вначале делайте тестирование. Если все в порядке, достаточно убирать этот параметр, и тогда сертификат будет получен уже реально.

В случае успешного теста будет ответ:

- The dry run was successful.

Кроме сертификата необходимо сгенерировать ключ:

openssl dhparam -outform PEM -out /etc/letsencrypt/live/pctuner.club/dh.pem 2048

На этом все. Включаем обратно подключение файла inc_ssl_pctuner в конфиге и перезапускаем Nginx.

В будущем если потребуется добавить в сертификат еще один домен, то просто используем выше приведенную команду, указав в ней все нужные домены, в том числе старые и новые, программа сама разберется, что с этим делать.

Для автоматического обновления сертификатов в будущем ничего делать не нужно, файл /etc/cron.d/certbot с необходимыми для этого настройками уже был создан. Программа автоматически запускается дважды в сутки. Она видит полученные сертификаты всех сайтов на сервере, при необходимости обновляет их.


Basic-auth

Это простой способ организовать доступ по логину и паролю к какому-то каталогу или всему сайту. Он имеет свои изъяны, информацию можно найти в интернете. Поэтому не стоит его использовать, как единственную защиту. Ну и, конечно, HTTPS — обязателен.

Для генерации файлов с логином и паролем установим:

apt install apache2-utils

Генерация:

htpasswd -c /etc/nginx/my_auth логин_для_доступа

В процессе будет запрошен пароль.

Пример подключения файла в конфиге Nginx для всего сайта:

...
    location / {
        auth_basic "closed site";
        auth_basic_user_file my_auth;
        ...
    }
...

MySQL

Вместо оригинального MySQL я предпочитаю сборку Percona Server, которая, как говорят, отличается улучшенной производительностью. По части использования разницы нет. Никаких специфичных настроек не требуется.

wget https://repo.percona.com/apt/percona-release_0.1-4.$(lsb_release -sc)_all.deb
dpkg -i percona-release_0.1-4.$(lsb_release -sc)_all.deb
apt update
apt install percona-server-server-5.7
rm percona-release_0.1-4.$(lsb_release -sc)_all.deb

В процессе надо будет придумать пароль для root. Это новый пользователь базы, а не системы, не стоит путать.

Настройки безопасности:

mysql_secure_installation

На следующие вопросы важно ответить положительно:

Remove anonymous users? : y
Disallow root login remotely? : y
Remove test database and access to it? : y
Reload privilege tables now? : y

Настройки MySQL можно найти в файле /etc/mysql/percona-server.conf.d/mysqld.cnf.

Если на сервере мало памяти, то в секцию [mysqld] обязательно добавьте параметр:

performance_schema = off

Перезагрузка MySQL:

service mysql reload

MySQL должен проработать непрерывно хотя бы пару дней. Должна накопиться статистика именно по вашей базе, нагрузке и т.д. После этого можно запустить mysqltuner.pl и посмотреть его рекомендации:

wget http://mysqltuner.pl/ -O mysqltuner.pl
perl ./mysqltuner.pl

phpMyAdmin

Установим Сomposer. Он всегда может пригодиться.

cd /usr/src
apt install curl
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

И конкретно сейчас он будет нужен для установки новейшего phpMyAdmin.

Лучше создать отдельный сайт для использования подобного рода утилит, что-то вроде dev.pctuner.club. Выше вся информация есть. Конечно это должен быть HTTPS-сайт, плюс можно добавить дополнительную защиту в виде basic-auth.

Переходим в подготовленный каталог сайта и запускаем установку:

cd /var/www/dev.pctuner.club
composer create-project phpmyadmin/phpmyadmin --repository-url=https://www.phpmyadmin.net/packages.json --no-dev

Он установится по пути /var/www/dev.pctuner.club/phpmyadmin и можно уже обращаться к нему соответствующим образом.

При авторизации внизу будет сообщение:

Хранилище конфигурации phpMyAdmin не полностью настроено, некоторые расширенные функции были отключены. Узнайте причину.
Или перейдите на вкладку 'Операции' любой базы данных, чтобы настроить хранилище в ней.

Ничего страшного. Просто нужно создать базу, в которую phpMyAdmin будет сохранять свои настройки. Следуем по ссылке «Узнайте причину». И там нажимаем ссылку «Создать».

Еще одно уведомление внизу:

В конфигурационном файле необходимо задать парольную фразу (blowfish_secret).

Создаем файл конфигурации из файла-примера (копируем):

cp /var/www/dev.pctuner.club/phpmyadmin/config.sample.inc.php /var/www/dev.pctuner.club/phpmyadmin/config.inc.php

В файле редактируем параметр:

$cfg['blowfish_secret'] = 'nf4eDr5uFf6n7GfH......';

В качестве значения вписываете любые свои символы, порядка 40 знаков.

Теперь phpMyAdmin готов к полноценному использованию.


Что еще?

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

Комментарии