История создания домашнего облака. Часть 2. Создание сервера — настройка LAMP в Debian

  • Tutorial
На пути создания своего облачного сервиса пока мы только освоились в системе Debian. Теперь пришла пора для следующего шага — создание и настройка веб-сервера, на базе которого можно будет запустить Nextcloud.


Оглавление


Часть 1. Настройка среды Debian для повседневного использования
Часть 2. Создание сервера — настройка LAMP в Debian
Часть 3. Создание персонального облака — установка и настройка Nextcloud
Часть 4. Актуализация 2018 – Debian 9 и Nextcloud 13



Быстрая навигация по главе


Предисловие
Установка программного обеспечения
Настройка веб-сервера Apache2 и доступа к нему по HTTP и HTTPS протоколам
Настройка SQL
Настройка PHP
Настройка доступа SSH
Защита доступа
Справочный материал по веб-серверу
Справочный материал по MySQL
Справочный материал по fail2ban



Предисловие


В первой части этой истории был показан один из возможных вариантов настройки графического интерфейса Debian для удобного и привычного (исключительно субъективная точка зрения автора) использования человеком, пришедшим в Linux из Windows. И если для настройки виртуальной машины с Debian я пользовался только хостовой системой, то далее я специально работал только в этой виртуальной машине, ища информацию в интернете, конспектируя её в Notepadqq или gedit, слушая музыку через Аudacious, открывая файлы через LibreOffice и тому подобное. Таким образом можно обжиться и гораздо глубже почувствовать и оценить работу с операционной системой и её окружения, которое в стандартной поставке Debian довольно полноценно и функционально.

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

Текущая цель – создание сервера, чему и будет посвящена эта часть. Сервер можно настроить как с установкой и использованием графического интерфейса, так и без него. Во втором случае из предыдущей части можно просто пропустить разделы, касающиеся установки и настройки ПО для графического интерфейса и его настройки, установки пакетов графический программ и vmware-tools.

Я ничего не вижу плохого в использовании графического интерфейса при создании сервера: если человеку привычнее, удобнее и комфортнее сделать свой первый или второй сервер с графической средой – почему бы и нет? В конце концов, мой веб-сервер с графическим интерфейсом отработал год и отработает еще столько лет, сколько потребуется. Однако нужно иметь ввиду некоторые моменты.

В идеальном варианте единожды настроенная система должна будет работать без нашего вмешательства очень долго время. Мой сервер в «чистовом» варианте был настроен за два дня, а отработал без вмешательства практически год. Это значит, что графический интерфейс был задействован 0,05% времени активного существования сервера (компьютер работает только половину суток) и при этом занимал ресурсы: оперативную память, дисковое пространство, процессорное время. Все эти ресурсы лучше направить на обеспечение функционирования самого сервера: например, поднять memory_limit для PHP или вместить больше пользовательских данных на жесткий диск. Кроме этого, в случае проблем и неполадок при работе с реально удалённым сервером зачастую гораздо проще задействовать SSH-доступ. В данном контексте наличие графического интерфейса нежелательно и именно поэтому вторым сервером в моей сети уже была виртуальная машина без графического окружения, на которой из графического ПО был установлен только Midnight Commander, который я использовал для перемещения по файловой системе и редактирования файлов настроек через его редактор mcedit. Поэтому ниже приведена универсальная инструкция: даны команды с упором на использование командной строки, однако подразумевается, что в самый первый раз пользователь настраивает машину с графическим окружением, чем обусловлено использование браузера для локальной проверки доступности созданных сайтов и некоторые особенности настройки почтовой программы.

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

Примечание
При дальнейшем чтении в конструкциях вида http:// 127.0.0.1 (https:// 127.0.0.1) пробел после http:// (https://) необходимо убирать при вводе в адресную строку браузера. Пробел вставлен при публикации этой статьи с целью воспрепятствовать автоматической конвертации движком сайта текста в ссылки.



Установка программного обеспечения


Apache и Nginx – это пара веб-серверов с открытым исходным кодом, на которых построено порядка 55% серверов во всего мира. Apache является самым популярным веб-сервером с 1995 года и я выбрал именно его надеясь на хорошую задокументированность, популярность и, так сказать, хотелось начать с истоков. Это не значит, что Nginx хуже: Nginx эффективнее по потреблению ресурсов и работой под нагрузкой. В российском сегменте интернета сервер Nginx занимает порядка 65%, в то время как Apache – около 18%. Неплохая сравнительная статья двух серверов размещена на хабре.

Установка веб-сервера Apache2:

# apt-get install apache2 apache2-doc

И это – всё. Каких-то двадцать мегабайт и веб-сервер уже установлен. Не надо никаких перезагрузок или настроек — сервер уже умеет открывать странички HTML. Однако современный сайт в интернете – это не только набор статичных файлов, стилей, шрифтов и прочего подобного как двадцать лет назад. Современный сайт содержит скрипты, написанные на PHP, а динамическая информация (например, текстовой контент, комментарии, профили пользователей) пишется не в файлы рядом с PHP файлами, а в специальную базу данных SQL. Для полноценного сервера необходимо обеспечить поддержку этих технологий. Тем более – это несложно:

# apt-get install mysql-server mysql-client phpmyadmin
# apt-get install php5 php5-mysql libapache2-mod-php5

В процессе установки MySQL будет задан запрос для установки пароля суперпользователя mysql и нужно будет выбрать сервер apache2 для автоматической настройки работы с mysql. При установке пакета phpmyadmin я согласился с автоматической настройкой пакета и везде ввёл пароль суперпользователя mysql. Установка PHP происходит без каких-либо запросов.

Я не стал использовать более быстрый PHP7 или свободный MariaDB в качестве альтернативной открытой замены SQL и решил построить свой сервер на «каноническом» LAMP = Linux + Apache + MySQL + PHP, используя старые и проверенные решения, в случае проблем с которыми я бы мог быстро и беспроблемно найти информацию в интернете.

Три команды (которые на самом деле можно свести в одну) и у нас локально установлен полноценный и современный сервер. Это совсем просто!

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



Настройка веб-сервера Apache2


Для начала необходимо убедиться в том, что веб-сервер работает. Для этого нужно открыть браузер и набрать адрес http:// 127.0.0.1 (localhost). Должна открыться веб-страница с обнадёживающей надписью: «Apache2 Debian Default Page. It's works!». Сервер действительно работает. Если у вас есть набор файлов сайта 2000-го года, то его можно разместить в директории /var/www/html и он наверняка будет открываться на нашем сервере.



Все основные настройки веб-сервера хранятся по пути /etc/apache2. Если открыть эту директорию, то можно увидеть основной файл конфигурации apache2.conf и директории conf-available, mod-available, sites-available. В этих директориях содержатся заранее сконфигурированные файлы с настройками (так называемые сниппеты), которые можно просто использовать по умолчанию, со своими правками или взять их как шаблон для создания своих конфигураций. Например, в директории sites-available находится конфигурационный файл хоста по умолчанию 000-default.conf. Если его открыть и поизучать, то окажется, что этот файл как раз и задаёт путь, по которому открывается наш сайт по адресу http:// 127.0.0.1: «DocumentRoot /var/www/html». Мало того, строчка «<VirtualHost *:80>» означает, что если я выпущу свою машину в локальную сеть и буду обращаться к ней по порту 80 (порт для HTTP), то мне будет открываться сайт, расположенный по пути /var/www/html. Как в этом убедиться?

Сначала нужно узнать IP адрес, который был назначен виртуальной машине после её загрузки. Для просмотра конфигурации сетевых адаптеров выполним:

# ifconfig

В информации, выведенной на консоль несложно определить, что для адаптера eth0 установлен следующий адрес:

inet addr:192.168.233.138

Теперь на хостовой машине я открываю в браузере адрес http:// 192.168.233.138 и ожидаю, что откроется знакомая страница. Но… она не открывается. Через некоторое время мой браузер пишет: «Время ожидания соединения истекло». И правильно пишет. Ведь в первой части я включил файрвол, но порт 80 не открыл! Исправим это:

# ufw allow 80

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

Помимо директорий -available так же присутствуют ещё директории -enabled, которые содержат то, что на данный момент «включено». Если заглянуть в них, то можно увидеть, что эти директории содержат ссылки на файлы, находящиеся в директориях -available. В директории sites-enabled на данный момент только одна ссылка – на файл /etc/apache2/sites-available/000-default.conf. Это очень удобно — ярлыками мы можем управлять включением или отключением хостов без правки их конфигурационных файлов. Кроме этого источник конфигурации – один файл в независимости включена эта конфигурация сейчас или нет и это предотвращает ошибки, когда что-то правится в каком-то одном файле, а в другом — забывается. Для отключения нашего хоста нужно удалить требуемый ярлык, а для его включения – создать его. Для того, чтобы не удалять или создавать ярлыки вручную проще и надёжнее использовать специальные утилиты.

Отключаем виртуальный хост:

# a2dissite 000-default

Включаем виртуальный хост:

# a2enssite 000-default

После каждого изменения нужно перезагрузить конфигурации хостов или перезапустить сервер:

# service apache2 reload

или

# service apache2 restart

Итак, базовое понимание как конфигурировать обычные хосты в apache теперь имеется, и далее я покажу пример того, как я сконфигурировал свой сервер для работы по HTTP и HTTPS протоколам.

Начать нужно с того, что при отключении виртуального хоста 000-default отключения как такового не происходит. То есть, сайт как открывался изнутри и снаружи виртуальной машины – так и будет открываться в независимости от нахождения его конфигурации в папке sites-enabled. Это было неожиданно и я потратил относительно много времени, чтобы понять всё ли я правильно сделал или понял. До конца я с этим так и не разобрался, видимо это связано с тем, что путь /var/www/html задан глобально как директория по умолчанию для DocumentRoot. Так как мне не хотелось, чтобы было включено и доступно что-то лишнее я решил избавиться от самой директории html, а для всех вложенных /var/www по умолчанию доступ запретить.

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

# nano /etc/apache2/sites-available/000-default.conf

Содержимое конфигурационного файла стало следующим:

<VirtualHost *:80> 
  ServerName localhost
  ServerAdmin user@localhost
  
  DocumentRoot /var/www
  <Directory /var/www>
    Options FollowSymLinks
    AllowOverride All
    Require all denied
  </Directory>

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Этой конфигурацией я переустановил директорию по умолчанию на /var/www, разрешил серверу следовать по символическим ссылкам в этой директории, разрешил серверу выполнять все директивы, объявленные в найденных файлах .htaccess и запретил доступ в этот каталог. Логика этих действий в том, чтобы я мог управлять доступом в эту директорию не обращаясь к настройкам веб-сервера вообще и не перезагружая его. Теперь нужно проверить это решение.
Переносим файл:

# mv /var/www/html/index.html /var/www/index.html

И удаляем каталог:

# rm /var/www/html

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

# service apache2 restart

Создаём файл:

# nano /var/www/.htaccess

В котором прописываем одну строку (без кавычек): «Require all granted».

Подытожим. Теперь пути /var/www/html нет, но хост по умолчанию переконфигурирован на путь /var/www, по которому находится файл index.html, причём по умолчанию, на уровне веб-сервера, доступ в эту директорию запрещён, но разрешается содержимым локально расположенного там файла .htaccess.

Открываем в браузере http:// 127.0.0.1 и видим уже знакомую страницу «Apache2 Debian Default Page. It's works». Теперь проверим работоспособность «локального» управления доступом:
Удаляем файл .htaccess:

# rm /var/www/.htaccess

И обновляем в браузере открытую страничку — должна открыться страница с уведомлением об ограничении доступа (Forbidden). Да, всё это работает, значит всё сделано правильно.

В принципе, этих нехитрых настроек вполне достаточно для дальнейшей беспроблемной работы веб-сервера. Но мне этого показалось мало. Сейчас наш веб-сервер умеет работать только по протоколу HTTP. Но как быть с протоколом HTTPS? Ведь если в будущем выводить проекты на базе этого веб-сервера в интернет, то умение работать по этому протоколу как минимум желательно. И я решил организовать поддержку HTTPS на основе создания самоподписного сертификата SSL.

Сначала нужно получить SSL сертификат, который будет установлен на наш сервер. Никакого домена у нас нет, да и статичного IP адреса тоже по сути не имеется. Но это всё неважно, потому что сертификат я буду генерировать самостоятельно, используя средства своей системы.

Внимание! В приведённой ниже инструкции считается, что сервер установлен на «безымянную» машину. Если имеется реальный IP или доменное имя, то их нужно указать в ТРЁХ местах: <Common Name IP/Domain>; <ServerName IP/Domain>; <Redirect "/" «https: //IP/Domain/»> — в соответствующих конструкциях заменить IP/Domain на IP адрес или доменное имя. В приведённом ниже тексте вместо IP/Domain используется localhost.

Сгенерируем SSL-сертификат:

# openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/ssl/private/apache-selfsigned.key -out /etc/ssl/certs/apache-selfsigned.crt

Данная команда создаст самоподписной сертификат стандарта Х.509 сразу аж на 10 лет с пропуском опции защиты сертификата парольной фразой — это нужно чтобы при запуске сервер Apache имел возможность читать файл без вмешательства пользователя, так как установив пароль, придется вводить его после каждой загрузки или перезагрузки сервера. Вместе с сертификатом будет создан новый ключ RSA на 2048 бит, которым и будет подписан сертификат. Опции –keyout и –out указывают пути, по которым OpenSSL должен сгенерировать ключ и сертификат.

В процессе создания сертификата будут заданы вопросы, на которые я указал следующие данные:

Country Name = MW
State or Province Name = Sun System
Locality Name = Lunar
Organization Name = Hellium Inc.
Organizational Unit Name = 2
Common Name = localhost
Email Address = user@localhost

Далее нужно создать ключи Диффи-Хеллмана для обеспечения поддержки PFS:

# openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

В терминале побегут точечки и плюсики и после окончания мультфильма можно создать файл ssl-params.conf, в котором будут определены параметры SSL для сервера:

# nano /etc/apache2/conf-available/ssl-params.conf

Для безопасной актуальной настройки я использовал код, сгенерированный в генераторе для конфигурации SSL на mozilla.github.io. В генераторе я выбрал сервер Apachе2, профиль Modern и правильно выставил версии сервера и OpenSSL, которые можно узнать по следующим командам:

# apache2 -v
# openssl version


В результате у меня получился следующий текст:

# 14-01-2018 / for apache2 2.4.10 & openssl 1.0.1t
# from https://mozilla.github.io/server-side-tls/ssl-config-generator/
# parametrs help: https://raymii.org/s/tutorials/Strong_SSL_Security_On_Apache2.html
# modern configuration, tweak to your needs
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite 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
SSLHonorCipherOrder on
SSLCompression off

# OCSP Stapling, only in httpd 2.3.3 and later
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache shmcb:/var/run/ocsp(128000)

Теперь настроим виртуальный хост с поддержкой SSL:

# nano /etc/apache2/sites-available/default-ssl.conf

Текст этого файла я привёл к следующему виду:

<IfModule mod_ssl.c>
  <VirtualHost _default_:443>
    ServerAdmin user@localhost
    ServerName localhost

    DocumentRoot /var/www
    <Directory /var/www>
      Options FollowSymLinks
      AllowOverride All
      Require all denied
    </Directory>
    
    # HSTS (mod_headers is required) (15768000 seconds = 6 months)
    Header always set Strict-Transport-Security "max-age=15768000"
    
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    SSLEngine on
    SSLCertificateFile  /etc/ssl/certs/apache-selfsigned.crt
    SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key

    <FilesMatch "\.(cgi|shtml|phtml|php)$">
      SSLOptions +StdEnvVars
    </FilesMatch>
    <Directory /usr/lib/cgi-bin>
      SSLOptions +StdEnvVars
    </Directory>

    BrowserMatch "MSIE [2-6]" \
      nokeepalive ssl-unclean-shutdown \
      downgrade-1.0 force-response-1.0
    BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
    
  </VirtualHost>
</IfModule>

Из вышеприведённого следует, что у нас в качестве директории DocumentRoot определена так же /var/www, доступ к которой настроен аналогично предыдущим настройкам. Включен механизм HSTS, который способствует принудительной установке соединения через протокол HTTPS. Включена поддержка SSL с указанием используемых сертификата и ключа, а также подключена поддержка обработки данных сертификата в PHP и CGI-скриптах. Последняя секция призвана обеспечить совместимость с ранними версиями браузера Internet Explorer и, в целом, необходимой не является.

Теперь сделаем финальные штрихи.

Откроем порт для SSL:

# ufw allow 443

Включим модули apache для поддержки SSL и HSTS:

# a2enmod ssl
# a2enmod headers


Включим конфигурацию SSL:

# a2enconf ssl-params

Включим виртуальный хост с поддержкой SSL:

# a2ensite default-ssl

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

# service apache2 restart

Вот и наступил интересный момент – проверки работоспособности нового функционала настроенной системы.

Создаём файл:

# nano /var/www/.htaccess

В котором прописываем одну строку: «Require all granted».

Открываем в браузере https:// 127.0.0.1. Должна открыться страница о неизвестном сертификате, после принятия которого (однократное или постоянное разрешение) откроется уже знакомая страница с уведомлением о запущенном веб-сервере.

Удаляем файл .htaccess:

# rm /var/www/.htaccess

И обновляем в браузере открытую страничку — должна открыться страница с уведомлением об ограничении доступа (Forbidden). Всё работает корректно. Теперь наши сайты доступны и по HTTP и через HTTPS.

Доступ по HTTP можно оставить включенным, отключить или сделать принудительное перенаправление на HTTPS.

Для включенного доступа HTTP делать ничего не нужно, так как запросы на порты 80 и 443 сервер обрабатывает индивидуально и наш сайт в папке /var/www будет открываться как через HTTP, так и через HTTPS.

Для отключения доступа по HTTP необходимо просто отключить соответствующий виртуальный хост и перезапустить веб-сервер:

# a2dissite 000-default
# service apache2 restart


Теперь, если открыть в браузере http:// 127.0.0.1 должна открыться страница с уведомлением об отсутствии страницы (Not Found).

Самый интересный третий вариант. В этом случае HTTP формально остаётся включенным, но обработка данных будет принудительно перенаправлена через HTTPS.

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

# a2enmod rewrite

Теперь откроем файл 000-default.conf:

# nano /etc/apache2/sites-available/000-default.conf

И перед закрывающимся тегом добавим нижеприведённый текст:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]

Перезапустим сервер:

# service apache2 restart

Создаим файл:

# nano /var/www/.htaccess

В котором прописываем одну строку: «Require all granted».

Теперь, если открыть в браузере адрес http:// 127.0.0.1 нас автоматически перенаправит на https:// 127.0.0.1 с предупреждением о неизвестном сертификате (если ранее он не был внесён в список исключений в браузере), после принятия которого откроется уже знакомая страница с уведомлением о запущенном веб-сервере.



Настройка SQL


Для первичной настройки mysql достаточно выполнить следующую команду:

# mysql_secure_installation

После ввода пароля суперпользователя mysql я ответил на задаваемые вопросы в следующем порядке:

  • отказался от изменения пароля root;
  • подтвердил удаление анонимных пользователей из БД;
  • подтвердил блокировку удаленного подключения для root (в целях безопасности пуcть root подключается только локально);
  • подтвердил удаление тестовых БД;
  • согласился с перезагрузку таблиц привилегий.

Для проверки работоспособности mysql можно выполнить следующую команду:

# mysql -uroot -p

После ввода пароля суперпользователя mysql мы видим приглашение mysql – значит сервис запущен и работает. Выйти из терминала mysql можно введя команду «exit».

Для проверки работоспособности phpmyadmin открываем в браузере адрес http:// 127.0.0.1/phpmyadmin. Если открылась страница c приглашением войти в phpmyadmin значит сервис запущен и работает.



Настройка PHP


После установки PHP я открыл файл его настроек:

# nano /etc/php5/apache2/php.ini

И привёл некоторые параметры к следующему виду:

  • memory_limit = 1024M
  • default_charset = «UTF-8»
  • upload_max_filesize = 256M
  • sendmail_path = /usr/bin/fake_sendmail.sh

С помощью модуля PHP можно обеспечить кеширование данных в памяти. Кеширование полезно при высокой нагрузке на сервер для данных, генерация которых требует большого количества ресурсов, например, результатов запросов к базе данных или обработкой «тяжелых» кусков шаблона сайта. В качестве сервера кеширования я выбрал модуль memcached.

Установка memcache:

[ Данный текст написан специально для сайта geektimes.ru автором AlexanderS.
Ссылка на источник необязательна, но его упоминание крайне желательно! ]


# apt-get install memcached php5-memcached

Посмотрим на настройки конфигурации сервиса:

# nano /etc/memcached.conf

В настройках я увеличил размер используемой памяти для кеширования: -m 64 -> -m 256. И проверил наличие режима работы только в локальной зоне: -l 127.0.0.1.

Перезапускаем сервис кеширования и веб-сервер:

# service memcached restart
# service apache2 restart


Теперь нужно убедиться в работоспособности сервиса. Для этого создаём файл:

# nano /var/www/info.php

И добавим в него следующий текст:

<?php
    phpinfo ();
?>

Не забываем проверить наличие файла .htaccess в директории /var/www с соответствующим разрешающим содержимым, если его там нет – создаём.

Теперь можно открыть в браузере http:// 127.0.0.1/info.php — должна открыться страница со сведениями о PHP, в которой нужно проверить наличие в ней секции memcached. Если таблица появилась — PHP работает.

Проверить запущенный сервис memcached можно так:

$ ps -aux | grep memcached

В терминале должна вернуться строка, содержащая настройки memcached.

Создание почтовой заглушки для PHP

При настройках PHP в качестве параметра sendmail_path был указан шелл-скрипт. Функция этого скрипта — сохранять письма, отправленные через стандартную функцию php mail(), на локальной машине, в какой-то удобной папке, а не отправлять их куда-то.

Создадим файл:

# nano /usr/bin/fake_semdmail.sh

Со следующим содержимым:

#!/bin/sh
prefix="/var/mail/sendmail/new"
numPath="/var/mail/sendmail"

if [ ! -f $numPath/num ]; then
echo "0" > $numPath/num
fi
num=`cat $numPath/num`
num=$(($num + 1))
echo $num > $numPath/num

name="$prefix/letter_$num.txt"
while read line
do
echo $line >> $name
done
chmod 777 $name
/bin/true

Сделаем этот файл исполняемым:

# chmod +x /usr/bin/fake_semdmail.sh

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

# mkdir /var/mail/sendmail /var/mail/sendmail/cur /var/mail/sendmail/new /var/mail/sendmail/tmp

И назначаем права, чтобы сервер мог записывать файлы в этой папке:

# chmod 777 -R /var/mail/sendmail

Теперь все исходящие письма будут складываться в /var/mail/sendmail. Их можно просматривать текстовым редактором, а можно собирать почтовой программой. В комплекте предустановленного ПО Debian есть почтовый клиент Evolution. При настройке учётной записи в качестве типа сервера нужно выбрать «Почтовые каталоги в формате Maildir» и указать путь к почтовому каталогу (/var/mail/sendmail), а в качестве сервера указать «Sendmail».

Всё. В целом с сервером мы закончили — получена универсальная виртуальная машина, на базе которой можно строить свои сетевые сервисы. Я оставил и HTTP, и HTTPS доступы. Однако, после того как получен опыт по созданию и настройке сервера, а также добавлению сайтов (см. ниже) на него, я бы рекомендовал создать новую виртуальную машину с сервером без графического интерфейса как более оптимальную по потреблению ресурсов.



Настройка доступа SSH


Сервер не был бы полноценным сервером без наличия доступа через SSH. Так называемый «шелл» позволяет быстро и безопасно подключиться к удалённому серверу, используя, например, небольшую программку putty, — на локальном компьютере мы получаем прямой доступ к терминалу удалённого сервера.

Установка сервиса:

# apt-get install ssh

Откроем порт для SSH (вообще-то, порт по умолчанию должен быть под номером 22, но ниже я переопределил порт в конфигурации SSH):

# ufw allow 106

Для организации доступа для нашего пользователя user нужно открыть файл:

# nano /etc/ssh/sshd_config

И добавить в конец файла директиву:

AllowUsers user

Кроме этого, в целях безопасности я сделал в этом файле следующие изменения:

  • сменил порт с 22 на какой-то другой (список портов): Port 22 -> Port 106
  • отключил устаревший протокол: Protocol 2,1 -> Protocol 2
  • отключил удалённый доступ для root: PermitRootLogin yes (или PermitRootLogin without-password) -> PermitRootLogin no

После чего перезапускаем сервис:

# service sshd restart

Теперь я могу запустить программу putty на хостовой машине и подключиться к своему серверу в консольном режиме введя адрес подключения 192.168.233.138, порт 106 и имя пользователя user. При подключении необходимо ответить утвердительно на принятие ключей и ввести пароль пользователя user. Если понадобиться выполнить команды от суперпользователя, то можно использовать уже известную команду su.



Защита доступа


Я не стал заниматься защитой веб-сервера от DDoS, изначально полагая, что если он будет размещаться на VPS/VDS, то эффективную защиту обеспечит хостинг, а если делать свой сервер «торчащий» в интернет, то этим вопросом надо заниматься серьёзно и это тема отдельной статьи. Защита от Slow HTTP DDoS делается относительно просто в соответствии с многочисленными инструкциями в интернете, но она не спасёт от распределенной атаки, производимой с множества разных IP адресов.

При DDoS наш сервер просто перестанет работать на какое-то время. Но после атаки, которая не будет длиться вечно, работа сервера восстановится. А вот если кто-то сумеет заполучить доступ по SSH, то контроль за сервером будет потерян, а данные на нём скомпроментированы, поэтому контроль доступа к серверу по SSH – здравая идея.

Самое простое и банальное, что можно сделать – сменить стандартный порт, что мы и сделали при настройке SSH. Лет пять назад я «выставил» только что созданный сервер в интернет по недавно полученному реальному IP адресу и был удивлён тому, что за неделю существования сервера, про который ещё никто ничего не знал, в логах системы накопилось большое количество записей о неудачных попытках авторизации по SSH и FTP. Очевидно, что в современном интернете существует немалое количество сервисов-роботов, которые ищут компьютеры с открытыми портами и пытаются к ним подключиться, перебирая пароли по имеющейся базе или используя метод полного перебора.

К счастью для нас, существует такая штука как fail2ban:

# apt-get install fail2ban

Сразу после установки утилита уже сконфигурирована на защиту большинства портов и если в логах системы за десять минут появится больше шести провальных попыток подключиться, то нарушитель будет заблокирован на десять минут. Механизм работы fail2ban довольно прост – по определённым триггерам срабатывают так называемые джейлы, которые определяют действие, предназначенное для защиты приложения.

Параметры блокировки можно задавать индивидуально:

# nano /etc/fail2ban/jail.local

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

# общие настройки
[DEFAULT]
ignoreip = 127.0.0.1
bantime = 2592000
findtime = 43200
maxretry = 6
banaction = iptables-multiport
# настройка отправки сообщения на почту
destemail = user@localhost
sendername = Fail2Ban
mta = sendmail
action = %(action_mwl)s

# защита SSH
[ssh]
enabled = true
port = 106
filter = sshd
logpath = /var/log/auth.log

# выявляем неудачные попытки ввода пароля
[apache]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache*/*error.log

# выявляем потенциальные сканирования для применения эксплойтов и php уязвимостей
[apache-noscript]
enabled = true
port = http,https
filter = apache-noscript
logpath = /var/log/apache*/*error.log

# выявляем попытки переполнения Апача
[apache-overflows]
enabled = true
port = http,https
filter = apache-overflows
logpath = /var/log/apache*/*error.log
maxretry = 2

# выявляем неудачные попытки в поиске домашней директории на сервере
[apache-nohome]
enabled = true
port = http,https
filter = apache-nohome
logpath = /var/log/apache*/*error.log
maxretry = 2


Приведённая выше настройка позволяет не контролировать локальный доступ, а при шести неверных попыток входа в течение 12 часов банит IP адрес атакующего, используя iptables, на 30 дней. Контролируется не только доступ по порту для SSH, но и подозрительные действия, направленные на дестабилизацию работы веб-сервера.



Справочный материал по веб-серверу


Запуск, остановка и перезагрузка сервера:

# service apache2 start
# service apache2 stop
# service apache2 restart


Перезагрузка конфигураций сервера:

# service apache2 reload

Включение и отключение хоста test:

# a2ensite test
# a2dissite test


Включение и отключение конфигурации test:

# a2enconf test
# a2disconf test


Проверка синтаксиса файлов (должно вернуться: «Syntax OK»):

# apache2ctl configtest

Вариант добавление сайта с доступом по HTTP или HTTPS используя имеющийся виртуальный хост

Допустим, на наш сервер нужно добавить новый сайт, размещённый в директории site.com, расположенной в /home/user/www. Это может быть удобно, так как пользователю user не нужно будет покидать пределы своего домашнего каталога при работе с сайтом.

Выставляем права для пользовательского каталога (на всякий случай):

# chmod 755 /home/user

Создаём каталога для сайта:

$ mkdir /home/user/www /home/user/www/site.com

Размещаем символическую ссылку на каталог сайта:

# ln -s /home/user/www/site.com /var/www/site.com

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

# nano /etc/apache2/sites-available/000-default.conf

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

# nano /etc/apache2/sites-available/default-ssl.conf

И добавляем в открытый файл нижеприведённое содержимое перед закрывающимся тегом /VirtualHost:

<Directory /var/www/site.com>
  Options FollowSymLinks
  AllowOverride All
  Require all granted
</Directory>

Перезапускаем веб-сервер:

# service apache2 restart

Проверяем доступность сайта по адресу http:// 127.0.0.1/site.com или https:// 127.0.0.1/site.com (методика проверки — см. ниже). Нужно обратить внимание, что сайт будет открываться в независимости от наличия файла .htaccess, так как для директории с сайтом установлена директива: «Require all granted».

Вариант добавление сайта с доступом по HTTP или HTTPS используя новый виртуальный хост и настройкой обращения к сайту через его доменное имя, а не IP

Условия задачи – те же, что и выше: допустим, на наш сервер нужно добавить новый сайт, размещённый в директории site.com, расположенной в /home/user/www. Но теперь я ещё хочу обращаться к сайту вводя в строку браузера только его доменное имя.

Выставляем права для пользовательского каталога (на всякий случай):

# chmod 755 /home/user

Создаём каталога для сайта:

$ mkdir /home/user/www/site.com

Размещаем символическую ссылку на каталог сайта:

# ln -s /home/user/www/site.com /var/www/site.com

Для добавления доступа по HTTP создаём файл:

# nano /etc/apache2/sites-available/site.com.conf

И добавляем в него следующее содержимое:

<VirtualHost *:80>
  ServerName site.com
  ServerAlias www.site.com
  ServerAdmin user@localhost

  DocumentRoot /var/www/site.com
  <Directory /var/www/site.com>
    Options FollowSymLinks
    AllowOverride All
    Require all granted
  </Directory>
  
  # Redirect HTTP->HTTPS
  #RewriteEngine On
  #RewriteCond %{HTTPS} off
  #RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]

  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Или для добавления доступа по HTTPS создаём файл:

# nano /etc/apache2/sites-available/site.com-ssl.conf

И добавляем в него следующее содержимое:

<IfModule mod_ssl.c>
  <VirtualHost _default_:443>
    ServerName site.com
    ServerAlias www.site.com
    ServerAdmin user@localhost

    DocumentRoot /var/www/site.com
    <Directory /var/www/site.com>
      Options FollowSymLinks
      AllowOverride All
      Require all granted
    </Directory>
    
    # HSTS (mod_headers is required) (15768000 seconds = 6 months)
    Header always set Strict-Transport-Security "max-age=15768000"
    
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    SSLEngine on
    SSLCertificateFile  /etc/ssl/certs/apache-selfsigned.crt
    SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key

    <FilesMatch "\.(cgi|shtml|phtml|php)$">
      SSLOptions +StdEnvVars
    </FilesMatch>
    <Directory /usr/lib/cgi-bin>
      SSLOptions +StdEnvVars
    </Directory>

    BrowserMatch "MSIE [2-6]" \
      nokeepalive ssl-unclean-shutdown \
      downgrade-1.0 force-response-1.0
    BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
    
  </VirtualHost>
</IfModule>

В /etc/hosts добавляем строку «127.0.0.1 site.com»:

# echo >> /etc/hosts 127.0.0.1 site.com

Активируем HTTP хост:

# a2ensite site.com.conf

Или активируем HTTPS хост:

# a2ensite site.com-ssl.conf

Перезапускаем веб-сервер:

# service apache2 restart

Проверяем доступность сайта по адресу http:// site.com или https:// site.com (методика проверки – см. ниже). Нужно обратить внимание, что сайт будет открываться в независимости от наличия файла .htaccess, так как для директории с сайтом установлена директива: «Require all granted».

Все действия производятся внутри гостевой виртуальной машины. Было бы интересно «открыть» сайт в браузере хостовой системы. Это несложно. Мы знаем доменное имя и IP адрес гостевой машины. Если хостовая система Windows, то необходимо открыть файл c:\Windows\System32\drivers\etc\hosts и в самый конец добавить следующую строчку:

192.168.233.138 site.com

После этого изменения компьютер или хостовую систему придётся перезагрузить. Теперь, при открытии в браузере сайта site.com обращение к нему будет перенаправлено на нашу виртуальную машину. Фактически, мы сделали простейшую маршрутизацию в своём личном интернете на уровне хостовой операционной системы.

В случае, если нужен доступ к виртуальному хосту только по HTTPS, но не хочется терять соединения по протоколу HTTP можно настроить редирект:

— создать файл /etc/apache2/sites-available/site.com.conf по вышеприведённой инструкции, если он не создан
— в файле /etc/apache2/sites-available/site.com.conf раскомментировать три строки RewriteEngine/RewriteCond/RewriteRule
— активировать хост site.com.conf, если он не активирован
— перезапустить сервер: # service apache2 restart

Проверка работоспособности добавленного сайта

Самый простой способ проверки доступности сайта — разместить в его корневой директории файл index.html с каким-то содержимым.

Создаём файл index.html:

$ nano /home/user/www/site.com/index.html

И добавляем в него следующее содержимое:

<html>
<head>
<title>TEST OK</title>
</head>
<body>
<h1>TEST OK</h1>
</body>
</html>

В зависимости от метода добавления сайта открыть в браузере адрес http:// 127.0.0.1/site.com (https:// 127.0.0.1/site.com) или http:// site.com (https:// site.com) — должна открыться страница содержащая текст «TEST OK».



Справочный материал по MySQL


Создание пользователя user123 с паролем pass123 и базой данных db123 через консоль.

Войти в mysql, введя пароль суперпользователя mysql при запросе:

# mysql -u root -p

И создать базу данных (префикс «mysql>» набирать не нужно, точка с запятой в конце обязательна):

mysql> CREATE DATABASE `db123`;

Создать пользователя user123 с паролем pass123:

mysql> CREATE USER 'user123'@'localhost' IDENTIFIED BY 'pass123';

Выдать привилегии пользователю на базу данных:

mysql> GRANT ALL PRIVILEGES ON `db123`.* TO 'user123'@'localhost';

Обновить таблицу привилегий:

mysql> FLUSH PRIVILEGES;

Выйти из mysql:

mysql> exit

Для проверки открыть адрес http:// 127.0.0.1/phpmyadmin и авторизоваться с реквизитами доступа user123/ pass123. Должен открыться доступ к базе данных db123.

Изменение пароля для root mysql c pass123 на pass456:

# mysqladmin -uroot -ppass123 password pass456

Изменение пароля пользователя user123 c pass123 на pass456:

# mysqladmin -uuser123 -ppass123 password pass456

Удаление пользователя user123:

mysql> DROP USER 'user123'@'localhost';

Удаление таблицы db123:

mysql> DROP DATABASE `db123`;



Справочный материал по fail2ban


Перезапуск сервиса:

# service fail2ban restart

Проверка запущенных правил:

# fail2ban-client status

Подробная статистика по правилу sshd:

# fail2ban-client status ssh

Разбанивание:

# fail2ban-client set ssh unbanip Banned_IP



Вернуться в начало, к оглавлению.



История создания домашнего облака. Часть 2. Создание сервера — настройка LAMP в Debian.
Версия текста: 1.0.0.
Дата первой публикации: 30.01.2018.
Дата последней правки: хх.хх.хххх.

Лог обновлений
1.0.0 [30-01-2018]
Первая версия.
Описывается установка и настройка LAMP в Debian 8.7.x.
Поделиться публикацией
Комментарии 19
    +2
    Большое спасибо за публикацию. Дойдут руки — может быть и я попробую, что такое Linux…

    А на счет вариантов исполнения с GUI или без, так всем не угодишь. Описывая свой вариант Вы получили массу комментариев, что дало бесценный опыт, причем без затрат времени на поиск и изучения документации. Тот, кто захочет, сможет прочитать весь материал (вместе с комментариями) и создать СВОЕ облако.
      +1
      Если несколько человек «попробуют, что такое Linux» прочитав эти статьи — значит я писал не зря)
      +2
      Apache и Nginx – это пара веб-серверов с открытым исходным кодом, на которых построено порядка 55% серверов во всего мира

      Тут как всегда не учитывается процент, когда Nginx стоит перед Apache в качестве прокси
      • НЛО прилетело и опубликовало эту надпись здесь
          +1
          Радуют меня такие комментарии в стиле «Это Моё Мнение»)
          Проблема только в том, что ты только узнаёшь чьё-то мнение, а почему оно такое — непонятно.

          В чём минусы самоподписного сертификата с точки зрения обеспечения шифрования обмена между клиентом и сервером? Почему его лучше не использовать в домашней сети?

          Apple — это контора которая много чего решает за пользователя, поэтому у меня нет устройств Apple. И вообще, если устройство меня будет ограничивать подобным образом — в топку его! На андроиде тоже с таким сталкивался. Чего это вообще за мода пошла — если сертификат просрочен или неизвестен — ну выведи предупреждение и дай выбор переходить на ресурс или нет.

          Ну а если сервер с выходом в интернет…

          Не понял мысль за многоточием. Разверните, если нетрудно.
            0
            наверно имелось ввиду сертификат от Let's Encrypt
            на хабре есть мануал для nginx habrahabr.ru/post/306128
              0
              Мне не очень понятно какая принципиальная разница между самоподписным сертификатом и тем же Let's Encrypt. Только удобство? Нет, если делать сервер и размещать сайты для людей, это да — не стоит людей мучить лишними действиями. Но если для себя — с т.з. безопасности же вроде без разницы должно быть, SSL же всё равно будет?
                0
                Смотря для каких целей, вообще некоторые клиенты на телефоны не могут работать с webdav с самоподписанными сертификатами, так же как и некоторые программы. Вообще, не критично, если не надоедает в браузере красная плашка.
                Вообще, можно воспользоваться бесплатным dns и завести бесплатное же доменное имя и через бесплатный же letsencrypt получить валидный сертификат.
                  0
                  По факту самоподписанный сертификат защищает примерно ни от чего. Если Ева может запустить сниффер и перехватить ваш трафик, то она либо физически влезла в сеть, либо имеет админа / рута на одном из устройств (без таких прав сетевуху в промискуитет не переведешь). А значит она может стать человеком-посередине (через подделку arp, dns, фейковой ap) и направить ваш трафик через свое устройство. Дальше, если у вас самоподписанный серт, она просто выпускает свой такой же самоподписанный, и вы никак это не заметите. А вот подделать незаметно сертификат от letsencrypt уже сильно сложнее.
                    0
                    Спасибо за ответ, теперь стало понятнее.
                    Но можно ли обеспечить безопасность без всяких внешних сервисов, своими силами? Какие-то может быть параметры сертификата? Или отсутствие стороннего доверительного центра — это критично?
                      0
                      Сделать корневой сертификат, внести его в хранилица устройств, а потом с помощью его подписать сертификат на сайте. Если с помощью MITM сертификат сайта будет изменен, то это станет видно. И тут Apple в плюсе.
                        0
                        Понятно. Но сейчас вроде любой современный браузер как минимум предупредит о несоответствии сертификата? Но — это только браузеры.
            0
            Подскажите пожалуйста хорошую и информативную статью по комплексной настройке защиты своего веб-сервера на Linux. Я собираюсь разместить WEB + SVN и открыть порты в интернет только для себя. Один раз попробовал просто голую linux машину — через пару дней уже взломали (судя по «левой» активности), и даже пару каких-то программ поставили, пришлось убрать из интернета.
              0

              Есть отличный способ, пароли в 10-12 случайных символов. Уж очень долго подбирать.
              Ломают обычно не ssh а установленные wordpress-ы и тому подобные вещи.

                0
                Могу попробовать интереса ради виртуалку с тем, что я описал в этой статье, вытащить в инет на неделю. Но только у меня же пароли везде по 16 символов, плюс шесть неудачных попыток — IP улетает на месяц в бан. Тут… подобрать-то нереально — не будут же обширный ботнет заряжать ради какого-то безымянного сервера)
                  0
                  Пароли лучшее вообще запретить. Авторизация только по ключам.
                +2
                Какой ламповый стэк технологий
                  0
                  Три команды (которые на самом деле можно свести в одну) и у нас локально установлен полноценный и современный сервер. Это совсем просто!
                  Мне кажется, что это уже перебор для описания apache с php5 (активная поддержка которого закончена в прошлом году).
                    0
                    Сдаётся мне что установить php7 вместо php5 — не сильно большая и сложная задача. Правда, всего скорее, придётся дополнительный репозиторий поключать, так как debian довольно консервативная система, хотя для Stretch он уже и может быть доступен — это надо пробовать.

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

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

                  Самое читаемое