Базовая настройка нового VPS

Описывается базовая настройка VPS для работы в качестве веб-сервера. Будут установлены Apache, PHP, сервер баз данных MariaDB и Nginx в качестве кеширующего прокси.

Итак, к вам на почту пришло долгожданное письмо от хостера, что ваш VPS установлен и готов к работе. В отличие от виртуального хостинга, где приходишь на все готовое и можно сразу загружать сайт, здесь потребуется предварительно установить необходимое ПО.

Минимальный набор для большинства случаев включает:

  • веб-сервер Apache;
  • интерпретатор PHP, установленный как модуль Apache;
  • сервер баз данных MariaDB, как более совершенная замена MySQL;
  • кеширующий прокси-сервер Nginx.

Я буду предполагать, что в качестве операционной системы выбрана Debian.

Как подключиться к серверу, думаю, все знают. Во всяком случае, здесь я не буду об этом рассказывать, можно поискать по тегам ssh, putty, winscp.

Авторизация на сервере предполагается по паролю. Авторизация по ключу - это отдельная тема. Я считаю, что при достаточно сложном пароле защита получается ничуть не хуже.

1 Обновить систему

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

apt update
apt upgrade

Для debian ниже 9 лучше вместо apt использовать aptitude. Если система будет ругаться, что aptitude: command not found, ее нужно просто установить:

apt-get install aptitude

Устанавливаем часовой пояс:

dpkg-reconfigure tzdata

2 Обезопасить SSH

Настройки SSH назодятся в файле /etc/ssh/sshd_config. Внесем туда несколько изменений, чтобы повысить безопасность.

2.1 Разрешаем вход в систему только определенным пользователям:

AllowUsers root dummy

Чтобы запретить вход только конкретному пользователю, используйте

#DenyUsers root

Я здесь намеренно разрешаю пользователю root входить на сервер. Не думаю, что в случае с веб-сервером использование sudo оправдано.

2.2 Изменяем стандартный порт SSH на что-нибудь неочевидное:

Port 2022

Это простое действие обламывает множество тупых ботов. Хотя остается немало умных, увы.

2.3 Запрещаем вход по пустым паролям:

PermitEmptyPasswords no

2.4 Проверяем кодировку, чтобы нормально читались файлы с кириллическими именами:

AcceptEnv LANG LC_*

2.5 Органичиваем время ожидания авторизации, максимальное количество попыток ввода пароля, максимальное количество сессий:

LoginGraceTime 1m
PermitRootLogin yes
StrictModes yes

MaxAuthTries 3
MaxSessions 3

Здесь же разрешаем root вход на сервер.

2.6 Заставляем использовать только протокол версии 2:

Protocol 2

2.7 Перезапускаем SSH

/etc/init.d/ssh restart

Теперь можно выйти из системы, изменить порт подключения и войти снова.

3 Установим вспомогательный софт

Необязательный набор, но который, скорее всего, потом понадобится. Как минимум, он точно понадобится, когда будем собирать из исходников php5 для старых сайтов. Здесь устанавливаем такие пакеты как: gcc, g++, make, perl, patch и иные.

apt install build-essential 

Установим редактор nano и zip-архиватор

apt install nano zip unzip

4 Устанавливаем сервер баз данных

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

Возможно, MariaDB установится не задав вопроса о пароле root. Это значит, что она пытается авторизовать  root используя unix_socket plugin, а не пароль. Глобально отменить это поведение можно задав в файле конфигурации в секции [mariadb] параметр unix_socket=OFF или disable_unix_socket.Подробнее см. в документации к MariaDB - Authentication Plugin - Unix Socket.

Я же предпочитаю просто отменить это поведение для root. Для этого нуно подключиться к mysql:

mysql -u root

и обнулить поле plugin:

[mysql] use mysql;
[mysql] update user set plugin='' where User='root';
[mysql] flush privileges;
[mysql] quit;

 Далее обезопасим MariaDB утилитой mysql_secure_installation:

mysql_secure_installation

Примерные вопросы, которые будут задаваться: 

Enter current password for root (enter for none):  # введите пароль для root, если он задавался при установке.
Set new root password? [Y/n]  # Задать новый пароль root? Да
New password:                # вводим пароль
Re-enter new password:   # повторяем
Remove anonymous users? [Y/n] # Удалить анонимных пользователей? Да.
Disallow root login remotely? [Y/n] # Запретить удаленных вход под root? Да (обязательно!)
Remove test database and access to it? [Y/n] # Удалить тестовую БД? Да.
Reload privilege tables now? [Y/n]  # Перезагрузить привилегии? Да.

5 Устанавливаем Apache

Здесь, помимо самой установки, сразу сделаем несколько настроек на будущую интеграцию с Nginx.

5.1 Установить Apache:

apt install apache2

5.2 Включаем мод-реврайт:

a2enmod rewrite

5.3 Изменить порт, который слушает Apache. Обычно это 80, но у нас на нем будет Nginx. Задача Nginx - перехватывать запросы клиента и отдавать ему статику, не задействуя Apache. Другие запросы будут переадресовываться Apache. Такая цепочка сильно разгружает Apache и повышает нагрузочную способность сервера. Для этого в файле /etc/apache2/ports.conf изменяем директиву Listen на:

Listen 127.0.0.1:8080

Аналогично нужно исправить порт в дефолтном конфиге Apache /etc/apache2/sites-available/000-default.conf.

SSL у нас тоже будет обрабатывать Nginx, поэтому все вхождения Listen 443 необходимо закомментировать:

#Listen 443

Также исправляем дефолтный хост Apache, как правило он /etc/apache2/sites-available/000-default.conf. Там нужно изменить директиву VirtualHost  на <VirtualHost 127.0.0.1:8080>, чтобы Apache был полностью недоступен из внешнего мира.

5.3 Теперь нужно сделать так, чтобы в логах Apache мы видели реальный IP клиента, а не 127.0.0.1 (в нашем случае реальный IP для Apache это как раз 127.0.0.1, т.к. он получает запрос не от клиента напрямую, а через Nginx). Apache начиная с версии 2.2.4 не поддерживает модуль mod_rpaf, а использует модуль mod_remoteip для замены реального IP на IP из заголовка запроса.

Включаем модуль mod_remoteip

a2enmod remoteip

Создаем файл /etc/apache2/conf-available/remoteip.conf :

touch /etc/apache2/conf-available/remoteip.conf
nano /etc/apache2/conf-available/remoteip.conf

И пишем туда:

RemoteIPHeader X-Forwarded-For
RemoteIPTrustedProxy 127.0.0.1

Включаем созданный файл конфигурации (команда создает символическую ссылку в папке conf-enabled)

a2enconf remoteip

Редактируем /etc/apache2/apache2.conf

Меняем

LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined

на

LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined

Разница в этих строках: %h превратилась в %a

Перезапускаем Apache

service apache2 restart

Теперь в логах Apache будет реальный IP клиента.

5.4 Запускаем Apache от имени пользователя.

Штатно из коробки Apache (и PHP как его модуль) работают от имени пользователя www-data, а корневой директорией сайта будет /var/www. Эта схема хороша только в однопользовательском режиме: один сервер - один сайт. Если сейчас создать на сервере несколько пользователей, например, чтобы разместить несколько разных сайтов, пользователей придется поместить в одну группу, а это значит, что они смогут читать файлы друг друга. Это не всегда допустимо. Мы будем делать по-взрослому, для каждого сайта создавать своего пользователя, домашняя директория будет в /home/username, а Apache будет работать от имени того пользователя, к чьему сайту он обращается. Попытка прочитать чужие файлы будет запрещена на уровне разграничения прав системой.

О настройке Apache будет отдельная статья, а сейчас устанавливаем модуль libapache2-mpm-itk:

apt install libapache2-mpm-itk

Обращаю внимание, что в более старых версиях Debian он назывался иначе:

Debian 7 : apache2-mpm-itk
Debian 8 : apache2-mpm-itk
Debian 9 : libapache2-mpm-itk

Если что-то не работает, проверяем разрешены ли модули mpm_prefork и mpm_itk и, при необходимости, разрешаем их:

a2enmod mpm_prefork
a2enmod mpm_itk

Перезапускаем Apache и проверяем модуль:

apachectl -t -D DUMP_MODULES

В списке должно быть mpm_itk_module (shared)

6 Установка PHP

Поскольку в репозиториях Debian не самая свежая версия PHP, мы будем устанавливать его с DEB.SURY.ORG.

Устанавливаем репозиторий Sury:

apt -y install apt-transport-https lsb-release ca-certificates

wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'

apt update

Устанавливаем нужные модули PHP (в моем случае, у вас модули могут быть другими):

apt install php7.4-cli php7.4-common php7.4-curl php7.4-gd php7.4-json php7.4-mbstring php7.4-mysql php7.4-opcache php7.4-readline php7.4-xml

Устанавливаем модуль Apache:

apt install libapache2-mod-php7.4

Если PHP не запустился, принудительно активируем модуль:

a2enmod php7.4

Если ставите 5.6, не забудьте подключить модуль mysqlnd:

apt install php5.6-mysqlnd

7 Установка NGINX

Здесь все по официальному мануалу:

wget https://nginx.org/keys/nginx_signing.key
apt-key add nginx_signing.key
apt install nginx

Чтобы передавать в Apache реальный IP добавить в nginx.conf в секцию http:

set_real_ip_from    	    000.000.000.000;  # указать реальный IP сервера
real_ip_header      	    X-Real-IP;

Также проверить, что Nginx запускается от пользователя www-data. В файле конфигурации nginx.conf вне всех секций должно быть:

user                www-data    www-data;

Заключение

В следующих сериях:

  • Создание пользователей сайтов и настройка Apache для работы с ними.
  • Настройка Nginx
  • Настройка сервера БД и создание базы данных
  • Установка и настройка почтового сервера Exim4 для отправки писем с сайта
  • Настройка ftp сервера Proftpd c авторизацией пользователей
  • Сборка PHP5.6
  • Установка SSL-сертификата Let's Encript