Настройка web сервера apache в CentOS 8

Сегодня займемся поднятием одной из наиболее востребованных ролей любого linux сервера, которые занимают в этом функциональном сегменте лидирующую роль. Настройка web сервера CentOS 8 на базе связки популярного http сервера apache, интерпретатора php и сервера баз данных mysql, или коротко — установка lamp. Данная связка является самой популярной конфигурацией на сегодняшний день среди веб хостинга. Хотя последнее время ей на пятки наступает та же компания, но на базе nginx, возможно уже и опередила, точных данных у меня нет на этот счет.

Углубленный онлайн-курс по MikroTik

Научиться настраивать MikroTik с нуля или систематизировать уже имеющиеся знания можно на углубленном онлайн-курcе по администрированию MikroTik. Автор курcа – сертифицированный тренер MikroTik Дмитрий Скоромнов. Более 40 лабораторных работ по которым дается обратная связь. В три раза больше информации, чем в MTCNA.

Если вам нужен высокопроизводительный web сервер на базе последних версий nginx и php-fpm, то читайте отдельную статью по этой теме - установка и настройка nginx и php-fpm7 на centos.

Цели статьи

  1. Описать общий принцип настройки web сервера на базе apache.
  2. Показать, как установить актуальные версии apache, php и mariadb.
  3. Привести примеры своих конфигов для перечисленных сервисов.
  4. Настроить бесплатные ssl сертификаты let's encrypt для сайтов.
  5. Показать, как настроить selinux для web сервера apache (httpd).
  6. Записать и показать видео настройки веб сервера apache.

Данная статья является частью единого цикла статьей про сервер Centos.

Введение

В этой статье я расскажу, как настроить web сервер на базе популярного стека технологий - apache и php с модулем prefork. В связи с выходом нового релиза Centos 8, многие статьи на эту тему стали не актуальны, так как версии софта в базовых репозиториях обновились и тот же php нет смысла ставить из стороннего репозитория.

Работать будем на сервере под управлением CentOS 8. Если у вас его еще нет, то читайте мои статьи на тему установки и базовой настройки centos. Не забудьте уделить внимание теме настройки iptables. В данной статье я ее не буду касаться, хотя тема важная для web сервера.

В своей тестовой среде я буду использовать следующие сущности.

z.serveradmin.ru имя тестового виртуального хоста и сайта
/web/sites директория для размещения виртуальных хостов
10.20.1.23 локальный ip адрес сервера
pma.serveradmin.ru имя виртуального хоста для phpmyadmin

Если вам не хочется настраивать SELinux, то просто отключите его. Если же вы планируете включить и использовать после настройки, то переведите его в режим Permissive. В этом режиме он будет отключен, но все ограничения будут отражаться в лог файле audit.log. Это позволит нам в конце статьи сформировать модуль selinux для httpd и php и включить их.

# setenforce 0

Web сервер на CentOS 8

Итак, наш веб сервер centos будет состоять из трех основных компонентов - http сервера apache, интерпретатора языка программирования php и сервера баз данных mysql. Познакомимся немного с каждым из них:

  1. Apache - http сервер или просто веб сервер апач. Является кросплатформенным ПО, поддерживающим практически все популярные операционные системы, в том числе и Windows. Ценится прежде всего за свою надежность и гибкость конфигурации, которую можно существенно расширить благодаря подключаемым модулям, которых существует великое множество. Из недостатков отмечают большую требовательность к ресурсам, по сравнению с другими серверами. Держать такую же нагрузку, как, к примеру, nginx, apache не сможет при схожих параметрах железа.
  2. PHP - язык программирования общего назначения, который чаще всего применяется в веб разработке. На сегодняшний день это самый популярный язык в этой области применения. Поддерживается практически всеми хостинг-провайдерами.
  3. Mysql - система управления базами данных. Завоевала свою популярность в среде малых и средних приложений, которых очень много в вебе. Так что, как и php, на сегодняшний день является самой популярной бд, использующейся на веб сайтах. Поддерживается большинством хостингов. В CentOS вместо mysql устанавливается mariadb - ответвление mysql. Они полностью совместимы, возможен в любой момент переход с одной субд на другую и обратно. Я встречал информацию, что mariadb пошустрее работает mysql и люди потихоньку перебираются на нее. На практике мне не довелось это наблюдать, так как никогда не работал с нагруженными базами данных. А в обычных условиях разница не заметна.

Подопытным сервером будет выступать виртуальная машина от ihor, характеристики следующие:

Процессор 2 ядра
Память 3 Gb
Диск 30 Gb SSD

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

Настройка apache в CentOS 8

В CentOS служба apache называется httpd. Когда я только знакомился с этим дистрибутивом, мне было непривычно. В Freebsd и Debian, с которыми я до этого работал служба веб сервера называлась apache, хотя где-то я замечал, кажется во фрюхе, что файл конфигурации имеет имя httpd.conf. До сих пор я не знаю, почему распространились оба эти названия. Был бы рад, если бы со мной кто-то поделился информацией на этот счет в комментариях.

Теперь приступим к установке apache. В CentOS 8 это делается очень просто:

# dnf install httpd

Добавляем apache в автозагрузку:

# systemctl enable httpd

Запускаем apache в CentOS 8:

# systemctl start httpd

Проверяем, запустился ли сервер:

# netstat -tulnp | grep httpd
tcp6       0      0 :::80                   :::*                    LISTEN      21586/httpd

Все в порядке, повис на 80-м порту, как и положено. Уже сейчас можно зайти по адресу http://10.20.1.23 и увидеть картинку:

Настройка web сервера apache

Если ничего не видите, скорее всего у вас не настроен firewall. Если не занимались его настройкой, то по-умолчанию в centos установлен firewalld. На нем открыть порты для web сервера можно следующими командами.

# firewall-cmd --permanent --zone=public --add-service=http
# firewall-cmd --permanent --zone=public --add-service=https
# firewall-cmd --reload

Проверить, открылись ли порты можно командой.

# firewall-cmd --list-all

Настройка firewalld

Вместо ожидаемой картинки с каким-то приветствием, мы видим просто ошибку. Я не знаю, почему в Centos 8 в стандартном пакете httpd из базового репозитория не положили в директорию web сервера по-умолчанию /var/www/html хоть какую-нибудь страничку. Там пусто, поэтому мы и видим ошибку. Давайте тогда сами что-то туда положим, чтобы просто проверить работу apache. Создаем простую страничку index.html.

# echo "Hello, Centos 8 and apache." >> /var/www/html/index.html

Проверяем страницу.

Проверка работы apache

Все в порядке, веб сервер работает. Теперь займемся настройкой apache. Я предпочитаю следующую структуру веб хостинга:

/web/sites раздел для размещения сайтов
/web/z.serveradmin.ru/www директория для содержимого сайта
/web/z.serveradmin.ru/log директория для логов сайта

Создаем для нее директории.

# mkdir -p /web/sites/z.serveradmin.ru/{www,log}
# chown -R apache. /web/sites/

Дальше редактируем файл конфигурации apache — httpd.conf по адресу /etc/httpd/conf. Первым делом проверим, раскомментирована ли строчка в самом конце:

IncludeOptional conf.d/*.conf

Если нет, раскомментируем и идем в каталог /etc/httpd/conf.d. Создаем там файл z.serveradmin.ru.conf:

# mcedit /etc/httpd/conf.d/z.serveradmin.ru.conf
<VirtualHost *:80>

    ServerName z.serveradmin.ru
    ServerAlias www.z.serveradmin.ru
    DocumentRoot /web/sites/z.serveradmin.ru/www

    ErrorLog /web/sites/z.serveradmin.ru/log/error.log
    CustomLog /web/sites/z.serveradmin.ru/log/access.log common

    <Directory /web/sites/z.serveradmin.ru/www>
        Options FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

</VirtualHost>

Перезапуск apache в centos

Проверим созданную конфигурацию и выполним перезапуск apache.

# apachectl -t
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::95:c6f3:e49f:7204. Set the 'ServerName' directive globally to suppress this message
Syntax OK

В данном случае ошибок нет, показано предупреждение. Теперь делаем restart apache:

# systemctl restart httpd

Если возникли какие-то ошибки — смотрим лог apache /var/log/httpd/error_log. Если все в порядке, то проверим, нормально ли настроен наш виртуальный хост. Для этого создадим в папке /web/sites/z.serveradmin.ru/www файл index.html следующего содержания:

# mcedit /web/sites/z.serveradmin.ru/www/index.html
<h1>Апач работает как надо, а надо хорошо!</h1>
# chown apache. /web/sites/z.serveradmin.ru/www/index.html

Дальше на своем компьютере правим файл hosts, чтобы обратиться к нашему виртуальному хосту. Добавляем туда строчку:

10.20.1.23 z.serveradmin.ru

где 10.20.1.23 ip адрес нашего веб сервера. Это нужно сделать только в том случае, если настраиваете web сервер где-то в локальной сети без реально существующего доменного имени.

Теперь в браузере набираем адрес http://z.serveradmin.ru. Если видим картинку:

Настройка виртуального хоста

значит все правильно настроили. Если какие-то ошибки, то идем смотреть логи. Причем в данном случае не общий лог httpd, а лог ошибок конкретного виртуального хоста по адресу /web/z.serveradmin.ru/log/error.log.

Установка php в CentOS 8

Установка php в Centos 8 сильно упростилась по сравнению с предыдущей версией, потому что в базовом репозитории хранится актуальная версия php 7.2, которой можно пользоваться. Пока нет необходимости подключать сторонние репозитории, так как версия 7.2 вполне свежа и актуальна. Если у вас нет необходимости использовать что-то новее, то можно остановиться на этой версии.

Устанавливаем php в CentOS 8, а так же некоторые популярные модули, которые могут пригодиться для того же phpmyadmin.

# dnf install php php-cli php-mysqlnd php-json php-gd php-ldap php-odbc php-pdo php-opcache php-pear php-xml php-xmlrpc php-mbstring php-snmp php-soap php-zip

Выполним перезапуск apache:

# systemctl restart httpd

Создадим файл в директории виртуального хоста и проверим работу php:

# mcedit /web/sites/z.serveradmin.ru/www/index.php
<?php phpinfo(); ?>
# chown apache. /web/sites/z.serveradmin.ru/www/index.php

Заходим по адресу http://z.serveradmin.ru/index.php

Проверка работы php

Вы должны увидеть вывод информации о php. Если что-то не так, возникли какие-то ошибки, смотрите лог ошибок виртуального хоста, php ошибки будут тоже там. Если вам необходима более свежая версия php, то читайте статью по обновлению php 7.2 до 7.4.

Где лежит php.ini

После установки часто возникает вопрос, а где хранятся настройки php? Традиционно они находятся в едином файле настроек. В CentOS php.ini лежит в /etc, прямо в корне. Там можно редактировать глобальные настройки для всех виртуальных хостов. Персональные настройки каждого сайта можно сделать отдельно в файле конфигурации виртуального хоста, который мы сделали раньше. Давайте добавим туда несколько полезных настроек:

# mcedit /etc/httpd/conf.d/z.serveradmin.ru.conf

Добавляем в самый конец, перед </VirtualHost>

php_admin_value date.timezone 'Europe/Moscow'
php_admin_value max_execution_time 60
php_admin_value upload_max_filesize 30M

Для применения настроек нужно сделать restart apache. Если у вас полностью дефолтная установка, как у меня, то скорее всего вы увидите ошибку.

Invalid command 'php_admin_value', perhaps misspelled or defined by a module not included in the server configuration

Суть  ошибки в том, что у нас не загружен модуль mod_php. Проверим, где он подключается. Это файл /etc/httpd/conf.modules.d/15-php.conf.

<IfModule !mod_php5.c>
  <IfModule prefork.c>
    LoadModule php7_module modules/libphp7.so
  </IfModule>
</IfModule>

Тут стоит проверка на запуск модуля. Он загружается только, если у нас загружен модуль prefork. Давайте попробуем его загрузить принудительно. Для этого комментируем все строки, кроме основной.

LoadModule php7_module modules/libphp7.so

Проверяем конфигурацию apache.

# apachectl -t

Apache is running a threaded MPM, but your PHP Module is not compiled to be threadsafe.

Получили новую ошибку. Смысл в том, что изначально apache сконфигурирован на работу модуля mpm_event, он подключается в конфиге /etc/httpd/conf.modules.d/00-mpm.conf.

LoadModule mpm_event_module modules/mod_mpm_event.so

Стандартный модуль mod_php скомпилирован с поддержкой модуля mpm_prefork. С другими он работать не будет. Таким образом, чтобы у нас нормально заработал php, нам надо вместо модуля mpm_event подключить модуль mpm_prefork. Для этого в конфиге 00-mpm.conf закомментируем подключение mpm_event_module и раскомментируем prefork.

LoadModule mpm_prefork_module modules/mod_mpm_prefork.so

После этого проверяйте конфигурацию и перезапускайте apache. Все должно заработать. Теперь в выводе phpinfo можно увидеть изменение настроек.

Настройка php

Я подробно разобрал эти ошибки, чтобы у вас было понимание, как все устроено и куда смотреть в случае проблем. Более подробно о работе и выборе mpm модулей читайте в официальной документации apache - http://httpd.apache.org/docs/2.4/mpm.html.

Установка MySQL в CentOS 8

Как я уже писал ранее, сейчас все большее распространение получает форк mysql — mariadb. Она имеет полную совместимость с mysql, так что можно смело пользоваться. Я предпочитаю использовать именно ее.

Устанавливаем mariadb на CentOS 8:

# dnf install mariadb mariadb-server

Запускаем mariadb и добавляем в автозагрузку.

# systemctl start mariadb
# systemctl enable mariadb

Запускаем скрипт начальной конфигурации mysql и задаем пароль для root. Все остальное можно оставить по-умолчанию.

# /usr/bin/mysql_secure_installation

Не буду приводить весь вывод работы этого скрипта, там все достаточно просто и понятно. Сначала задаем пароль для root (текущий пароль после установки пустой), потом удаляем анонимных пользователей, отключаем возможность подключаться root удаленно, удаляем тестового пользователя и базу.

Файлы настроек mysql/mariadb в Centos 8 лежат в директории /etc/my.cnf.d. Для обычной работы достаточно настроек по-умолчанию. Но если вы решите изменить их, не забудьте перезапустить службу баз данных.

Перезапуск mariadb/mysql в CentOS 8:

# systemctl restart mariadb

На этом все. Базовый функционал web сервера на CentOS 8 настроен. Дальше настроим популярную панель управления mysql сервером - phpmyadmin.

Установка phpmyadmin

Для того, чтобы установить phpmyadmin на наш web сервер, достаточно просто распаковать в директорию с виртуальным хостом исходники панели. Давайте подготовим виртуальный хост. Создаем структуру папок.

# mkdir -p /web/sites/pma.serveradmin.ru/{www,log}

И готовим конфиг apache по аналогии с уже созданным доменом. Создаем файл pma.serveradmin.ru.conf.

# mcedit pma.serveradmin.ru.conf
<VirtualHost *:80>

    ServerName pma.serveradmin.ru
    DocumentRoot /web/sites/pma.serveradmin.ru/www

    ErrorLog /web/sites/pma.serveradmin.ru/log/error.log
    CustomLog /web/sites/pma.serveradmin.ru/log/access.log common

    <Directory /web/sites/pma.serveradmin.ru/www>
        Options FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    php_admin_value date.timezone 'Europe/Moscow' 
    php_admin_value max_execution_time 360
    php_admin_value upload_max_filesize 100M

</VirtualHost>

После добавления конфига, не забудьте перезапустить apache.

# apachectl restart

Идем на сайт https://www.phpmyadmin.net и копируем ссылку на последнюю версию панели. Затем загружаем ее через консоль.

# cd ~
# wget https://files.phpmyadmin.net/phpMyAdmin/4.9.1/phpMyAdmin-4.9.1-all-languages.zip

Архив упакован в zip. Если у вас нет на сервере пакета unzip, установите его.

# dnf install unzip

Распаковываем исходники в директорию виртуального хоста.

# unzip phpMyAdmin-4.9.1-all-languages.zip
# cp -R phpMyAdmin-4.9.1-all-languages/* /web/sites/pma.serveradmin.ru/www
# chown -R apache. /web/sites/pma.serveradmin.ru/www

Можно заходить и проверять работу phpmyadmin, пройдя по адресу pma.serveradmin.ru. Ее установка закончена.

Установка phpmyadmin

Более подробно вопрос установки и настройки phpmyadmin я рассматривал отдельно. Можете зайти в панель и создать базу mysql для тестового сайта, например, wordpress. Затем через консоль загрузить исходники cms и распаковать их.

# cd ~
# wget https://ru.wordpress.org/latest-ru_RU.tar.gz
# tar xzvf latest-ru_RU.tar.gz
# cp -R wordpress/* /web/sites/z.serveradmin.ru/www
# chown -R apache. /web/sites/z.serveradmin.ru/www

После этого открывайте в браузере страницу z.serveradmin.ru и увидите приветствие установщика wordpress.

Установка wordpress на apache

Настройка ssl сертификата Lets Encrypt в apache

Теперь настроим работу web сервера apache с ssl сертификатом. Хотя если быть точным, то tls сертификатом. Устанавливаем пакет certbot для получения бесплатного ssl сертификата от let’s encrypt. Для этого нам сначала надо подключить репозиторий epel.

# dnf install epel-release
# dnf install certbot

Установка certbot в centos 8

После установки пакетов certbot, если его запустить, напишет ошибку, что не может сам настроить apache.

Конфигурация certbot

Настроим все сами. Для начала создадим самоподписанный дефолтный сертификат, чтобы apache не ругался на отсутствие файла и смог запуститься.

# openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/pki/tls/private/localhost.key -out /etc/ssl/certs/localhost.crt

Все параметры оставляйте дефолтные, не принципиально. Мы этот сертификат использовать не будет. Перезапустите apache.

# apachectl restart

Теперь выпустим сертификат для нашего домена. Имейте ввиду, чтобы получить сертификат у вас должно быть действующее доменное имя, ссылающееся на web сервер, который настраиваете. Let's Encrypt будет по доменному имени обращаться к серверу, на котором настраиваете сертификат, чтобы проверить домен. В тестовой лаборатории с вымышленным доменным именем получить настоящий ssl сертификат не получится.

# certbot certonly

Настройка ssl сертификатов let's encrypt на apache

В качестве способа аутентификации выбирайте

1: Apache Web Server plugin (apache)

Дальше заполняйте в соответствии с вашими названиями. После получения сертификата, укажем его в конфигурации виртуального хоста. В моем случае в файле z.serveradmin.ru.conf. Добавляем туда параметры ssl.

<VirtualHost *:80 *:443>

    ServerName z.serveradmin.ru
    ServerAlias www.z.serveradmin.ru
    DocumentRoot /web/sites/z.serveradmin.ru/www

    ErrorLog /web/sites/z.serveradmin.ru/log/error.log
    CustomLog /web/sites/z.serveradmin.ru/log/access.log common

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/z.serveradmin.ru/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/z.serveradmin.ru/privkey.pem

    <Directory /web/sites/z.serveradmin.ru/www>
        Options FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    php_admin_value date.timezone 'Europe/Moscow'
    php_admin_value max_execution_time 60
    php_admin_value upload_max_filesize 30M

</VirtualHost>

Перезапускайте apache и проверяйте работу сайта по https, зайдя по соответствующему протоколу.

Настройка ssl

По аналогии делаете с остальными виртуальными хостами, для которых используете бесплатные сертификаты let’s encrypt. Осталось дело за малым — настроить автоматический выпуск новых ssl сертификатов, взамен просроченным. Для этого добавляем в /etc/crontab следующую строку:

# Cert Renewal
30 4 * * * root /usr/bin/certbot renew --post-hook "/usr/sbin/apachectl restart" >> /var/log/le-renew.log

Переадресация с http на https в apache

В настроенном ранее примере https отлично работает, но неудобно, что нет автоматической переадресации с http на https. Чтобы использовать безопасную версию сайта, необходимо вручную в браузере набирать https. Хотя все современные браузеры уже сами умеют проверять версии сайта и если есть защищенная, то они автоматически сами ее выбирают.

Тем не менее, лучше все же добавить редирект с http на https. Его можно сделать двумя различными способами:

  1. Через файл .htaccess
  2. С помощью настройки виртуального хоста.

Мне нравится больше второй вариант, поэтому приводим конфиг виртуального хоста к следующему виду.

<VirtualHost *:80>

    ServerName z.serveradmin.ru
    ServerAlias www.z.serveradmin.ru
    Redirect permanent / https://z.serveradmin.ru

</VirtualHost>

<VirtualHost *:443>

    ServerName z.serveradmin.ru
    ServerAlias www.z.serveradmin.ru
    DocumentRoot /web/sites/z.serveradmin.ru/www

    ErrorLog /web/sites/z.serveradmin.ru/log/error.log
    CustomLog /web/sites/z.serveradmin.ru/log/access.log common

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/z.serveradmin.ru/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/z.serveradmin.ru/privkey.pem

    <Directory /web/sites/z.serveradmin.ru/www>
        Options FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    php_admin_value date.timezone 'Europe/Moscow'
    php_admin_value max_execution_time 60
    php_admin_value upload_max_filesize 30M

</VirtualHost>

Перечитывайте конфиг httpd и проверяйте. Должно работать автоматическое перенаправление на https версию.

Ротация логов веб сервера apache

Последний штрих в настройке web сервера — ротация логов виртуальных хостов. Если этого не сделать, то через какое-то, обычно продолжительное, время возникает проблема в связи с огромным размером лог файла.

У нас уже будет файл конфигурации logrotate для httpd, который был создан во время установки — /etc/logrotate.d/httpd. Приведем его к следующему виду:

/var/log/httpd/*log {
    missingok
    notifempty
    sharedscripts
    delaycompress
    postrotate
        /bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true
    endscript
}

/web/sites/pma.serveradmin.ru/log/*log {
    size=10M
    rotate 10
    missingok
    notifempty
    compress
    sharedscripts
    postrotate
        /bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true
    endscript
}

/web/sites/z.serveradmin.ru/log/*log {
    size=10M
    rotate 10
    missingok
    notifempty
    compress
    sharedscripts
    postrotate
        /bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true
    endscript
}

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

Настройка SELinux для web сервера apache

Раздел для тех, кто хочет настроить SELinux на своем web сервере. Сначала ставим пакет policycoreutils-python-utils если он еще не установлен. Он нам нужен для утилиты semanage.

# dnf install policycoreutils-python-utils

Теперь автоматически сформируем модуль для selinux на основе событий аудита, которые накопились, пока мы настраивали сайт. Посмотреть их можно командой.

# grep httpd /var/log/audit/audit.log | audit2why

Создаем модуль selinux.

# grep httpd /var/log/audit/audit.log | audit2allow -M my-httpd

Загружаем его.

# semodule -i my-httpd.pp

То же самое делаем для php.

# grep php /var/log/audit/audit.log | audit2allow -M my-php
# semodule -i my-php.pp

Добавим нашу директорию /web/sites в соответствующие таблицы selinux для контента и логов.

# semanage fcontext -a -t httpd_sys_content_t "/web/sites(/.*)?"
# semanage fcontext -a -t httpd_log_t "/web/sites(/.*)?/log(/.*)?"

И отдельно добавим каталог, куда web сервер сможет писать данные. Я покажу на примере правила для сайтов wordpress, где web сервер должен уметь писать в директорию wp-content для загрузки медиафайлов, установки тем и плагинов, а так же изменять файл wp-config.php.

# semanage fcontext -a -t httpd_sys_rw_content_t "/web/sites/\*/www/wp-content(/.\*)?"
# semanage fcontext -a -t httpd_sys_rw_content_t "/web/sites/\*/www/wp-config.php"

Обновляем атрибуты файлов новым контекстом SELinux.

# restorecon -Rv /web/sites

В завершении настройки selinux для apache, добавим еще один параметр, без которого httpd не сможет писать файлы в указанные каталоги.

# setsebool -P httpd_unified 1

Теперь активируем защиту selinux и проверяем, что она работает.

# setenforce 1
# getenforce
Enforcing

Режим работы Enforcing означает, что selinux работает. Убедиться, что модули загружены, можно командой.

# semodule -l | grep my-

В целом, по selinux все. Мы просто разрешили все, что веб сервер просил. По идее, надо вдумчиво во всех правилах разбираться и разрешать только то, что считаешь нужным. Я честно скажу, что selinux знаю не очень хорошо. Дальше загрузки готовых модулей и автоматического создания модулей с помощью audit2allow я не двигался. Руками модули никогда не писал. Если есть какой-то более осмысленный и правильный способ настройки selinux на кастомной конфигурации веб сервера, буду рад полезной информации.

Хорошая практическая статья по ручной настройке selinux для web сервера — https://habr.com/ru/post/322904/. Там же есть ссылки на другие статьи автора на тему selinux. Написано содержательно и наглядно, рекомендую для тех, кто будет знакомиться с технологией.

Видео

В завершении полное видео настройки web сервера apache на основе приведенной статьи. Если у кого-то что-то не получается, посмотрите, как это сделал я.

Заключение

Не понравилась статья и хочешь научить меня администрировать? Пожалуйста, я люблю учиться. Комментарии в твоем распоряжении. Расскажи, как сделать правильно!

На этом по настройке apache все. Я рассмотрел все основные моменты, которые необходимы для установки и настройки web сервера на основе apache и php, который обычно называют LAMP. При этом рассказал о некоторых вещах, которые повышают удобство и гибкость эксплуатации сервера.

Тема настройки веб сервера обширна. Рассмотреть все варианты в одной статье невозможно, так как функционал будет разниться, в зависимости от назначения сервера. Тем не менее приведу еще несколько ссылок на материалы, которые имеют отношение к настройке web сервера:

Если еще что-то полезное вспомню, добавлю ссылки. Пока вроде все. Статья получилось большой и насыщенной. Было не просто все собрать воедино, проверить, связать между собой и оформить в последовательное повествование. Мог где-то ошибиться. Жду комментариев и отзывов. Написал все по своему опыту, как я обычно настраиваю веб сервера. Предполагаю что-то можно сделать более удобно и правильно. Буду рад научиться.

Напоминаю, что данная статья является частью единого цикла статьей про сервер Centos.

Онлайн-курс по устройству компьютерных сетей.

На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.

Помогла статья? Подписывайся на telegram канал автора

Анонсы всех статей, плюс много другой полезной и интересной информации, которая не попадает на сайт.

Автор Zerox

Владимир, системный администратор, автор сайта. Люблю настраивать сервера, изучать что-то новое, делиться знаниями, писать интересные и полезные статьи. Открыт к диалогу и сотрудничеству. Если вам интересно узнать обо мне побольше, то можете послушать интервью. Запись на моем канале - https://t.me/srv_admin/425 или на сайте в контактах.

65 комментариев

  1. Эх, еще бы для постфикса показали как подкинуть данный сертификат и полный комплект бы был!

    • В смысле как подкинуть? Берите и пользуйтесь полученным сертификатом. Не совсем понял вопрос.

  2. Спасибо, большое! Заработали сайты на разных директориях. А я создал их в папке sites-available и сто раз перезапустил апаче и ни каких результатов. И только с помощью вашей статьи сделал

  3. Александр

    Спасибо за статью!

    Как установить модули:
    php-imap php-imagick php-tidy php-memcached

    Выдает ошибку:

    No match for argument: php-imap
    No match for argument: php-imagick
    No match for argument: php-tidy
    No match for argument: php-memcached

    • Centos 8 больше не поддерживается. Репы закрыли. Сейчас уже нет смысла использовать Centos 8. Используйте другую систему.

  4. Спасибо за ваши труды!
    Подскажите такой момент...

    В качестве способа аутентификации выбирайте

    1: Apache Web Server plugin (apache)

    Есть инструкции если при выборе такого нет пункта? После установки cerbot есть только два пункта последующих пункта

    •  разобрался. не хватало пакета python3-certbot-apache.
      dnf install python3-certbot-apache

      • В принципе, все эти плагины можно не использовать. Лично я всегда настраиваю подтверждение доменов через webroot. Это универсальный способ, который одинаково работает на всех системах и веб серверах.

  5. Поправь с "dnf install certbot"
    на "dnf install certbot python3-certbot-apache mod_ssl"
    А то я столкнулся что certbot установился без модуля для apache. И в самом начале после ввода "certbot certonly" не было выбора для Апача только два варианта вместо трёх.

  6. Добрый день. Теперь при запуске certbot-auto выдается сообщение:
    Skipping bootstrap because certbot-auto is deprecated on this system.
    WARNING: couldn't find Python 3.6+ to check for updates.
    Your system is not supported by certbot-auto anymore.
    Certbot cannot be installed.
    Please visit https://certbot.eff.org/ to check for other alternatives.
    На сайте несколько другая инструкия по установке. Добавите к себе в статью?

  7. Чтобы запускать выпуск сертификата каждые 3 месяца, как и положено, нужно в файле /etc/crontab нужно сделать так:
    # Cert Renewal
    0 0 1 */3 * root /usr/local/bin/certbot-auto renew --post-hook "/usr/sbin/apachectl restart" >> /var/log/le-renew.log

    Тогда оно будет отрабатывать 1-ого числа через каждые 3 месяца в 0 часов 0 минут.
    А у вас это запуск в 4 часа 30 минут каждый день... Зачем? :)

    • А если у вас обновление сертификата раз в 3 месяца не состоится по какой-то причине, будете следующие 3 месяца ждать? Это операция ничего не стоит. Если продление не нужно, ничего не произойдет. Обновление может завершиться ошибкой с достаточно большой долей вероятности. Я постоянно с этим сталкиваюсь. Самая популярная ошибка - не пройдет резолв dns. Я предпочитаю на следующий день еще раз произвести попытку обновления, если предыдущая завершилась ошибкой.

  8. Андрей

    Надо к статье добавить ftp установку

      • Андрей

        Спасибо и ещё вопросик, как тут включить Обработка .htaccess ? при установке Bitrix показывает, что выключен

        • В свойства виртуального хоста добавить:
          AllowOverride All

          А вообще для битрикса рекомендую использовать bitrixenv.

          • Дак по вашему учебнику уже добавлен

            ...........................................................

            ServerName сайт.ru
            ServerAlias http://www.сайт.ru
            DocumentRoot /web/sites/сайт.ru/www

            ErrorLog /web/sites/сайт.ru/log/error.log
            CustomLog /web/sites/сайт.ru/log/access.log common

            SSLEngine on
            SSLCertificateFile /etc/letsencrypt/live/сайт.ru/fullchain.pem
            SSLCertificateKeyFile /etc/letsencrypt/live/сайт.ru/privkey.pem

            Options FollowSymLinks
            AllowOverride All
            Require all granted

            php_admin_value date.timezone 'Europe/Moscow'
            php_admin_value max_execution_time 60
            .............................................................................

          • А по поводу bitrixenv, не не ставится на centos 8 stream

          • Андрей

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

  9. Появляется после добавления конфы:

    ServerName z.serveradmin.ru
    ServerAlias http://www.z.serveradmin.ru
    DocumentRoot /web/sites/z.serveradmin.ru/www

    ErrorLog /web/sites/z.serveradmin.ru/log/error.log
    CustomLog /web/sites/z.serveradmin.ru/log/access.log common

    Options FollowSymLinks
    AllowOverride All
    Require all granted

    • Вы фатально не понимаете, что делаете. Я даже не знаю, чем помочь. Надо внимательно вникать в то, что написано в статье и в то, что делаете. У вас ошибка в этой строке:

      ServerAlias http://www.z.serveradmin.ru

      Уберите ее вообще или замените на

      ServerAlias www.z.serveradmin.ru

      как у меня в статье.

      • да всё так и делаю как в статье
        скопировалось в коммент почемуто с http://

        убираю строку, всё так же:

        [root@lamp01 ~]# systemctl restart httpd
        Job for httpd.service failed because the control process exited with error code.
        See "systemctl status httpd.service" and "journalctl -xe" for details.

        [root@lamp01 ~]# systemctl status httpd.service
        ● httpd.service - The Apache HTTP Server
        Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
        Drop-In: /usr/lib/systemd/system/httpd.service.d
        └─php-fpm.conf
        Active: failed (Result: exit-code) since Thu 2020-07-02 11:28:06 +05; 8s ago
        Docs: man:httpd.service(8)
        Process: 2544 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
        Main PID: 2544 (code=exited, status=1/FAILURE)
        Status: "Reading configuration..."

        Jul 02 11:28:05 lamp01 systemd[1]: Starting The Apache HTTP Server...
        Jul 02 11:28:06 lamp01 systemd[1]: httpd.service: Main process exited, code=exited, status=1/FAILURE
        Jul 02 11:28:06 lamp01 systemd[1]: httpd.service: Failed with result 'exit-code'.
        Jul 02 11:28:06 lamp01 systemd[1]: Failed to start The Apache HTTP Server.

        в логах выдаёт:
        [Thu Jul 02 11:21:54.267125 2020] [mpm_event:notice] [pid 1450:tid 140293726718272] AH00492: caught SIGWINCH, shutting down gracefully
        (13)Permission denied: AH00091: httpd: could not open error log file /web/sites/z.serveradmin.ru/log/error.log.
        AH00015: Unable to open logs
        (13)Permission denied: AH00091: httpd: could not open error log file /web/sites/z.serveradmin.ru/log/error.log.
        AH00015: Unable to open logs

        • Вот ошибка:

          (13)Permission denied: AH00091: httpd: could not open error log file /web/sites/z.serveradmin.ru/log/error.log

          Нет доступа к папке с логами, которые указаны в конфиге.

          • Помогите понять почему нет доступа то?
            папки созданы, но в них действительно пусто, файлы .log не создались

            • Виталий

              У меня такая же проблема, я так понимаю что то с командой chown -R apache. /web/sites/, потому как она как раз и даёт доступ до нужных папок данной службе. Попробуйте без точки, вот так chown -R apache /web/sites/

              • Проверьте вручную, кто владелец директорий с сайтами и логами. Должен быть apache. Если нет, назначьте его.

              • Леонид

                Добрый день!
                Отключите или настройте selinux.

  10. ошибка такая:
    Job for httpd.service failed because the control process exited with error code.
    See "systemctl status httpd.service" and "journalctl -xe" for details.

  11. народ подскажите
    не могу выполнить
    # IncludeOptional conf.d/*.conf
    выдаёт command not found

    после # apachectl -t ошибок нет
    а вот после # systemctl restart httpd апач не запускается(
    что не так?

    • Эту команду не нужно выполнять. Это комментарий в конфигурационном файле.

  12. Огромное спасибо! Все настроил по Вашей статье и по ходу дела больше стал разбираться что и зачем.

  13. Опечатка в цели. Не nginx, а apache.
    Показать, как установить актуальные версии nginx, php и mariadb.

  14. Виталий

    День добрый, на первом же шаге, dnf install httpd, показывает ошибки кодировки:
    Total download size: 2.3 M
    Installed size: 6.6 M
    Is this ok [y/N]: y
    Traceback (most recent call last):
    File "/usr/bin/dnf", line 58, in
    main.user_main(sys.argv[1:], exit_code=True)
    File "/usr/lib/python3.6/site-packages/dnf/cli/main.py", line 191, in user_main
    errcode = main(args)
    File "/usr/lib/python3.6/site-packages/dnf/cli/main.py", line 65, in main
    return _main(base, args, cli_class, option_parser_class)
    File "/usr/lib/python3.6/site-packages/dnf/cli/main.py", line 98, in _main
    return cli_run(cli, base)
    File "/usr/lib/python3.6/site-packages/dnf/cli/main.py", line 122, in cli_run
    ret = resolving(cli, base)
    File "/usr/lib/python3.6/site-packages/dnf/cli/main.py", line 166, in resolving
    base.do_transaction(display=displays)
    File "/usr/lib/python3.6/site-packages/dnf/cli/cli.py", line 213, in do_transaction
    if self.conf.assumeno or not self.output.userconfirm():
    File "/usr/lib/python3.6/site-packages/dnf/cli/output.py", line 712, in userconfirm
    choice = dnf.i18n.ucd_input(msg)
    File "/usr/lib/python3.6/site-packages/dnf/i18n.py", line 122, in ucd_input
    return dnf.pycomp.raw_input()
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd0 in position 0: invalid continuation byte

    • Какие-то проблемы с dnf и кодировкой консоли. У вас язык какой установлен? Рекомендую сменить временно на en_US.UTF-8 и попробовать.

      • Виталий

        Изначально при установке:
        LANG=en_US.UTF-8

        При повторном выполнении команды dnf install httpd, установилось нормально, что было фиг знает. Но всё равно спасибо за ответ.

        • В статье по центосу 7 описано как сгенерировать для апачи и как его подкинуть к постфиксу, но там не работает уже бесплатный сервис, а в этой статье описан альтернативный вариант через certbot, но не написано как их прописать в постфиксе. И еще не понятно про автоматическое обновление сертификата, оно через каждые 30 минут и каждые 4 часа обновляется, по расписанию планировщика?

  15. хм чето не пойму вроде все сделал по инструкции, но с https проблема выдает циклическую переадресацию сайта браузер. Сайт простенький одна html страница.

  16. Виктор

    Приветствую.
    Если несколько сайтов на апаче, каким ты образом разграничиваешь доступ? mpm-itk вроде в epel-release под 8 центос отсутствует.

    • У меня нет сейчас сайтов под apache, кроме bitrix. Но там свое окружение bitrixenv. На каждого заказчика отдельная виртуалка. Нет необходимости разграничения доступа. Так что я не прорабатывал этот вопрос. Сейчас и битрикс умеет на php-fpm работать. Скоро апач вообще не нужен будет.

  17. В главе - Настройка ssl сертификата Lets Encrypt в apache
    Сайт не хотел запускаться, так как писалось, что сертификат самоподписан (не сильно разобрался), но помогло создание отдельных конфигов для ssl

  18. Владимир

    Добрый день!
    Все сделал по гайду, но вот затык на php my admin, все по инструкции но не заходит на него никак. Я тока начал линукс изучать и не могу добится почему... помогите плиз

    • Владимир

      Может потому что нет на самом деле доменного имени? по ip из локалки видно апач и phpinfo, но они доступны по ip в строке браузера. а вот pma.cit.ru недоступен из сети ни локально никак... хотя на своей рабочей машине я прикрутил в файлик host ip___cit.ru

      • Владимир

        с хостом разобрался, мешала настройка прокси, убрал заработало, но pma.cit.ru недоступно попрежнему

        • Я новичок в этой теме. Такая же проблема, но потом заметил, что в папке /etc/httpd/conf.d/ нет файла для pma.serveradmin.ru, в инструкции опечатка, мы его создали но не туда положили) Поэтому и не работало) ну и файл hosts тоже нужно подправить и добавить туда pma.serveradmin.ru

          А вообще спасибо автору, изучаю Centos по данной статье)

          • Где именно опечатка, не понял?

            • Цитирую: "И готовим конфиг apache по аналогии с уже созданным доменом. Создаем файл pma.serveradmin.ru.conf.

              # mcedit pma.serveradmin.ru.conf"

              путь не указан

            • Друзья выше, просто имели в виду, что при ЧИСТОЙ установке CentOS 8: в главе Установка phpmyadmin, указанный Вами сайт - подсайт pma.serveradmin.ru, требуется положить в каталог /etc/httpd/conf.d и создать там файл pma.serveradmin.ru.conf
              ! mcedit /etc/httpd/conf.d/pma.serveradmin.ru.conf

  19. Андрей

    Добрый день, разворачиваю Apache+PHP на RHEL8 и заметил, что в момент установка PHP, он также устанавливает PHP_FPM и судя по этой статье https://www.linuxbabe.com/redhat/install-lamp-stack-centos-8-rhel-8
    в 8ой версии по умолчанию ставится связка Apache + PHP_FPM а не Apache + MOD_PHP

    Apache web server on CentOS 8/RHEL 8 by default uses PHP-FPM instead of mod_php to run PHP code

    Можно ли сделать классическую установку Apache+MOD_PHP

    • Да, все верно. Я тоже это заметил. По-умолчанию ставится php-fpm. Если вам надо mod_php, то ставьте его и используйте. Проблем быть не должно.

      • Андрей

        А вот тут как раз мои знания не очень =), а как это сделать? Подскажите пожалуйста

  20. Александр

    Добрый день! Спасибо, отличная статья.
    На сервере не хочет обновляться wordpress
    Не подскажите как и какие права нужно дать на папку /wp-content/

  21. Привет.
    Уже написал про проблемы со стартом ВМ Hyper-v 2016.
    Обнаружил еще одну.
    У меня в ВМ два сетевых интерфейса, один смотрит в локалку , второй смотрит наружу.
    Установил связку Nginx+Apache .
    После перезагрузки httpd не стартует, сообщает "could not bind to address 192.168.101.19:80" , локальный интерфейс (там сидит PHPMyAdmin).
    Если httpd перестатовать , он запускается , но сайт не открывается, приходится перезапускать Nginx.
    После этого все работает. Такое впечатление, что Nginx и httpd запускаются до того как загрузился сетевой интерфейс.

    • А не получается так, что у вас и nginx, и apache оба настроены на порт 80 на одном и том же интерфейсе? Можно посмотреть лог /var/log/messages на наличие информации о загрузке сетевых интерфейсов. Если есть какие-то проблемы, там, скорее всего, будет информация. Обычно сетевые интерфейсы поднимаются раньше запуска софта. По крайней мере я ни разу не видел таких ошибок.

      • У меня nginx висит на внешнем интерфейсе, а httpd на внутреннем. И потом если один процесс захватил порт, то второй уже не запустится. Еще nginx работает как прокси для второго сайта, который висит в другой ВМ в локальной сети. Так вот, после перезагрузки ВМ доступа ко второму сайту тоже нет, пока не перезапустишь nginx.
        К стати по поводу отказа от iptables можно прочитать https://xakep.ru/2014/01/11/using-nftables/
        Но что бы облегчить нам переход , остался firewalld работающий по верх nftables, и есть еще iptables-translate.

        • Iptables нормально работают, я просто продолжаю использовать их. А по поводу ошибок, надо смотреть логи. Без этого можно только гадать, в чем там проблема.

          • Здравствуйте. Как я пониманию, в Centos 8 Iptables работает аналогично yum, что дает время на изучение nftables.
            И про php_admin_value. У меня на Centos 7 (Apache 2.4.6 php 7.3) такой проблемы нет, без всякого шаманства, но 15-php.conf выглядит так:
            # Cannot load both php5 and php7 modules

            LoadModule php7_module modules/libphp7.so

            LoadModule php7_module modules/libphp7-zts.so

            На 8-ке в httpd/error.log идут предупреждения о не совместимости с prefork.
            Честно скажу, я не любитель "шаманства" и считаю , что софт должен запускаться с настройками по умолчанию. А когда правишь системные конфиги, не известно где вылезут "грабли". Решил пока Centos 8 оставить для экспериментов.
            Спасибо за ответы.

            • Тут нет никакого шаманства. Ситуацию с prefork я описал в статье. Это все штатный функционал. Чтобы хорошо работало, надо разбираться. А если не хочется, то можно и Centos 7 использовать, там можно ничего не выбирать, все работает по дефолту. Разницы для сайта никакой нет.

      • Обновил Hyeper-v до 2019.
        Теперь Centos 8 стартует нормально в ВМ поколение 2.
        Но проблема осталась. При перезагрузке ВМ, Nginx стартует нормально а httpd по прежнему выдает «could not bind to address 192.168.101.19:80» и еще про "ServerName" ( 192.168.101.19 IP интерфейса eth1). Отключение из загрузка Nginx, смена порта на другой (8008) не помогает. Еще раз повторюсь, что если после загрузки сервера в консоли дать команду systemctl start httpd, Apache стартует без ошибок.
        Помогло следующее , в httpd.conf вместо Listen 192.168.101.19:8080 , прописал просто Listen 8080 ( на 80 у меня висит Nginx). Но я всё равно думаю , что это какой то косяк, и связан с загрузкой NetworkManager.
        Есть какие то мысли?
        Спасибо

        • Судя по всему, какая-то проблема с инициализацией сети. Httpd стартует раньше, чем готов настроенный сетевой интерфейс, вот и ошибка. А потом, когда сеть загрузится, проблем нет. Возможно, исправив юнит для systemd с загрузкой httpd, можно решить проблему. Там можно добавить ожидание готовности сети.

          • Здравствуйте.
            Разобрался. Действительно, httpd стартовал раньше инициализации сети, и эта проблема встречается довольно часто.
            Решение:
            Проверить , разрешен ли NetworkManager-wait-online.service , этот сервис запускается после NetworkManager.service.
            В httpd.service заменить: After=network.target на After=network-online.target.
            После этого все стартует нормально и даже про «ServerName» не ругается.
            К стати в nginx.service было прописана именно After=network-online.target.
            Всем удачи.

  22. Супер статья, всё разложил по полочкам. Спасибо

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Нажимая кнопку "Отправить комментарий" Я даю согласие на обработку персональных данных.
Используешь Telegram? Подпишись на канал автора →
This is default text for notification bar