tech-tips/Программное обеспечение/LEMP-стек/Настройка LEMP сервера для простых проектов. Инструкция для самых маленьких/Часть 1.md

591 lines
31 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
source: https://habr.com/ru/company/nixys/blog/645451
tags: [lemp, mariadb]
---
> [!seealso] Все части
> * [Часть 1](Часть%201.md)
> * [Часть 2](Часть%202.md)
> * [Часть 3](Часть%203.md)
![[6ab46f702be837f91acf4e9818b42754.jpg]]
## Введение
Приветствую читателей. В практике нашей компании часто появляется потребность в настройке серверов для простых односерверных проектов или небольших кластеров. В этой статье я бы хотел рассказать вам о нашем опыте подобной настройки, выделить особенности, которые могут вам пригодиться при дальнейшем администрировании. Статья предназначена для людей, которые только вникают в администрирование, а также для тех, кто самостоятельно администрирует свой небольшой проект и хочет набраться опыта в этом деле. Если вы являетесь опытным администратором, то можете смело пропускать данный материал.
Целью серии статей является описание подготовки работы сервера со стеком LEMP ( #Linux, #nginx, #MySQL, #PHP), развертывание стэка и поднятие на нем работающих площадок. Инструкция подойдет для небольших #Bitrix проектов, а тажке для проектов развернутых под любой популярной CMS.
Не смотря на то, что тема уже достаточно подробно отражена в сети, мы решили подробно описать общие стандарты администрирования с нуля, по-скольку регулярно получаем большое количество базовых вопросов от людей, так или иначе, связанных с нашей сферой.
Большая часть проектов базируется на ОС #Ubuntu, #Debian в статьях будут отражены настройки для этих систем.
## Общая схема работы сервера
Представим, что вы получили сервер с установленной ОС, без каких-либо дополнительных настроек и кастомизаций со стороны ДЦ. Целью работы сервера является обслуживание сайта с развернутым на нем LEMP стэком.
Для удобства ниже представлена схема работы такого сервера со всем необходимым для работы ПО:
![[01fb2670c2429e46eee9d4a6fe45f295.png]]
В нашем случае вместо php-fpm будет развернут #apache2, поэтому данный стэк является не совсем LEMP, но вместо apache2 можно без каких-либо проблем развернуть php-fpm, целью статьи является все же указать на основные базовые моменты при настройке серверов для простых проектов.
На данной схеме отражено не все ПО, необходимое для работы и анализа проблем, это лишь основные компоненты, требуемые для работы нашей будущей площадки. В статье будет приведен более полный список ПО, а также более подробно описана работа каждого компонента данной схемы.
## Базовые пакеты
Для того, чтобы начать развертывание проекта, необходимо установить базовые пакеты для работы. Для их развертывния актуальны следующие команды:
```shell
apt-get update && apt-get install dirmngr mc iotop htop telnet tcpdump nmap curl console-cyrillic hexedit sudo zip unzip patch pwgen vim less parted subversion ntp bzip2 lsof strace mutt s-nail ncdu smartmontools tree dnsutils logrotate rsyslog
```
Здесь мы устанавливаем инструменты для работы на сервере, а также инструменты для анализа будущих проблем в работе сервера. Я не буду останавливаться на всех пакетах, а лишь перечислю самые необходимые:
- `dirmngr` необходим для добавления ключей репозиториев. **mc** он же Midnight Commander, файловый менеджер, не нуждающийся в представлении
- `iotop` утилита, показывающая каналы ввода/вывода; будет полезной при анализе работы дисков.
- `htop` наше все, могучий монитор ресурсов, отображающий всю информацию о текущем потреблении ресурсов системы. Позволяющий также отправлять системные вызовы процессам, менять их приоритет в системе и многое другое.
- `telnet` на практике, часто используем для проверки доступности удаленных портов. В случае если порт закрыт, мы будем точно знать, что проблема не на нашей стороне.
- `tcpdump` и `nmap` утилиты для анализа сетевого трафика
- `curl` используем для отправки различных запросов, отладки работы веб-серверов.
- `console`yrillic** - пакет для русификации консоли (поддержки кириллицы в локальном терминале).
- `hexedit` - пакет для редактирования данных, в котором данные представлены как последовательность байтов..
- `zip`, `unzip`, `bzip2` также не нуждаются в представлении, известные архиваторы данных.
- `pwgen` утилита для генерации паролей, будет полезна для оперативного создания доступов любого уровня.
- `strace` утилита для анализа системных вызовов процесса, используется для расширенного анализа работающих в системе процессов. По факту мы используем strace в тех случаях, когда логи сервисов не указывают на конкретную проблему.
- `ncdu` удобный инструмент для быстрого отображения размера данных в директории.
- `logrotate` инструмент для ротации логов в системе, также в отдельном представлении не нуждается.
После установки базовых пакетов устанавливаем время на сервере согласно текущему часовому поясу, с помощью команды:
```shell
dpkg-reconfigure tzdata
```
Далее выбираем нужные локали в системе (`RU-UTF8`, `RU-KOI8R`, `RU-CP1251`):
```shell
dpkg-reconfigure locales
```
Применяем локали:
```
/etc/default/locale
```
Устанавливаем mc как редактор по умолчанию:
```shell
update-alternatives --config editor
```
где выбираем пункт `mcedit`.
## Настройка `git-autocommit`
В процессе администрирования мы часто сталкиваемся с тем, что необходимо оперативно выяснить, кто и когда внес изменения в те или иные конфигурационные файлы. Для решения этой проблемы мы используем `git-autocommit`, который фиксирует изменения в конфигах в локальный `git` репозиторий сервера. Ниже будет описана его настройка:
Ставим на сервер `git`:
```shell
apt-get install git
```
Создаем файл конфигурации в корневой директории root пользователя с нужными правами:
```shell
touch ~/.gitconfig
chmod 600 ~/.gitconfig
```
Файл имеет следующее содержание
```ini
[user]
name = root
email = root@$HOSTNAME
```
`$HOSTNAME` заменяем на соответствующее название сервера в проекте. Далее потребуется создать репозиторий, с помощью команд:
```shell
cd
git init && mv .git config.git
chmod 700 /root/config.git
echo "gitdir: /root/config.git" > /.git && chmod 600 /.git
```
Далее задаем директории, для который автокоммит не должен фиксировать изменения, в файл `~/config.git/info/exclude`:
```gitignore
/*
!/etc
!/usr
/usr/*
!/usr/local
/usr/local/*
!/usr/local/scripts
!/var
/var/*
!/var/spool
/var/spool/*
!/var/spool/cron
/var/spool/cron/*
!/var/spool/cron/crontabs
```
На практике же нас интересуют директории `/usr` и `/etc`. В случае, если на проекте есть конфигурации `docker` контейнеров, не помещенных во внешний `git` репозиторий, мы также добавляем директорию в которой расположен `docker-compose` к автокомиту для отслеживания изменений. С недавних пор мы также отслеживаем изменения в пользовательских кронатобов `/var/spool/cron/crontabs`, так как существует проблема потери крон задач на Битрикс проектах. Также некоторые клиенты могут удалить нужную задачу по невнимательности.
После делаем первый коммит и проверяем:
```shell
git add -A && git commit -m 'Создание репозитория @system'
```
Также мы реализуем постоянное отслеживание установленных пакетов на сервере с помощью git autocommit, для этого записываем все текущие установленные пакеты в файл с помощью крон задачи:
```cron
* *      * * *   root     /usr/bin/dpkg -l > /etc/package_list
```
Сам автокоммит запускается с помощью следующего крона:
```cron
* *          * * *       root        sleep 10;cd / && git add -A && git commit -m "Autocommit @system" > /dev/null
```
Таким образом мы можем посмотреть, какие именно изменения вносились в конфигурации сервиса и в какое время. Пример коммита для файла **etc/nginx/nginx.conf** вызываем командой:
```shell
git log --follow -p /etc/nginx/nginx.conf
```
Результат:
```shell
git log --follow -p /etc/nginx/nginx.conf
```
Результат:
commit be993a2734e9f206ed7cb8ee52f54a52ca642cc9
Author: root
Date: Tue Oct 12 14:37:11 2021 +0300
Autocommit @system
diff --git a/etc/nginx/nginx.conf b/etc/nginx/nginx.conf
index 8c9ed7c..8d694c9 100644
--- a/etc/nginx/nginx.conf
+++ b/etc/nginx/nginx.conf
@@ -52,12 +52,12 @@ deny 178.166.163.237;
\#limit_conn_zone $binary_remote_addr zone=cglob:16m;
- map $http_user_agent $spam_bots {
- default '';
- ~*(321039152) 1;
- }
+# map $http_user_agent $spam_bots {
+# default '';
+# ~*(321039152) 1;
+# }
- limit_req_zone $spam_bots zone=spambots:16m rate=2r/s;
+# limit_req_zone $spam_bots zone=spambots:16m rate=2r/s;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
commit 2df8332dc97681489e43e9aaa85f9078fc50e321
Author: root
Date: Tue Oct 12 14:11:11 2021 +0300
Autocommit @system
diff --git a/etc/nginx/nginx.conf b/etc/nginx/nginx.conf
index 8d694c9..8c9ed7c 100644
--- a/etc/nginx/nginx.conf
+++ b/etc/nginx/nginx.conf
@@ -52,12 +52,12 @@ deny 178.166.163.237;
\#limit_conn_zone $binary_remote_addr zone=cglob:16m;
-# map $http_user_agent $spam_bots {
-# default '';
-# ~*(321039152) 1;
-# }
+ map $http_user_agent $spam_bots {
+ default '';
+ ~*(321039152) 1;
+ }
-# limit_req_zone $spam_bots zone=spambots:16m rate=2r/s;
+ limit_req_zone $spam_bots zone=spambots:16m rate=2r/s;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
```
Таким образом, мы видим, кто и когда внес изменения. Данное решение крайне полезно при возникновении спорных ситуаций внутри команды или когда проблема в конфигурации всплыла после внесения изменений не сразу, а спустя время.
## Базовая настройка ssh, добавление на сервер администратора
После можно приступить к установке и настройке базовых сервисов. Начнем с ssh. Устанавливаем службу, если по каким-то причинам она не была установлена ранее
```shell
apt update
apt install ssh
```
На наших серверах мы ограничиваем всех ssh пользователей через директиву `AllowUsers`, добавляем и удаляем пользователей по мере необходимости:
```
AllowUsers USERS_NAMES
```
Сразу же отключаем доступ для пользователя root путем изменения строки в `/etc/ssh/sshd_config`:
```
PermitRootLogin no
```
Вносим изменения в права на директорию ssh, в целях безопасности:
```shell
chmod 750 /etc/ssh
```
Перезапускаем службу для применения изменений:
```shell
/etc/init.d/ssh restart
```
Дальнейший вход на сервер по ssh будет доступен только для пользователей указанных в `AllowUsers`. Добавление системных администраторов на сервера происходит с помощью наших внутренних утилит, однако я опишу процесс добавления так, если бы это происходило ручным способом:
Для добавления на сервер системного администратора вам потребуется:
Авторизоваться на сервере от пользователя root
Создать пользователя системы и группу (пользователи площадок и администраторы имеют `UID` и `GID` от `1000` это общий стандарт для несистемных пользователей):
```shell
groupadd -g 10001 v.pupkin
useradd -g 10001 -u 10001 -s /bin/bash -d /home/v.pupkin v.pupkin
```
Далее создаем домашнюю директорию пользователя и права для него:
```shell
mkdir -p /home/v.pupkin v.pupkin
cd /home/v.pupkin v.pupkin
chown -R v.pupkin: /home/v.pupkin v.pupkin
chmod 751 /home/v.pupkin v.pupkin
chmod -R o-rwx /home/v.pupkin v.pupkin/*
```
После нам останется только прокинуть публичный ssh ключ для пользователя `v.pupkin` на сервер, а также дать пользователю права на выполнение `sudo`. Для этого достаточно добавить строку в файл `/etc/sudoers` вида:
```
v.pupkin ALL=(ALL) NOPASSWD: ALL
```
Делать это нужно **исключительно** путем выполнения команды:
```shell
visudo
```
Она проверит синтаксис файла `/etc/sudoers` перед сохранением. Так как если отредактируете файл вручную и он будет с синтаксической ошибкой, вы не сможете авторизоваться в системе от нужного пользователя или перейти в `/etc/sudoers`, что по сути поломает систему.
При этом обязательно в файле `/etc/sudoers` необходимо закомментировать строку:
```
%sudo ALL=(ALL) ALL
```
для ограничения выполнения `sudo` других пользователей. После внесения всех
После внесения всех изменений администратор `v.pupkin` сможет попадать на сервер, а для перехода в root достаточно будет ввести команду `sudo su -`. Обратите внимание на **"-"** в данной команде, зачастую многие начинающие системные администраторы забывают об этом. Дефис нужен для подтягивания системных окружений, так, например, без него вы не сможете корректно запустить скрипты на сервере.
После внесения всех изменений перейдите в консоль пользователя `v.pupkin` и сгенерируйте пару ssh ключей**:**
```shell
su v.pupkin -
ssh-keygen -t rsa
```
В завершении обязательно сгенерируйте пароль для пользователя `v.pupkin` в системе:
```shell
pwgen 15 1
```
Данная команда сгенерирует случайный **15** значный пароль. После примените его, для этого от пользователя root выполните команду:
```shell
passwd v.pupkin
```
На этом настройку ssh и предоставление доступов администратору можно считать завершенной. Дальнейшие администраторы будут добавлены также по этой схеме.
## Базовая настройка FTP
Далее переходим к настройке доступа к серверу по FTP. Для этих целей будем использовать пакет vsftpd, который есть в стандартных репозиториях. Устанавливаем пакет:
```shell
apt install vsftpd
```
Стандартный файл конфигурации vsftpd расположен по пути `/etc/vsftpd.conf`, но хранить конфигурации всех FTP пользователей в одном файле не совсем удобно для администрирования, поэтому мы создадим отдельный каталог для конфигураций службы и создадим символическую ссылку на конфигурационный файл `/etc/vsftpd.conf`, чтобы предотвратить конфликты в системе.
Удаляем основной файл конфигурации службы:
```shell
rm /etc/vsftpd.conf
```
Создаем новую директорию, которая будет основной для конфигураций сервиса:
```shell
mkdir /etc/vsftp/
```
Далее создаем основной файл конфигурации `/etc/vsftp/vsftpd.conf`:
```shell
touch /etc/vsftp/vsftpd.conf
```
Со следующим содержимым:
```
listen=YES
log_ftp_protocol=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
anon_upload_enable=NO
anon_mkdir_write_enable=NO
anon_other_write_enable=NO
dirmessage_enable=YES
pasv_enable=YES
port_enable=NO
connect_from_port_20=NO
pasv_max_port=30005 #
pasv_min_port=30000 #
xferlog_enable=YES
xferlog_file=/var/log/vsftpd.log
ascii_upload_enable=NO
ascii_download_enable=NO
ftpd_banner=Welcome to FTP server.
local_umask=0777
user_config_dir=/etc/vsftp/vsusers
chroot_local_user=NO
chroot_list_enable=YES
chroot_list_file=/etc/vsftp/vsftpd.chroot_list
userlist_file=/etc/vsftp/vsftpd.user_list
userlist_enable=YES
userlist_deny=NO
allow_writeable_chroot=YES
seccomp_sandbox=NO
force_dot_files=YES
pasv_promiscuous=YES
```
Здесь приведены основные настройки, вы можете их менять в зависимости от своих потребностей. Здесь же мы указываем файлы и директорию, в которых будем описывать FTP пользователей:
```
/etc/vsftp/vsftpd.chroot_list
/etc/vsftp/vsftpd.user_list
/etc/vsftp/vsusers
```
Логирование службы вынесено в отдельный файл:
```
xferlog_file=/var/log/vsftpd.log
```
Опционально вы можете воспользоваться следующими функциями при необходимости:
Для отображения скрытых файлов в листинге подключения, вне зависимости от настроек FTP-клиента можно использовать параметр `force_dot_files`:
```
force_dot_files=YES
```
Для исключения постоянных проверок соответствия IP адресов соединения и управляющего, чтобы исключить ошибку `425 Security: Bad IP connecting.`, необходимо добавить в файл `/etc/vsftp/vsftpd.conf` параметр:
```
pasv_promiscuous=YES
```
Далее создадим необходмые файлы и директории:
```shell
touch /etc/vsftp/vsftpd.chroot_list
touch /etc/vsftp/vsftpd.user_list
mkdir /etc/vsftp/vsusers
```
А также создадим символьную ссылку для корректной работы сервиса:
```shell
ln -s /etc/vsftp/vsftpd.conf /etc/vsftpd.conf
```
После вам потребуется открыть `21` и `30000:30005` порты для внешних подключений на уровне файрволла, например, следующим образом:
```
IPTABLES -A tcp_packets_inet -p tcp -s 0/0 --dport 30000:30005 -j allowed
IPTABLES -A tcp_packets_inet -p tcp -s 0/0 --dport 21 -j allowed
```
Мы рекомендуем открывать порты не для всех адресов, а только для тех IP, которым необходим доступ по FTP.
После выполнения этих действий, применяем права на каталог `/etc/vsftp/` в целях безопасности:
```shell
chmod 750 /etc/vsftp/
```
Перезапускаем сервис:
```shell
service vsftpd restart
```
И проверяем, что он работает и запущен:
```
service vsftpd status
● vsftpd.service - vsftpd FTP server
Loaded: loaded (/lib/systemd/system/vsftpd.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2021-12-19 17:08:13 MSK; 1s ago
Process: 1285 ExecStartPre=/bin/mkdir -p /var/run/vsftpd/empty (code=exited, status=0/SUCCESS)
Main PID: 1286 (vsftpd)
Tasks: 1 (limit: 1171)
Memory: 608.0K
CGroup: /system.slice/vsftpd.service
└─1286 /usr/sbin/vsftpd /etc/vsftpd.conf
Dec 19 17:08:13 31-31-192-22.cloudvps.regruhosting.ru systemd[1]: Starting vsftpd FTP server...
Dec 19 17:08:13 31-31-192-22.cloudvps.regruhosting.ru systemd[1]: Started vsftpd FTP server.
```
В завершении всех действий, проверяем, что нужные порты открыты и слушаются службой. Для проверки доступности используем `telnet`:
```shell
telnet 0.0.0.0 21
```
Где `0.0.0.0` - внешний IP адрес вашего сервера. Если команда выдает статус connected, то порты открыты корректно и служба vsftpd слушает их.
На данном этапе базовая настройка FTP завершена, как добавить конкретного пользователя я расскажу в третьей части статьи.
## Базовая настройка exim4 (smarthost)
После настройки работы по FTP переходим к настройке отправки почты с сервера. Так как у нас простой сервер для небольшого проекта, мы будем настраивать `exim4` в конфигурации `smarthost`. То есть почтовый сервер будет осуществлять только отправку почты с сервера, не более.
Приступим к установке пакета:
```
apt update
apt install exim4 exim4-base exim4-config exim4-daemon-light
```
После переходим к редактированию файла `/etc/exim4/update-exim4.conf`, и приводим его к следующему виду:
```
dc_eximconfig_configtype='internet'
dc_other_hostnames='DOMAIN.RU'
dc_local_interfaces='127.0.0.1 : EXTERNAL_IP'
dc_readhost=''
dc_relay_domains=''
dc_minimaldns='false'
dc_relay_nets='127.0.0.1 : RELAY_FROM_HOST_IPs'
dc_smarthost=''
CFILEMODE='644'
dc_use_split_config='false'
dc_hide_mailname=''
dc_mailname_in_oh='true'
dc_localdelivery='mail_spool'
```
Где:
1. `DOMAIN.RU` - Доменное имя сервера, прописанное в обратной зоне.
2. `EXTERNAL_IP` - Внешний IP данного сервера
3. `RELAY_FROM_HOST_IPs` - IP адреса **satellit-серверов**, если они есть.
Параметр `dc_eximconfig_configtype` отвечает за режим работы почтового сервера, по умолчанию он будет установлен в `local`, что запретит вам отправлять почту на удаленные сервера.
Далее переходим к файлу `/etc/exim4/exim4.conf.template` и меняем там значения двух строк:
```
qualify_domain = DOMAIN.RU
primary_hostname = DOMAIN.RU
```
Здесь также задаем основное доменное имя, к ДНС зоне которого мы имеем доступ. Данные настройки потребуются нам в дальнейшем, при настройке почтовых записей.
Для системного администрирования важно, чтобы уведомления служб сервера для пользователя root отправленные по почте, отправлялись на нужный почтовый ящик, для этого в `exim4.conf.template` потребуется внести следующие изменения, обеспечивающие доставку почты, адресованной пользователю root:
```
mail_for_root:
driver = redirect
domains = DOMAIN.RU
condition = ${if eq{$local_part}{root}}
data = admin@nixys.ru
```
где:
* `DOMAIN.RU` - это название проекта
* `admin@nixys.ru` почтовый ящик администратора сервера
После выполнения всех действий перезапускаем exim4:
```exim4
service exim4 restart
```
проверяем, что он запущен:
```
service exim4 status
● exim4.service - LSB: exim Mail Transport Agent
Loaded: loaded (/etc/init.d/exim4; generated)
Active: active (running) since Sun 2021-12-19 18:18:11 MSK; 1s ago
Docs: man:systemd-sysv-generator(8)
Process: 943 ExecStart=/etc/init.d/exim4 start (code=exited, status=0/SUCCESS)
Tasks: 1 (limit: 1171)
Memory: 2.1M
CGroup: /system.slice/exim4.service
└─1191 /usr/sbin/exim4 -bd -q30m
```
Проверяем, что права на файлы и каталоги exim следующие:
```
drwxr-x--- 3 root Debian-exim [...] exim4
```
Помните, что для работы почтового сервиса в режиме `smarthost` открытие `25` порта не требуется, так как осуществляется только отправка почты.
На данном этапе вы можете проверить отправку почты из консоли, достаточно будет просто ввести команду вида:
```shell
echo "Hello there" | mail -s "world" -r адрес@отправителя адрес@получателя
```
Однако с учетом текущих настроек, почта для вашего домена вряд ли дойдет до получателей. В третьей части статьи мы расскажем, как настроить все почтовые записи таким образом, чтобы ваша почта не оказалась в СПАМе.
## Заключение
Обратите внимание, что в данной статье не описывается настройка фаервола. Вы можете настроить правила фаервола любым из доступных вам решений. Для простых проектов мы используем надстройку над `iptables` в виде пакета `nxs-ferm`, в основу которого лег стандартный ferm с небольшими изменениями.
Во второй части статьи мы расскажем о настройке веб-серверов.
Создание площадок и пользователей площадок, обеспечения ими доступов, а также о настройке почтовых записей для отправки почты будет отражено в третьей части статьи.