Веб-сервер Apache до сих пор остается достаточно популярным и де-факто является стандартом веб-сервера для платформы Linux, так или иначе большинство современных веб-приложений продолжают разрабатываться таким образом, чтобы работать на Apache из коробки, кроме того, сам веб-сервер имеет достаточно низкий порог входа и легко осваивается. В данной статье мы рассмотрим, как настроить полноценный веб-сервер на базе Apache с поддержкой PHP и MySQL (стек LAMP) c обязательным шифрованием на базе сертификатов Let's Encrypt.
Онлайн-курс по устройству компьютерных сетей
На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.
И все-таки почему Apache? Потому что он имеет ряд преимуществ, которые выводят его на первую роль там, где не требуется высокой производительности, а требуется простота внедрения и освоения, а также устойчивость самого сервера к неквалифицированным действиям. Начнем с того, что именно по Apache можно найти самое большое количество материалов для начинающих, также на Apachе без лишних движений заработает практически любое веб-приложение.
А способность использовать для настройки файлы .htaccess позволяет обеспечить устойчивость сервера от некорректных настроек со стороны пользователя. В случае ошибки перестанет работать только один сайт или его часть, сам веб-сервер останется работоспособен. Это также позволяет удобно привлекать третьих лиц для работы с сайтом, не давая им доступа к основной конфигурации веб-сервера.
Работа Apache c PHP происходит как еще с одним модулем в едином адресном пространстве, это не требует дополнительной настройки и обеспечивает высокую производительность. Поэтому, вопреки распространенному мнению, производительность PHP в связке с Apache является наиболее высокой.
В целом можно сказать, что Apachе является крепким универсалом, да, он не самый быстрый, не самый экономичный, не самый самый. Но если вам нужен простой и универсальный веб-сервер - это про него.
В данной статье мы будем рассматривать установку стека LAMP в среде последних версий Debian и Ubuntu, они имеют небольшие различия по версиям используемого ПО, но при этом содержат актуальные версии, что позволит развернуть веб-сервер штатными средствами без подключения дополнительных репозиториев. Набор используемого ПО таков:
- Debian 12: Apache 2.4.57, PHP 8.2, MariaDB 10.11 LTS
- Ubuntu 22.04 LTS: Apache 2.4.52, PHP 8.1, MySQL 8.0 LTS
Все команды, если не указано иного, следует выполнять с правами суперпользователя root или через sudo.
В качестве примера имени сайта мы будем использовать:
- site.example
- www.site.example
Их следует заменить на реальное доменное имя, которое вы будете использовать.
Установка Apache 2.4 и получение сертификатов Let's Encrypt
Для установки веб-сервера Apache следует воспользоваться одной простой командой:
apt install apache2
Теперь если набрать в адресной строке браузера адрес веб-сервера, то вы увидите стандартную страницу-заглушку, это обозначает, что веб-сервер установлен и работает.
Стандартная система расположения конфигурационных файлов в Debian или Ubuntu подразумевает, что конфигурационные файлы хранятся в директориях available с расширением conf, а для подключения их к текущей конфигурации веб-сервера для них создаются символические ссылки в директории enable, это делается автоматически, при помощи утилит Apache, но также допускается создавать такие ссылки вручную.
Создадим конфигурационный файл для нашего сайта и сразу откроем его на редактирование (если вы предпочитаете редактору nano редактор MC, то укажите в команде вместо nano mcedit):
nano /etc/apache2/sites-available/site.example.conf
И внесем в него следующие строки:
<VirtualHost *:80>
ServerName site.example
ServerAdmin webmaster@site.example
ServerAlias www.site.example
</VirtualHost>
Для нашей основной цели - получения сертификатов Let's Encrypt этого более чем достаточно.
Подключим сайт:
a2ensite site.example
Проверим конфигурацию и перезапустим веб-сервер:
apachectl -t
systemctl reload apache2
Для получения сертификатов нам понадобится специальная утилита Certbot, ее актуальные версии распространяются только через Snap и если у вас была установлена версия из репозитория, то ее следует удалить и заодно подчистить ненужные более зависимости:
apt remove certbot
apt autoremove
Затем установим поддержку Snap (в Ubuntu поддержка Snap установлена по умолчанию):
apt install snapd
После чего установим snap-версию Certbot:
snap install --classic certbot
И сделаем символическую ссылку на бинарный файл утилиты:
ln -s /snap/bin/certbot /usr/bin/certbot
Теперь можно приступить к получению сертификатов, мы будем использовать для этого специальный плагин для веб-сервера Apache, но не будем разрешать ему вносить изменения в конфигурационные файлы, ограничив режимом только получения сертификатов:
certbot certonly --apache
Утилита проверит конфигурационные файлы веб-сервера и покажет вам все обслуживаемые домены, вам следует выбрать и указать номера тех, для которых вы хотите получить сертификаты. Если у вас на веб-сервере обслуживается несколько сайтов, то можете запустить утилиту несколько раз, чтобы получить отдельные сертификаты для каждого сайта.
Если все прошло нормально и сертификаты получены, то перейдем к дальнейшей настройке веб-сервера для работы с шифрованием, прежде всего добавим файл конфигурации с общими для всего сервера настройками, которые будут применяться к любому HTTPS сайту:
nano /etc/apache2/conf-available/tls.conf
И внесем в него следующие строки:
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
SSLHonorCipherOrder off
SSLSessionTickets off
SSLUseStapling On
SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
Настройка TLS-защиты задача не простая, поэтому мы советуем использовать для получения адекватных настроек moz://a SSL Configuration Generator, также рекомендуем время от времени проверять сайт на наличие обновленных настроек.
Коротко пройдемся по указанным выше строкам. Первая отключает устаревшие протоколы шифрования, оставляя только TLS v1.2 и TLS v1.3, вторая определяет набор используемых шифров, шифры перечислены в порядке их предпочтения и клиент согласовывает с сервером самый стойкий из поддерживаемых шифров.
Опция SSLHonorCipherOrder off определяет, что приоритет в выборе шифра отдается клиенту, т.е. именно клиент выбирает из предложенных шифров тот, с которым он будет работать. Опция SSLSessionTickets off отключает сессионные билеты SSL, что нужно для работы совершенной прямой секретности.
Нижний блок включает OCSP Stapling, который ускоряет проверку браузером сертификата сайта и благоприятно сказывается на скорости работы сайта.
Сохраним данную конфигурацию и подключим ее:
a2enconf tls
Теперь вернемся к конфигурации сайта и продолжим ее настройку. Прежде всего настроим редиректы. Нам нужно направить весь незащищенный трафик HTTP на HTTPS-версию сайта, а также все запросы с www, на версию без www.
Сразу коснемся вопроса, а почему не продолжить использовать опцию ServerAlias, как мы это сделали выше, при получении сертификата? Да, можно, но в этом случае у нас будет как-бы два сайта, один с www, второй без, что негативно сказывается на его ранжировании поисковыми системами. Поэтому лучше иметь одну версию сайта, в нашем случае без www и перенаправлять на нее все запросы с www.
Ну и второй по популярности вопрос, а зачем вообще нужен www? По большому счету не нужен, это пережиток старины, но многие пользователи все еще могут набрать адрес сайта вместе с www, чтобы не терять таких пользователей мы будем обслуживать и этот поддомен.
Первую секцию в конфигурационном файле приводим к виду:
<VirtualHost *:80>
ServerName site.example
ServerAdmin webmaster@site.example
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</VirtualHost>
Она будет перенаправлять все запросы с HTTP на HTTPS версию сайта.
Ниже добавим вторую секцию:
<VirtualHost *:80>
ServerName www.site.example
ServerAdmin webmaster@site.example
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [L,R=301]
</VirtualHost>
Которая будет переадресовывать запросы с www на защищенную версию сайта без www, а за ней еще один блок, только уже для перенаправления www защищенной версии сайта на версию без www.
<VirtualHost *:443>
ServerName www.site.example
ServerAdmin webmaster@site.example
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [L,R=301]
</VirtualHost>
После чего добавим основную секцию, которая будет отвечать за работу нашего сайта:
<VirtualHost *:443>
ServerName site.example
ServerAdmin webmaster@site.example
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/site.example/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/site.example/privkey.pem
Protocols h2 http/1.1
Header always set Strict-Transport-Security "max-age=63072000"
DocumentRoot /var/www/site.example
CustomLog ${APACHE_LOG_DIR}/site.example.access.log combined
ErrorLog ${APACHE_LOG_DIR}/site.example.error.log
<Directory /var/www/site.example>
AllowOverride All
</Directory>
</VirtualHost>
Опция SSLEngine on включает поддержку шифрования, ниже идут пути к сертификатам, обратите внимание, что Let's Encrypt хранит их в /etc/letsencrypt/live в директориях с именем домена, если сертификат выпущен на несколько доменов, то используется указанное первым имя. Затем в опции Protocols перечисляются поддерживаемые протоколы в порядке убывания приоритета, в нашем случае приоритетным является HTTP 2.
Заголовок Strict-Transport-Security препятствует атакам на понижение безопасности, если браузер успешно соединился с таким сайтом через HTTPS, то он в течении времени указанного в заголовке (1 год) не будет даже пытаться установить незащищенное соединение, даже если HTTP-версия сайта доступна. Рекомендуется закомментировать данную опцию на время настройки и отладки сайта.
DocumentRoot определяет корневую директорию сайта.
Ниже указаны пути к логам, правилом хорошего тона является включать имя сайта в имя файла лога.
Секция Directory с указанием директории сайта позволяет задать опции применяемые непосредственно к каталогу, сегодня достаточно одной - AllowOverride All, которая разрешает использование любых конфигурационных директив в файлах .htaccess.
Сохраняем файл конфигурации, затем подключим нужные модули:
a2enmod headers rewrite ssl
Затем создадим директорию сайта
mkdir /var/www/site.example
В ней создадим индексный файл и откроем его на редактирование:
nano /var/www/site.example
И внесем в него следующий текст:
<body><h1>OK!</h1></body>
Сделаем владельцем файлов и директории веб-сервер:
chown -R www-data:www-data /var/www/site.example
Теперь проверим конфигурацию на ошибки и перезапустим веб-сервер:
apachectl -t
systemctl reload apache2
Если все сделано правильно, то теперь, при обращении к сайту вы сразу попадете на его защищенную версию с действительным сертификатом Let's Encrypt.
Как можно увидеть, для подключения применяется самый современный протокол TLS 1.3, шифр AES_128_GCM и совершенная прямая секретность на эллиптической кривой X25519.
Настройка сайта по умолчанию для блокирования несуществующих доменов
Использование TLS-шифрования имеет одну особенность: если мы обратимся к веб-серверу по IP-адресу или по доменному имени, которое указывает на веб-сервер, но не обслуживается им (или не имеет HTTPS-версии), то будет показан сайт, сертификат которого указан первым в конфигурации веб-сервера.
Такое поведение может быть нежелательным, так как позволяет раскрыть обслуживаемый сайт просто обратившись по имени или ввести пользователя в заблуждение. Поэтому настроим сайт по умолчанию, который будет блокировать все запросы к несуществующим доменам как в HTTP, так и в HTTPS версиях.
Для HTTPS нам понадобится сертификат, можно использовать любой существующий, но это позволит раскрыть реальный обслуживаемый сайт, поэтому выпустим для этих целей самоподписанный сроком на 10 лет:
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/apache2/apache.key -out /etc/apache2/apache.crt
Затем заменим содержимое файла /etc/apache2/sites-available/000-default.conf следующим содержимым:
<VirtualHost *:80>
ServerName _default_
RewriteEngine On
RewriteRule ^ - [F]
</VirtualHost>
<VirtualHost *:443>
ServerName _default_
SSLEngine on
SSLCertificateFile /etc/apache2/apache.crt
SSLCertificateKeyFile /etc/apache2/apache.key
RewriteEngine On
RewriteRule ^ - [F]
</VirtualHost>
Опция ServerName _default_ используется для перехвата любого запроса, который не обслуживается ни одним существующим виртуальным хостом, а RewriteRule ^ - [F] возвращает код состояния HTTP 403 (Forbidden).
Снова проверяем конфигурацию и перезапускаем службу веб-сервера:
apachectl -t
systemctl reload apache2
Если попробовать теперь обратиться к серверу по IP-адресу, то увидим:
Следует отметить, что данная настройка не является обязательной и ее следует применять по необходимости.
Установка и настройка PHP
Для работы с динамическим содержимым нам потребуется поддержка PHP, скриптового языка, на котором написано большинство современных систем управления контентом (CMS), также называемых движками сайтов. Apache использует PHP в режиме модуля веб-сервера и никаких особых настроек нам не потребуется, достаточно просто установить PHP командой:
apt install php
Но не будем спешить и сразу изменим некоторые настройки, откроем /etc/php/x.x/apache2/php.ini, где x.x текущая установленная версия PHP, в Debian 12 это 8.2, в Ubuntu 22.04 - 8.1, и приведем к следующему виду следующие опции:
post_max_size = 32M
upload_max_filesize = 30M
Первая из них определяет максимальный размер передаваемого на сервер пакета данных, а вторая - максимальный размер загружаемого файла.
После чего перезапустим веб-сервер:
systemctl reload apache2
Для проверки создадим в корневой директории веб-сервера файл:
nano /var/www/site.examlpe/info.php
И внесем в него следующий текст:
<?php
phpinfo();
?>
Если теперь в адресной строке браузера набрать site.example/info.php то увидим стандартную страницу с информацией о PHP, его настройках и установленных модулях.
Для расширения возможностей PHP используются модули, скажем, для работы с графикой может потребоваться модуль GD или ImageMagick, для модулей используют следующий шаблон имен пакетов: php-<имя модуля>, например:
apt install php-gd php-imagick
Необходимые модули и их имена вы можете узнать из документации к используемому веб-приложению.
Установка MySQL / MariaDB
Сервер баз данных третий неотъемлемый компонент классического веб-сервера и один из первых по важности, так как именно в базе данных хранится основная пользовательская информация сайта. В современных версиях Debian и Ubuntu используются разные варианты СУБД: MariaDB и MySQL, которые являются совместимыми и принципиально разницы какую из них использовать нет, тем более что в репозиториях содержатся последние LTS-версии обоих СУБД. Поэтому будем устанавливать версии из репозитория, что упростит дальнейшую поддержку и обслуживание сервера.
Для Debian это будет команда:
apt install mariadb-server
А для Ubuntu:
apt install mysql-server
В дальнейшем в обоих системах для управления можно использовать один и тот же набор команд:
systemctl start | stop | restart | status mysql
Вне зависимости от того, какую именно версию СУБД вы используете.
После установки сервера баз данных следует выполнить скрипт, который выполнит рекомендуемые настройки безопасности установленного экземпляра сервера:
mysql_secure_installation
В нем положительно отвечаем на все вопросы, кроме смены пароля суперпользователя СУБД root, в текущем режиме установки учетная запись root не имеет пароля и поддерживает вход исключительно через UNIX-сокет, поэтому не следует ее включать.
Затем установим модуль PHP для работы с MySQL / MariaDB:
apt install php-mysql
Теперь выполним некоторые настройки самого сервера СУБД, сначала поднимем собственные права до суперпользователя, в Debian выполните команду:
su -
В Ubuntu:
sudo -s
После чего перейдем в командную строку MySQL в режиме суперпользователя:
mysql -u root
В первую очередь создадим пользователей СУБД и разрешим им вход по паролю:
CREATE USER 'andrey'@'localhost' IDENTIFIED BY 'Pa$$word_1';
После чего отберем у него права на чужие базы:
GRANT USAGE ON *.* TO 'andrey'@'localhost';
А затем выдадим полные права на все базы с шаблоном имени andrey_<имя базы>, что позволит автоматически устанавливать права просто создав базу с нужным именем.
GRANT ALL PRIVILEGES ON `andrey\_%`.* TO 'andrey'@'localhost';
Обратите внимание, что шаблон оборачивается символами грависа (`), который находится на клавише с русской буквой Ё.
Перезагрузим привилегии:
FLUSH PRIVILEGES;
И выйдем из консоли MySQL:
QUIT;
На этом настройка сервера СУБД закончена.
Установка phpMyAdmin
phpMyAdmin - удобное веб-приложение для управления СУБД MySQL / MariaDB и, по сути, стандарт де-факто среди таких приложений, его использование для повседневной работы с СУБД повышает общее удобство, по сравнению с консолью и поэтому мы не видим причин отказывать от его использования.
Для его установки используйте команду:
apt install phpmyadmin
Приложение начинает работать сразу после установки и для его использования достаточно набрать в адресной строке браузера site.example/phpmyadmin:
Однако держать приложение в открытом доступе явно не стоит, так как phpMyAdmin представляет также лакомую цель для злоумышленников, поэтому закроем к нему доступ дополнительной парольной защитой. Прежде всего создадим пользователя и зададим ему пароль, если вы делаете это первый раз, то используйте в команде ключ -c, который создаст файл паролей или перезапишет существующий:
htpasswd -c /etc/apache2/passwd ivanov
Для следующего пользователя следует использовать просто:
htpasswd /etc/apache2/passwd petrov
Теперь откроем конфигурационный файл phpMyAdmin для Apache /etc/apache2/conf-available/phpmyadmin.conf и в секцию <Directory /usr/share/phpmyadmin> добавим следующий блок:
AuthType Basic
AuthName "Restricted Access"
AuthUserFile /etc/apache2/passwd
Require valid-user
Который разрешает доступ к указанной директории любому пользователю, прошедшему проверку. Если нужно ограничить доступ конкретным пользователям, то измените последнюю строку на:
Require user ivanov
Если пользователей несколько, то указываем их через пробел.
Отдельного упоминания следует использование Basic-аутентификации, ее особенностью является передача учетных данных в открытом виде, но в данном случае это не имеет значения, так как Apache у нас настроен исключительно на работу по HTTPS, где все передаваемые между клиентом и сервером данные защищены надежным шифрованием.
На этом настройка веб-сервера на базе Apache + PHP + MySQL с сертификатами Let's Encrypt закончена.
Онлайн-курс по устройству компьютерных сетей
На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.
Последние комментарии