Оглавление
Часть 1. Настройка среды Debian для повседневного использования
Часть 2. Создание сервера — настройка LAMP в Debian
Часть 3. Создание персонального облака — установка и настройка Nextcloud
Быстрая навигация по главе
Предисловие
Установка программного обеспечения
Настройка веб-сервера 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.
Дата последней правки: хх.хх.хххх.
Первая версия.
Описывается установка и настройка LAMP в Debian 8.7.x.
Комментарии (19)
Vinni37
30.01.2018 09:02Apache и Nginx – это пара веб-серверов с открытым исходным кодом, на которых построено порядка 55% серверов во всего мира
Тут как всегда не учитывается процент, когда Nginx стоит перед Apache в качестве прокси
Angrynik
30.01.2018 13:39Самоподписанный сертификат в 2018 году? Вы это серьезно?
Если используете его в домашней сети — лучше вообще не поднимать ssl. Те же устойства от apple просто не примут самоподписанный сертификат и не оставят опций.
Ну а если сервер с выходом в интернет…AlexanderS Автор
30.01.2018 13:50Радуют меня такие комментарии в стиле «Это Моё Мнение»)
Проблема только в том, что ты только узнаёшь чьё-то мнение, а почему оно такое — непонятно.
В чём минусы самоподписного сертификата с точки зрения обеспечения шифрования обмена между клиентом и сервером? Почему его лучше не использовать в домашней сети?
Apple — это контора которая много чего решает за пользователя, поэтому у меня нет устройств Apple. И вообще, если устройство меня будет ограничивать подобным образом — в топку его! На андроиде тоже с таким сталкивался. Чего это вообще за мода пошла — если сертификат просрочен или неизвестен — ну выведи предупреждение и дай выбор переходить на ресурс или нет.
Ну а если сервер с выходом в интернет…
Не понял мысль за многоточием. Разверните, если нетрудно.solalex
30.01.2018 15:50наверно имелось ввиду сертификат от Let's Encrypt
на хабре есть мануал для nginx habrahabr.ru/post/306128AlexanderS Автор
30.01.2018 18:03Мне не очень понятно какая принципиальная разница между самоподписным сертификатом и тем же Let's Encrypt. Только удобство? Нет, если делать сервер и размещать сайты для людей, это да — не стоит людей мучить лишними действиями. Но если для себя — с т.з. безопасности же вроде без разницы должно быть, SSL же всё равно будет?
shteyner
30.01.2018 19:07Смотря для каких целей, вообще некоторые клиенты на телефоны не могут работать с webdav с самоподписанными сертификатами, так же как и некоторые программы. Вообще, не критично, если не надоедает в браузере красная плашка.
Вообще, можно воспользоваться бесплатным dns и завести бесплатное же доменное имя и через бесплатный же letsencrypt получить валидный сертификат.
vanxant
30.01.2018 23:45По факту самоподписанный сертификат защищает примерно ни от чего. Если Ева может запустить сниффер и перехватить ваш трафик, то она либо физически влезла в сеть, либо имеет админа / рута на одном из устройств (без таких прав сетевуху в промискуитет не переведешь). А значит она может стать человеком-посередине (через подделку arp, dns, фейковой ap) и направить ваш трафик через свое устройство. Дальше, если у вас самоподписанный серт, она просто выпускает свой такой же самоподписанный, и вы никак это не заметите. А вот подделать незаметно сертификат от letsencrypt уже сильно сложнее.
AlexanderS Автор
31.01.2018 07:27Спасибо за ответ, теперь стало понятнее.
Но можно ли обеспечить безопасность без всяких внешних сервисов, своими силами? Какие-то может быть параметры сертификата? Или отсутствие стороннего доверительного центра — это критично?vvzvlad
31.01.2018 15:43Сделать корневой сертификат, внести его в хранилица устройств, а потом с помощью его подписать сертификат на сайте. Если с помощью MITM сертификат сайта будет изменен, то это станет видно. И тут Apple в плюсе.
AlexanderS Автор
31.01.2018 17:32Понятно. Но сейчас вроде любой современный браузер как минимум предупредит о несоответствии сертификата? Но — это только браузеры.
malishich
30.01.2018 16:19Подскажите пожалуйста хорошую и информативную статью по комплексной настройке защиты своего веб-сервера на Linux. Я собираюсь разместить WEB + SVN и открыть порты в интернет только для себя. Один раз попробовал просто голую linux машину — через пару дней уже взломали (судя по «левой» активности), и даже пару каких-то программ поставили, пришлось убрать из интернета.
nikolayv81
30.01.2018 23:01Есть отличный способ, пароли в 10-12 случайных символов. Уж очень долго подбирать.
Ломают обычно не ssh а установленные wordpress-ы и тому подобные вещи.
AlexanderS Автор
30.01.2018 23:16Могу попробовать интереса ради виртуалку с тем, что я описал в этой статье, вытащить в инет на неделю. Но только у меня же пароли везде по 16 символов, плюс шесть неудачных попыток — IP улетает на месяц в бан. Тут… подобрать-то нереально — не будут же обширный ботнет заряжать ради какого-то безымянного сервера)
OnYourLips
30.01.2018 23:31Три команды (которые на самом деле можно свести в одну) и у нас локально установлен полноценный и современный сервер. Это совсем просто!
Мне кажется, что это уже перебор для описания apache с php5 (активная поддержка которого закончена в прошлом году).AlexanderS Автор
31.01.2018 23:39Сдаётся мне что установить php7 вместо php5 — не сильно большая и сложная задача. Правда, всего скорее, придётся дополнительный репозиторий поключать, так как debian довольно консервативная система, хотя для Stretch он уже и может быть доступен — это надо пробовать.
А вообще бы с радостью почитал вашу статью о варианте установки и подробной настройки актуального сервера, так скажем, начального уровня.
vin2809
Большое спасибо за публикацию. Дойдут руки — может быть и я попробую, что такое Linux…
А на счет вариантов исполнения с GUI или без, так всем не угодишь. Описывая свой вариант Вы получили массу комментариев, что дало бесценный опыт, причем без затрат времени на поиск и изучения документации. Тот, кто захочет, сможет прочитать весь материал (вместе с комментариями) и создать СВОЕ облако.
AlexanderS Автор
Если несколько человек «попробуют, что такое Linux» прочитав эти статьи — значит я писал не зря)