Skip to content

Instantly share code, notes, and snippets.

@numbnet
Last active June 14, 2021 00:07
Show Gist options
  • Save numbnet/feec440330c04be057e9c984cd182e84 to your computer and use it in GitHub Desktop.
Save numbnet/feec440330c04be057e9c984cd182e84 to your computer and use it in GitHub Desktop.

Revisions

  1. numbnet revised this gist Jun 14, 2021. 1 changed file with 18 additions and 20 deletions.
    38 changes: 18 additions & 20 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,6 @@
    <div id="articleBody" itemprop="articleBody">
    <div itemscope="" itemtype="http://schema.org/ImageObject" itemprop="image" style="display: none;">
    <link itemprop="url contentUrl" href="https://www.dmosk.ru/img/schema.org/instruktions/tmico_centos8-mega-webserver.png">
    <meta itemprop="width" content="300">
    <meta itemprop="height" content="225">
    </div>
    <h1 itemprop="headline name">NGINX + Apache (httpd) + MariaDB&nbsp;(MySQL) + PHP&nbsp;+ PHP-FPM (fastCGI) + FTP + PHPMyAdmin + Memcached + Postfix на CentOS 8</h1>

    @@ -144,7 +142,7 @@
    <p style="display: none;">Внесем небольшую корректировку в файл nginx.conf:</p>

    <div class="console">
    <p>vi /etc/nginx/nginx.conf</p>
    <p>nano /etc/nginx/nginx.conf</p>
    </div>

    <p style="display: none;">В секцию&nbsp;http добавим строку:</p>
    @@ -241,7 +239,7 @@
    <p style="display: none;">Открываем настройки php-fpm:</p>

    <div class="console">
    <p>vi /etc/php-fpm.d/www.conf</p>
    <p>nano /etc/php-fpm.d/www.conf</p>
    </div>

    <p style="display: none;">Проверяем, что параметр listen настроен так:</p>
    @@ -275,7 +273,7 @@
    <p style="display: none;">Создаем index.php&nbsp;в каталоге&nbsp;сайта по умолчанию&nbsp;со следующим содержимым:</p>

    <div class="console">
    <p>vi /usr/share/nginx/html/index.php</p>
    <p>nano /usr/share/nginx/html/index.php</p>
    </div>

    <div class="editor">
    @@ -412,7 +410,7 @@
    <p style="display: none;">Откроем на редактирование или создадим файл:</p>

    <div class="console">
    <p>vi /usr/share/phpMyAdmin/config.inc.php</p>
    <p>nano /usr/share/phpMyAdmin/config.inc.php</p>
    </div>

    <p style="display: none;">Внесем в него строку:</p>
    @@ -432,7 +430,7 @@ $cfg['blowfish_secret'] = 'jd7n6yIcHOl55ikE7l5HAdNaWwunSHvR';<br>
    <p style="display: none;">Теперь создадим для phpmyadmin&nbsp;отдельный виртуальный домен в NGINX:</p>

    <div class="console">
    <p>vi /etc/nginx/conf.d/phpMyAdmin.conf</p>
    <p>nano /etc/nginx/conf.d/phpMyAdmin.conf</p>
    </div>

    <p style="display: none;">И добавим в него следующее содержимое:</p>
    @@ -494,7 +492,7 @@ $cfg['blowfish_secret'] = 'jd7n6yIcHOl55ikE7l5HAdNaWwunSHvR';<br>
    <p style="display: none;">Создаем или открываем на редактирование конфигурационный файл для запуска сервиса:</p>

    <div class="console">
    <p>vi /etc/sysconfig/memcached</p>
    <p>nano /etc/sysconfig/memcached</p>
    </div>

    <p style="display: none;">Приводим его к виду:&nbsp;</p>
    @@ -584,7 +582,7 @@ OPTIONS="-l 127.0.0.1 -U 0"</p>
    <p style="display: none;">Создаем конфигурационной файл для подключения расширения:</p>

    <div class="console">
    <p>vi /etc/php.d/20-memcached.ini</p>
    <p>nano /etc/php.d/20-memcached.ini</p>
    </div>

    <div class="editor">
    @@ -687,7 +685,7 @@ OPTIONS="-l 127.0.0.1 -U 0"</p>
    <p style="display: none;">Открываем на редактирование конфигурационный файл proftpd:</p>

    <div class="console">
    <p>vi /etc/proftpd.conf</p>
    <p>nano /etc/proftpd.conf</p>
    </div>

    <p style="display: none;">И редактируем следующее (комментируем):</p>
    @@ -699,7 +697,7 @@ OPTIONS="-l 127.0.0.1 -U 0"</p>
    <p style="display: none;">Создадим конфигурационный файл со своими настройками:</p>

    <div class="console">
    <p>vi /etc/proftpd/conf.d/custom.conf</p>
    <p>nano /etc/proftpd/conf.d/custom.conf</p>
    </div>

    <p style="display: none;">И добавим следующее:</p>
    @@ -810,7 +808,7 @@ AuthOrder mod_auth_file.c</p>
    <p style="display: none;">Создаем php-файл со следующим содержимым:</p>

    <div class="console">
    <p>vi /var/www/html/index.php</p>
    <p>nano /var/www/html/index.php</p>
    </div>

    <div class="editor">
    @@ -830,7 +828,7 @@ AuthOrder mod_auth_file.c</p>
    <p style="display: none;">Открываем конфигурационный файл nginx:</p>

    <div class="console">
    <p>vi /etc/nginx/nginx.conf</p>
    <p>nano /etc/nginx/nginx.conf</p>
    </div>

    <p style="display: none;">Находим наш настроенный location для php-fpm:</p>
    @@ -866,7 +864,7 @@ AuthOrder mod_auth_file.c</p>
    <p style="display: none;">Проверяем, есть ли файл:</p>

    <div class="console">
    <p>vi /etc/nginx/default.d/php.conf</p>
    <p>nano /etc/nginx/default.d/php.conf</p>
    </div>

    <p style="display: none;">... и если есть, комментируем его содержимое:</p>
    @@ -957,7 +955,7 @@ AuthOrder mod_auth_file.c</p>
    <p style="display: none;">Создаем конфигурационный файл со следующим содержимым:</p>

    <div class="console">
    <p>vi /etc/httpd/conf.d/mod_rpaf.conf</p>
    <p>nano /etc/httpd/conf.d/mod_rpaf.conf</p>
    </div>

    <div class="editor">
    @@ -995,7 +993,7 @@ RPAF_ForbidIfNotProxy&nbsp;&nbsp; Off</p>
    <p style="display: none;">Теперь нам необходимо сделать несколько простых настроек:</p>

    <div class="console">
    <p>vi /etc/postfix/main.cf</p>
    <p>nano /etc/postfix/main.cf</p>
    </div>

    <p style="display: none;">Редактируем:&nbsp;</p>
    @@ -1055,7 +1053,7 @@ inet_protocols = ipv4<br>
    <p style="display: none;">Открываем на редактирование следующий файл:</p>

    <div class="console">
    <p>vi /etc/php.ini</p>
    <p>nano /etc/php.ini</p>
    </div>

    <p style="display: none;">И правим следующее:</p>
    @@ -1085,7 +1083,7 @@ date.timezone = "Europe/Moscow"</p>
    <p style="display: none;">Открываем на редактирование следующий файл:</p>

    <div class="console">
    <p>vi /etc/nginx/nginx.conf</p>
    <p>nano /etc/nginx/nginx.conf</p>
    </div>

    <p style="display: none;">И внутри секции http добавляем:</p>
    @@ -1130,7 +1128,7 @@ date.timezone = "Europe/Moscow"</p>
    <p style="display: none;">Создаем новый файл виртуального домена NGINX:</p>

    <div class="console">
    <p>vi /etc/nginx/conf.d/$TMP_SITE.conf</p>
    <p>nano /etc/nginx/conf.d/$TMP_SITE.conf</p>
    </div>

    <p style="display: none;">
    @@ -1234,7 +1232,7 @@ server {<br>
    <p style="display: none;">Теперь настроим&nbsp;виртуальный&nbsp;домен в Apache:</p>

    <div class="console">
    <p>vi /etc/httpd/conf.d/$TMP_SITE.conf</p>
    <p>nano /etc/httpd/conf.d/$TMP_SITE.conf</p>
    </div>

    <div class="editor">
  2. numbnet revised this gist Jun 14, 2021. 1 changed file with 1193 additions and 338 deletions.
    1,531 changes: 1,193 additions & 338 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,472 +1,1327 @@
    NGINX + Apache (httpd) + MariaDB (MySQL) + PHP + PHP-FPM (fastCGI) + FTP + PHPMyAdmin + Memcached + Postfix на CentOS 8
    Описание
    Общая настройка системы
    Установка пакетов
    dnf update
    <div id="articleBody" itemprop="articleBody">
    <div itemscope="" itemtype="http://schema.org/ImageObject" itemprop="image" style="display: none;">
    <link itemprop="url contentUrl" href="https://www.dmosk.ru/img/schema.org/instruktions/tmico_centos8-mega-webserver.png">
    <meta itemprop="width" content="300">
    <meta itemprop="height" content="225">
    </div>
    <h1 itemprop="headline name">NGINX + Apache (httpd) + MariaDB&nbsp;(MySQL) + PHP&nbsp;+ PHP-FPM (fastCGI) + FTP + PHPMyAdmin + Memcached + Postfix на CentOS 8</h1>


    <label class="checkbox-switch checkbox-switch-switched">
    <div class="switch-box">
    <div class="switch-tumb">
    </div>
    <div class="switch-text">Описание</div>
    </div>
    <input type="checkbox">
    </label>
    <div class="checkbox-switch-after">
    </div>


    dnf install epel-release wget unzip
    <p style="display: none;">Веб-сервер, настроенный по данной инструкции можно будет использовать для размещения собственных сайтов в локальной сети или сети Интернет. Данная инструкция проверена для CentOS 8.</p>

    Время
    \cp /usr/share/zoneinfo/Europe/Moscow /etc/localtime
    <p style="display: none;">Тематические&nbsp;термины: <a href="/terminus.php?object=linux">Linux</a>, <a href="/terminus.php?object=centos">CentOS</a>,&nbsp;<a href="/terminus.php?object=nginx">NGINX</a>, <a href="/terminus.php?object=apache">Apache</a>, <a href="/terminus.php?object=mysql">MySQL</a>, <a href="/terminus.php?object=mariadb">MariaDB</a>,&nbsp;<a href="/terminus.php?object=php-fpm">PHP-FPM</a>,&nbsp;<a href="/terminus.php?object=ftp">FTP</a>,&nbsp;<a href="/terminus.php?object=phpmyadmin">phpMyAdmin</a>,&nbsp;<a href="/terminus.php?object=memcached">Memcached</a>,&nbsp;<a href="/terminus.php?object=postfix">Postfix</a>.</p>

    dnf install chrony
    <p style="display: none;">Содержание:</p>

    systemctl enable chronyd
    <p style="display: none;">
    <a class="self" href="#gen">Общая настройка системы</a>
    <br>
    <a class="self" href="#nginx">Установка NGINX</a>
    <br>
    <a class="self" href="#phpfpm">Установка PHP&nbsp;и PHP-FPM</a>
    <br>
    <a class="self" href="#sql">Установка MariaDB или&nbsp;MySQL</a>
    <br>
    <a class="self" href="#phpmyadmin">Установка phpMyAdmin</a>
    <br>
    <a class="self" href="#memcached">Установка Memcached</a>
    <br>
    <a class="self" href="#ftp">Установка и настройка FTP-сервера</a>
    <br>
    <a class="self" href="#apache">Apache (httpd)</a>
    <br>
    <a class="self" href="#postfix">Postfix</a>
    <br>
    <a class="self" href="#tuning">Тюнинг веб-сервера</a>
    <br>
    <a class="self" href="#firstsite">Создание первого сайта</a>
    </p>

    systemctl start chronyd
    <h2>
    <a id="gen">
    </a>Общая настройка системы</h2>

    Настройка безопасности
    sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config
    <h3>Установка пакетов</h3>

    setenforce 0
    <p style="display: none;">1. Обновляем CentOS:</p>

    firewall-cmd --permanent --add-port={80,443,8080}/tcp
    <div class="console">
    <p>dnf update</p>
    </div>

    firewall-cmd --permanent --add-port={20,21,60000-65535}/tcp
    <p style="display: none;">2. Устанавливаем репозиторий EPEL и дополнительные пакеты для загрузки и распаковки:</p>

    firewall-cmd --permanent --add-port={25,465,587}/tcp
    <div class="console">
    <p>dnf install epel-release wget&nbsp;unzip</p>
    </div>

    firewall-cmd --reload
    <h3>Время</h3>

    Установка NGINX
    dnf install nginx
    <p style="display: none;">1. Устанавливаем часовой пояс:</p>

    vi /etc/nginx/nginx.conf
    <div class="console">
    <p>\cp /usr/share/zoneinfo/Europe/Moscow /etc/localtime</p>
    </div>

    http {
    ...
    server_names_hash_bucket_size 64;
    ....
    }
    <p style="display: none;">
    <em>* данной командой мы&nbsp;установим&nbsp;часовой пояс по московскому времени.</em>
    </p>

    systemctl enable nginx
    <p style="display: none;">2. Устанавливаем и запускаем службу для автоматической синхронизации времени:</p>

    systemctl start nginx
    <div class="console">
    <p>dnf install chrony</p>
    </div>

    Установка PHP и PHP-FPM
    dnf install php php-fpm
    <div class="console">
    <p>systemctl enable chronyd</p>
    </div>

    systemctl enable php-fpm --now
    <div class="console">
    <p>systemctl start chronyd</p>
    </div>

    Настройка связки NGINX + PHP
    vi /etc/nginx/nginx.conf
    <h3>Настройка безопасности</h3>

    location / {
    index index.php index.html index.htm;
    }
    <p style="display: none;">1. Отключаем SELinux:</p>

    location ~ \.php$ {
    set $root_path /usr/share/nginx/html;
    fastcgi_pass unix:/run/php-fpm/www.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;
    include fastcgi_params;
    fastcgi_param DOCUMENT_ROOT $root_path;
    }
    <div class="console">
    <p>sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config</p>
    </div>

    vi /etc/php-fpm.d/www.conf
    <div class="console">
    <p>setenforce 0</p>
    </div>

    listen = /run/php-fpm/www.sock
    <p style="display: none;">
    <em>* первая команда редактирует конфигурационный файл, чтобы <a href="/terminus.php?object=selinux">SELinux</a> не запускался автоматически, вторая — отключает его разово. Подробнее читайте статью <a href="/miniinstruktions.php?mini=selinux-centos">Как отключить SELinux</a>.</em>
    </p>

    systemctl restart php-fpm
    <p style="display: none;">2. Открываем необходимые порты в <a href="/terminus.php?object=firewall">брандмауэре</a>:</p>

    nginx -t
    <div class="console">
    <p>firewall-cmd --permanent --add-port={80,443,8080}/tcp</p>
    </div>

    systemctl restart nginx
    <div class="console">
    <p>firewall-cmd --permanent --add-port={20,21,60000-65535}/tcp</p>
    </div>

    vi /usr/share/nginx/html/index.php
    <div class="console">
    <p>firewall-cmd --permanent --add-port={25,465,587}/tcp</p>
    </div>

    <?php phpinfo(); ?>
    <div class="console">
    <p>firewall-cmd --reload</p>
    </div>

    Установка MariaDB или MySQL
    dnf install mariadb mariadb-server
    <p style="display: none;">
    <em>* 80, 443 и 8080&nbsp;порты для <a href="/terminus.php?object=web-server">веб-сервера</a>; 20, 21&nbsp;порты нужны для работы FTP; </em>60000-65535<em> также необходимы для работы FTP (динамические порты для пассивного режима);&nbsp;25,&nbsp;465 и 587&nbsp;порты нужны&nbsp;для работы почтового сервера по <a href="/terminus.php?object=smtp">SMTP</a>;&nbsp;последняя команда перезапускает&nbsp;firewalld, чтобы применить новые правила. Подробнее про <a href="/miniinstruktions.php?mini=firewalld-centos">настройку firewalld</a>.</em>
    </p>

    systemctl enable mariadb --now
    <h2>
    <a id="nginx">
    </a>Установка NGINX</h2>

    mysqladmin -u root password
    <p style="display: none;">Устанавливаем&nbsp;NGINX:</p>

    PHP + MariaDB (MySQL)
    dnf install php-mysqli
    <div class="console">
    <p>dnf install nginx</p>
    </div>

    dnf install php-mysql
    <p style="display: none;">Внесем небольшую корректировку в файл nginx.conf:</p>

    systemctl restart php-fpm
    <div class="console">
    <p>vi /etc/nginx/nginx.conf</p>
    </div>

    Установка phpMyAdmin
    wget https://files.phpmyadmin.net/phpMyAdmin/5.0.2/phpMyAdmin-5.0.2-all-languages.zip
    <p style="display: none;">В секцию&nbsp;http добавим строку:</p>

    unzip phpMyAdmin-*-all-languages.zip
    <div class="editor">
    <p>http {<br>
    &nbsp;&nbsp; &nbsp;...<br>
    &nbsp;&nbsp; &nbsp;server_names_hash_bucket_size 64;<br>
    &nbsp;&nbsp; &nbsp;....<br>
    }</p>
    </div>

    mkdir /usr/share/phpMyAdmin
    <p style="display: none;">
    <em>* на практике, может встретиться ошибка&nbsp;<strong>could not build server_names_hash, you should increase server_names_hash_bucket_size: 32</strong>. Она возникает при большом количестве виртуальных серверов или если один из них будет иметь длинное название. Данная строка в конфиге исправит ситуацию.</em>
    </p>

    mv phpMyAdmin-*-all-languages/* /usr/share/phpMyAdmin/
    <p style="display: none;">Разрешаем автозапуск сервиса и запустим его:</p>

    chown -R apache:apache /usr/share/phpMyAdmin
    <div class="console">
    <p>systemctl enable nginx</p>
    </div>

    dnf install php-json php-mbstring php-mysqli
    <div class="console">
    <p>systemctl start nginx</p>
    </div>

    head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo ''
    <p style="display: none;">Проверим, что веб-сервер работает. Для этого открываем браузер на другом компьютере, который находится в одной сети&nbsp;и вводим в адресной строке <a href="/terminus.php?object=ipaddr">IP-адрес</a> сервера. В итоге мы должны увидеть заголовок «Welcome to nginx!»:</p>

    vi /usr/share/phpMyAdmin/config.inc.php
    <p style="display: none;">
    <img alt="Заголовок Welcome to nginx!" src="https://www.dmosk.ru/img/instruktions/centos8-mega-webserver-01.jpg" style="width: 680px; height: 185px;" title="Welcome to nginx!">
    </p>

    <?php
    ...
    $cfg['blowfish_secret'] = 'jd7n6yIcHOl55ikE7l5HAdNaWwunSHvR';
    <p style="display: none;">
    <em>* обратите внимание, что данное приветствие может иметь и другой вид.</em>
    </p>

    ?>
    <h2>
    <a id="phpfpm">
    </a>Установка PHP&nbsp;и PHP-FPM</h2>

    vi /etc/nginx/conf.d/phpMyAdmin.conf
    <p style="display: none;">Устанавливаем PHP и php-fpm следующей командой:</p>

    server {
    listen 80;
    server_name phpmyadmin.dmosk.local;
    set $root_path /usr/share/phpMyAdmin;
    <div class="console">
    <p>dnf install php&nbsp;php-fpm</p>
    </div>

    location / {
    root $root_path;
    index index.php;
    }
    <p style="display: none;">
    <em>* В CentOS 8 будет установлена версия php 7.2 и выше</em>
    </p>

    location ~ \.php$ {
    fastcgi_pass unix:/run/php-fpm/www.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;
    include fastcgi_params;
    fastcgi_param DOCUMENT_ROOT $root_path;
    fastcgi_read_timeout 300;
    }
    }
    <p style="display: none;">Запускаем php-fpm и разрешаем его автозапуск:</p>

    systemctl reload nginx
    <div class="console">
    <p>systemctl enable php-fpm --now</p>
    </div>

    systemctl restart php-fpm
    <h3>Настройка связки NGINX + PHP</h3>

    Установка Memcached
    Сервис memcached
    dnf install memcached libmemcached
    <p style="display: none;">Открываем файл для настройки виртуального домена по умолчанию:</p>

    vi /etc/sysconfig/memcached
    <div class="console">
    <p>vi&nbsp;/etc/nginx/nginx.conf</p>
    </div>

    PORT="11211"
    USER="memcached"
    MAXCONN="1024"
    CACHESIZE="512"
    OPTIONS="-l 127.0.0.1 -U 0"
    <p style="display: none;">В секции&nbsp;<strong>location</strong> редактируем параметр <strong>index</strong> на следующее значение:</p>

    systemctl enable memcached --now
    <div class="editor">
    <p>&nbsp; &nbsp; location / {<br>
    &nbsp; &nbsp; &nbsp; &nbsp; index &nbsp;index.php index.html index.htm;<br>
    &nbsp; &nbsp; }</p>
    </div>

    Модуль для php
    wget http://pecl.php.net/get/memcached-3.1.5.tgz
    <p style="display: none;">
    <em>* добавляем&nbsp;<strong>index.php</strong> в начало списка. Если параметра <strong>index</strong> нет, создаем его.</em>
    </p>

    dnf install php-devel zlib-devel make
    <p style="display: none;">А внутри секции&nbsp;<strong>server</strong> добавим следующее:</p>

    dnf --enablerepo=PowerTools install libmemcached-devel
    <div class="editor">
    <p>&nbsp; &nbsp; location ~ \.php$ {<br>
    &nbsp; &nbsp; &nbsp; &nbsp; set $root_path /usr/share/nginx/html;<br>
    &nbsp; &nbsp; &nbsp; &nbsp; fastcgi_pass unix:/run/php-fpm/www.sock;<br>
    &nbsp; &nbsp; &nbsp; &nbsp; fastcgi_index index.php;<br>
    &nbsp; &nbsp; &nbsp; &nbsp; fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;<br>
    &nbsp; &nbsp; &nbsp; &nbsp; include fastcgi_params;<br>
    &nbsp; &nbsp; &nbsp; &nbsp; fastcgi_param DOCUMENT_ROOT $root_path;<br>
    &nbsp; &nbsp; }</p>
    </div>

    tar -xvzf memcached-*.tgz
    <p style="display: none;">
    <em>* где&nbsp;<strong>/usr/share/nginx/html</strong> — корневой путь хранения скриптов; <strong>unix:/run/php-fpm/www.sock</strong> — файл для взаимодействия с php-fpm.</em>
    </p>

    cd memcached-*/
    <p style="display: none;">Открываем настройки php-fpm:</p>

    phpize
    <div class="console">
    <p>vi /etc/php-fpm.d/www.conf</p>
    </div>

    ./configure
    <p style="display: none;">Проверяем, что параметр listen настроен так:</p>

    make
    <div class="editor">
    <p>listen = /run/php-fpm/www.sock</p>
    </div>

    cp modules/memcached.so /usr/lib64/php/modules/
    <p style="display: none;">... иначе, меняем значение. После перезагружаем php-fpm:</p>

    vi /etc/php.d/20-memcached.ini
    <div class="console">
    <p>systemctl restart php-fpm</p>
    </div>

    extension=memcached.so
    <p style="display: none;">
    <em>* в данном примере мы указываем, что php-fpm будет использовать сокетный файл&nbsp;<strong>/run/php-fpm/www.sock</strong> для взаимодействия. Этот файл мы указали выше в настройке NGINX.</em>
    </p>

    systemctl restart php-fpm
    <p style="display: none;">Проверяем правильность настроек nginx:</p>

    php -m | grep memcached
    <div class="console">
    <p>nginx -t</p>
    </div>

    Установка и настройка FTP-сервера
    dnf install proftpd
    <p style="display: none;">И перезагружаем его:</p>

    wget http://www.castaglia.org/proftpd/contrib/ftpasswd -P /etc/proftpd
    <div class="console">
    <p>systemctl restart nginx</p>
    </div>

    chmod +x /etc/proftpd/ftpasswd
    <p style="display: none;">Создаем index.php&nbsp;в каталоге&nbsp;сайта по умолчанию&nbsp;со следующим содержимым:</p>

    /etc/proftpd/ftpasswd --passwd --file=/etc/proftpd/ftpd.passwd --name=ftpwww --uid=48 --gid=48 --home=/var/www --shell=/sbin/nologin
    <div class="console">
    <p>vi /usr/share/nginx/html/index.php</p>
    </div>

    chmod 440 /etc/proftpd/ftpd.passwd
    <div class="editor">
    <p>&lt;?php phpinfo(); ?&gt;</p>
    </div>

    vi /etc/proftpd.conf
    <p style="display: none;">Открываем в браузере IP-адрес нашего сервера. Теперь мы должны увидеть сводную информацию по PHP и его настройкам, например:</p>

    #AuthOrder ...
    <p style="display: none;">
    <img alt="Информация о php (phpinfo)" src="https://www.dmosk.ru/img/instruktions/centos8-mega-webserver-02.jpg" style="width: 531px; height: 263px;" title="Информация о php (phpinfo)">
    </p>

    vi /etc/proftpd/conf.d/custom.conf
    <h2>
    <a id="sql">
    </a>Установка MariaDB или&nbsp;MySQL</h2>

    UseIPv6 off
    IdentLookups off
    PassivePorts 60000 65535
    <p style="display: none;">В данной статье мы установим MariaDB, но процедура установки и настройки MySQL аналогичная. Все расхождения будут отмечены явно в инструкции.</p>

    RequireValidShell off
    AuthUserFile /etc/proftpd/ftpd.passwd
    AuthPAM off
    LoadModule mod_auth_file.c
    AuthOrder mod_auth_file.c
    <p style="display: none;">Устанавливаем MariaDB следующей командой:</p>

    systemctl enable proftpd --now
    <div class="console">
    <p>dnf install mariadb&nbsp;mariadb-server</p>
    </div>

    Apache (httpd)
    dnf install httpd
    <p style="display: none;">
    <em>* для установки mysql выполняем команду <strong>dnf install mysql</strong>
    </em>
    </p>

    vi /etc/httpd/conf/httpd.conf
    <p style="display: none;">Разрешаем автозапуск и запускаем СУБД:</p>

    Listen 8080
    <div class="console">
    <p>systemctl enable mariadb --now</p>
    </div>

    <IfModule dir_module>
    DirectoryIndex index.php index.html
    </IfModule>
    <p style="display: none;">
    <em>* для работы с mysql меняем&nbsp;<strong>mariadb</strong> на&nbsp;<strong>mysql</strong>.</em>
    </p>

    <Directory /var/www/*/www>
    AllowOverride All
    Options Indexes ExecCGI FollowSymLinks
    Require all granted
    </Directory>
    <p style="display: none;">Сразу создаем пароль для учетной записи root:</p>

    apachectl configtest
    <div class="console">
    <p>mysqladmin -u root password</p>
    </div>

    systemctl enable httpd
    <h3>PHP + MariaDB (MySQL)</h3>

    systemctl start httpd
    <p style="display: none;">Для возможности подключаться к базе данных скриптами PHP необходимо установить следующие модули:</p>

    vi /var/www/html/index.php
    <div class="console">
    <p>dnf install&nbsp;php-mysqli</p>
    </div>

    <?php phpinfo(); ?>
    <p style="display: none;">Если мы установили php5, также ставим&nbsp;php-mysql:</p>

    NGINX + Apache
    vi /etc/nginx/nginx.conf
    <div class="console">
    <p>dnf install php-mysql</p>
    </div>

    ...
    location ~ \.php$ {
    set $root_path /usr/share/nginx/html;
    fastcgi_pass unix:/run/php-fpm/www.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;
    include fastcgi_params;
    fastcgi_param DOCUMENT_ROOT $root_path;
    }
    ...
    <p style="display: none;">После перезагружаем php-fpm:</p>

    ...
    location ~ \.php$ {
    proxy_pass http://127.0.0.1:8080;
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    ...
    <div class="console">
    <p>systemctl restart php-fpm</p>
    </div>

    vi /etc/nginx/default.d/php.conf
    <p style="display: none;">И открываем наш сайт в браузере. В phpinfo появится новая секция MySQL:</p>

    #index index.php index.html index.htm;
    #
    #location ~ \.(php|phar)(/.*)?$ {
    # fastcgi_split_path_info ^(.+\.(?:php|phar))(/.*)$;
    #
    # fastcgi_intercept_errors on;
    # fastcgi_index index.php;
    # include fastcgi_params;
    # fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    # fastcgi_param PATH_INFO $fastcgi_path_info;
    # fastcgi_pass php-fpm;
    #}
    <p style="display: none;">
    <img alt="В phpinfo появилась информация о поддержке MySQL" src="https://www.dmosk.ru/img/instruktions/centos-mega-webserver-03.jpg" style="width: 687px; height: 120px;" title="В phpinfo появилась информация о поддержке MySQL">
    </p>

    nginx -t
    <p style="display: none;">
    <em>* нас не должно смущать, что установили мы mariadb, а заголовок mysql. Если посмотреть в таблицу, можно увидеть ячейку <strong>Client API version</strong>, в которой указано, что используется именно mariadb.</em>
    </p>

    systemctl restart nginx
    <h2>
    <a id="phpmyadmin">
    </a>Установка phpMyAdmin</h2>

    Apache Real IP
    dnf install httpd-devel gcc unzip redhat-rpm-config
    <p style="display: none;">Переходим на&nbsp;<a href="https://www.phpmyadmin.net/files/" target="_blank">сайт разработчика&nbsp;phpMyAdmin</a>&nbsp;и копируем ссылку на&nbsp;нужную нам версию, например, последнюю:</p>

    cd /usr/local/src
    <p style="display: none;">
    <img alt="Копируем ссылку на последнюю версию phpMyAdmin" src="https://www.dmosk.ru/img/instruktions/centos-mega-webserver-12.jpg" style="width: 449px; height: 210px;" title="Копируем ссылку на последнюю версию phpMyAdmin">
    </p>

    wget https://github.com/gnif/mod_rpaf/archive/stable.zip
    <p style="display: none;">Воспользовавшись скопированной ссылкой, скачиваем архив с установочными&nbsp;файлами:</p>

    unzip stable.zip
    <div class="console">
    <p>wget&nbsp;https://files.phpmyadmin.net/phpMyAdmin/5.0.2/phpMyAdmin-5.0.2-all-languages.zip</p>
    </div>

    cd mod_rpaf-stable/
    <p style="display: none;">Распаковываем скачанный архив:</p>

    make
    <div class="console">
    <p>unzip phpMyAdmin-*-all-languages.zip</p>
    </div>

    make install
    <p style="display: none;">Создаем каталог для phpmyadmin:</p>

    vi /etc/httpd/conf.d/mod_rpaf.conf
    <div class="console">
    <p>mkdir&nbsp;/usr/share/phpMyAdmin</p>
    </div>

    LoadModule rpaf_module modules/mod_rpaf.so
    RPAF_Enable On
    RPAF_ProxyIPs 127.0.0.1
    RPAF_SetHostName On
    RPAF_SetHTTPS On
    RPAF_SetPort On
    RPAF_ForbidIfNotProxy Off
    <p style="display: none;">... и переносим в него&nbsp;содержимое распакованного архива:</p>

    systemctl restart httpd
    <div class="console">
    <p>mv phpMyAdmin-*-all-languages/* /usr/share/phpMyAdmin/</p>
    </div>

    Postfix
    dnf install postfix
    <p style="display: none;">Задаем владельца для каталога:</p>

    vi /etc/postfix/main.cf
    <div class="console">
    <p>chown -R apache:apache&nbsp;/usr/share/phpMyAdmin</p>
    </div>

    ...
    myorigin = $mydomain
    ...
    inet_protocols = ipv4
    ...
    <p style="display: none;">
    <em>* как правило, сервис, которых обрабатываем php-запросы работает от пользователя&nbsp;<strong>apache</strong>.</em>
    </p>

    smtp_generic_maps = hash:/etc/postfix/generic_map
    <p style="display: none;">Устанавливаем&nbsp;модули&nbsp;php, необходимые для корректной работы&nbsp;phpMyAdmin:</p>

    vi /etc/postfix/generic_map

    @dmosk.local [email protected]

    postmap /etc/postfix/generic_map

    systemctl restart postfix

    Тюнинг веб-сервера
    PHP
    vi /etc/php.ini

    upload_max_filesize = 512M
    ...
    post_max_size = 512M
    ...
    short_open_tag = On
    ...
    date.timezone = "Europe/Moscow"

    systemctl restart php-fpm

    systemctl restart httpd

    NGINX
    vi /etc/nginx/nginx.conf

    client_max_body_size 512M;
    <div class="console">
    <p>dnf install php-json&nbsp;php-mbstring&nbsp; php-mysqli</p>
    </div>

    systemctl restart nginx
    <p style="display: none;">Внесем небольшую настройку в конфигурацию phpMyAdmin.</p>

    Postfix
    Создание первого сайта
    TMP_SITE=site1
    <p style="display: none;">Сгенерируем случайную последовательность символов:</p>

    vi /etc/nginx/conf.d/$TMP_SITE.conf
    <div class="console">
    <p>head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo ''</p>
    </div>

    server {
    listen 80;
    server_name site1.local www.site1.local;
    set $root_path /var/www/site1/www;
    <p style="display: none;">Откроем на редактирование или создадим файл:</p>

    access_log /var/www/site1/log/nginx/access_log;
    error_log /var/www/site1/log/nginx/error_log;

    gzip on;
    gzip_disable "msie6";
    gzip_min_length 1000;
    gzip_vary on;
    gzip_proxied expired no-cache no-store private auth;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
    <div class="console">
    <p>vi /usr/share/phpMyAdmin/config.inc.php</p>
    </div>

    root $root_path;
    <p style="display: none;">Внесем в него строку:</p>

    location / {
    proxy_pass http://127.0.0.1:8080/;
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location ~* ^.+\.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|docx|xls|xlsx|exe|pdf|ppt|tar|wav|bmp|rtf|js)$ {
    expires modified +1w;
    }
    }
    <div class="editor">
    <p>&lt;?php<br>
    ...<br>
    $cfg['blowfish_secret'] = 'jd7n6yIcHOl55ikE7l5HAdNaWwunSHvR';<br>
    <br>
    ?&gt;</p>
    </div>

    server {
    listen 80;
    server_name site1.local www.site1.local;
    return 301 https://$host$request_uri;
    }
    <p style="display: none;">
    <em>* где&nbsp;jd7n6yIcHOl55ikE7l5HAdNaWwunSHvR — последовательность, которую нам выдала команда&nbsp;head <strong>/dev/urandom ...</strong>; Также обратите внимание на&nbsp;</em>
    <strong>&lt;?php&nbsp;?&gt;</strong>&nbsp;— если мы создали новый файл, необходимо указать данные теги, так как они открывают код PHP. В противном случае, настройка не применится.</p>

    server {
    listen 443 ssl;
    ssl on;
    ssl_certificate /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/cert.key;
    <p style="display: none;">Теперь создадим для phpmyadmin&nbsp;отдельный виртуальный домен в NGINX:</p>

    server_name site1.local www.site1.local;
    set $root_path /var/www/site1/www;
    <div class="console">
    <p>vi /etc/nginx/conf.d/phpMyAdmin.conf</p>
    </div>

    access_log /var/www/site1/log/nginx/access_log;
    error_log /var/www/site1/log/nginx/error_log;

    gzip on;
    gzip_disable "msie6";
    gzip_min_length 1000;
    gzip_vary on;
    gzip_proxied expired no-cache no-store private auth;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
    <p style="display: none;">И добавим в него следующее содержимое:</p>

    root $root_path;
    <div class="editor">
    <p>server {<br>
    &nbsp; &nbsp; &nbsp; &nbsp; listen &nbsp; &nbsp; &nbsp; 80;<br>
    &nbsp; &nbsp; &nbsp; &nbsp; server_name &nbsp;phpmyadmin.dmosk.local;<br>
    &nbsp; &nbsp; &nbsp; &nbsp; set $root_path /usr/share/phpMyAdmin;<br>
    <br>
    &nbsp; &nbsp; &nbsp; &nbsp; location / {<br>
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; root $root_path;<br>
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; index index.php;<br>
    &nbsp; &nbsp; &nbsp; &nbsp; }<br>
    <br>
    &nbsp; &nbsp; &nbsp; &nbsp; location ~ \.php$ {<br>
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fastcgi_pass unix:/run/php-fpm/www.sock;<br>
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fastcgi_index index.php;<br>
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;<br>
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; include fastcgi_params;<br>
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fastcgi_param DOCUMENT_ROOT $root_path;<br>
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;fastcgi_read_timeout 300;<br>
    &nbsp; &nbsp; &nbsp; &nbsp; }<br>
    }</p>
    </div>

    location / {
    proxy_pass http://127.0.0.1:8080/;
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location ~* ^.+\.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|docx|xls|xlsx|exe|pdf|ppt|tar|wav|bmp|rtf|js)$ {
    expires modified +1w;
    }
    }
    <p style="display: none;">
    <em>* где&nbsp;<strong>phpmyadmin.dmosk.local</strong> — адрес для виртуального домена, именно этот адрес должен быть введен в адресную строку браузера, чтобы открылся нужный сайт. Поэтому если&nbsp;нет возможности&nbsp;зарегистрировать домен и имя узла в <a href="/terminus.php?object=dns">DNS</a>, можно воспользоваться локальным файлом hosts. <strong>/usr/share/phpMyAdmin</strong> — это каталог, в который по умолчанию устанавливается phpMyAdmin.</em>
    </p>

    vi /etc/httpd/conf.d/$TMP_SITE.conf
    <p style="display: none;">После перезапускаем&nbsp;NGINX:</p>

    <VirtualHost *:8080>
    Define root_domain site1.local
    Define root_path /var/www/site1
    <div class="console">
    <p>systemctl reload nginx</p>
    </div>

    ServerName ${root_domain}
    ServerAlias www.${root_domain}
    DocumentRoot ${root_path}/www
    <p style="display: none;">Также нужно перезапустить php-fpm, так как в процессе установки были&nbsp;добавлены модули для PHP:</p>

    ErrorLog ${root_path}/log/apache/error_log
    TransferLog ${root_path}/log/apache/access_log
    </VirtualHost>
    <div class="console">
    <p>systemctl restart php-fpm</p>
    </div>

    mkdir -p /var/www/$TMP_SITE/{www,tmp}
    <p style="display: none;">И открываем в браузере наш домен, в данном примере, <u>http://phpmyadmin.dmosk.local</u>. Откроется форма для авторизации — вводим логин root и пароль,&nbsp;который&nbsp;мы указали после установки и запуска mariadb.</p>

    mkdir -p /var/www/$TMP_SITE/log/{nginx,apache}
    <h2>
    <a id="memcached">
    </a>Установка Memcached</h2>

    vi /var/www/$TMP_SITE/www/index.php
    <p style="display: none;">Первым этапом&nbsp;мы установим и настроим&nbsp;сервис&nbsp;memcached. Вторым — модуль php-memcached.</p>

    <?php echo "<h1>Hello from site1</h1>"; ?>
    <h3>Сервис&nbsp;memcached</h3>

    chown -R apache:apache /var/www/$TMP_SITE

    chmod -R 775 /var/www/$TMP_SITE
    <p style="display: none;">Выполняем&nbsp;установку пакетов:</p>

    nginx -t

    apachectl configtest

    systemctl reload nginx

    systemctl reload httpd

    mysql -uroot -p

    > CREATE DATABASE site1 DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
    <div class="console">
    <p>dnf install memcached&nbsp;libmemcached</p>
    </div>

    > GRANT ALL PRIVILEGES ON site1.* TO dbuser@localhost IDENTIFIED BY 'password' WITH GRANT OPTION;
    <p style="display: none;">Создаем или открываем на редактирование конфигурационный файл для запуска сервиса:</p>

    <div class="console">
    <p>vi /etc/sysconfig/memcached</p>
    </div>

    <p style="display: none;">Приводим его к виду:&nbsp;</p>

    <div class="editor">
    <p>PORT="11211"<br>
    USER="memcached"<br>
    MAXCONN="1024"<br>
    CACHESIZE="512"<br>
    OPTIONS="-l 127.0.0.1 -U 0"</p>
    </div>

    <p style="display: none;">
    <em>* где&nbsp;<strong>PORT</strong> указываем на каком порту будет слушать сервис кэширования;&nbsp;<strong>USER</strong> — пользователь, под которым должен запускаться сервис;&nbsp;<strong>MAXCONN</strong> — максимальное число одновременных подключений;&nbsp;<strong>CACHESIZE</strong> — размер под кэш в мегабайтах;&nbsp;<strong>OPTIONS</strong> — параметры запуска (в данном примере наш сервис будет принимать запросы только с адреса локальной петли).</em>
    </p>

    <p style="display: none;">После разрешаем автозапуск и запускаем сервис кэширования:</p>

    <div class="console">
    <p>systemctl enable memcached --now</p>
    </div>

    <h3>Модуль для php</h3>

    <p style="display: none;">Переходим на <a href="http://pecl.php.net/package/memcached" target="_blank">страницу загрузки memcached</a>&nbsp;сайта&nbsp;pecl.php.net и копируем ссылку на стабильную версию memcached:</p>

    <p style="display: none;">
    <img alt="Копируем ссылку на исходник memcached" src="https://www.dmosk.ru/img/instruktions/centos-mega-webserver-07.jpg" style="width: 538px; height: 238px;" title="Копируем ссылку на исходник memcached">
    </p>

    <div class="note" style="display: none;">
    <p>Обратите внимание, что у каждой версии пакета есть свои требования к версии PHP. Внимательно изучаем, подойдет ли версия&nbsp;php-memcached для нашего сервера.</p>
    </div>

    <p style="display: none;">Скачиваем архив, ссылку на который мы скопировали:</p>

    <div class="console">
    <p>wget http://pecl.php.net/get/memcached-3.1.5.tgz</p>
    </div>

    <p style="display: none;">Устанавливаем пакеты, необходимые для сборки&nbsp;php-pecl-memcached:</p>

    <div class="console">
    <p>dnf install&nbsp;php-devel&nbsp;zlib-devel make</p>
    </div>

    <div class="console">
    <p>dnf --enablerepo=PowerTools install libmemcached-devel</p>
    </div>

    <p style="display: none;">Распаковываем скачанный архив:</p>

    <div class="console">
    <p>tar -xvzf memcached-*.tgz</p>
    </div>

    <p style="display: none;">Переходим в распакованный каталог:</p>

    <div class="console">
    <p>cd memcached-*/</p>
    </div>

    <p style="display: none;">Запускаем компиляцию php-расширения:</p>

    <div class="console">
    <p>phpize</p>
    </div>

    <p style="display: none;">Конфигурируем исходник:</p>

    <div class="console">
    <p>./configure</p>
    </div>

    <p style="display: none;">Собираем&nbsp;расширение:</p>

    <div class="console">
    <p>make</p>
    </div>

    <p style="display: none;">Копируем созданный модуль в каталог php-модулей:</p>

    <div class="console">
    <p>cp modules/memcached.so /usr/lib64/php/modules/</p>
    </div>

    <p style="display: none;">Создаем конфигурационной файл для подключения расширения:</p>

    <div class="console">
    <p>vi /etc/php.d/20-memcached.ini</p>
    </div>

    <div class="editor">
    <p>extension=memcached.so</p>
    </div>

    <p style="display: none;">После установки модуля&nbsp;перезапускаем php-fpm:</p>

    <div class="console">
    <p>systemctl restart php-fpm</p>
    </div>

    <p style="display: none;">Чтобы проверить, что модуль&nbsp;memcached работаем, открываем наш сайт в браузере — в phpinfo должна появиться новая секция:</p>

    <p style="display: none;">
    <img alt="В phpinfo появилась информация о поддержке Memcached" src="/img/instruktions/centos-mega-webserver-13.jpg" style="width: 770px; height: 142px;" title="В phpinfo появилась информация о поддержке Memcached">
    </p>

    <p style="display: none;">... или вводим команду:</p>

    <div class="console">
    <p>php -m | grep memcached</p>
    </div>

    <p style="display: none;">Мы должны получить:</p>

    <div class="console-like" style="display: none;">
    <p>
    <span style="color:#FF0000;">memcached</span>
    </p>
    </div>

    <h2>
    <a id="ftp">
    </a>Установка и настройка FTP-сервера</h2>

    <p style="display: none;">В качестве FTP-сервера будем использовать ProFTPd, так как он позволяет авторизовываться под uid системных учетных записей.</p>

    <p style="display: none;">ProFTPd&nbsp;можно устанавливать командой:</p>

    <div class="console">
    <p>dnf install&nbsp;proftpd</p>
    </div>

    <p style="display: none;">Загружаем скрипт&nbsp;ftpasswd:</p>

    <div class="console">
    <p>wget http://www.castaglia.org/proftpd/contrib/ftpasswd -P /etc/proftpd</p>
    </div>

    <p style="display: none;">Разрешаем запуск на выполнение скрипта:</p>

    <div class="console">
    <p>chmod +x /etc/proftpd/ftpasswd</p>
    </div>

    <p style="display: none;">Создаем виртуального пользователя:</p>

    <div class="console">
    <p>/etc/proftpd/ftpasswd --passwd --file=/etc/proftpd/ftpd.passwd --name=ftpwww --uid=48&nbsp;--gid=48&nbsp;--home=/var/www&nbsp;--shell=/sbin/nologin</p>
    </div>

    <p style="display: none;">
    <em>* где</em>
    </p>

    <ul style="display: none;">
    <li>
    <em>
    <strong>/etc/proftpd/ftpd.passwd</strong>&nbsp;— путь до файла, в котором хранятся пользователи; </em>
    </li>
    <li>
    <em>
    <b>ftpwww&nbsp;</b>—&nbsp;имя пользователя (логин);&nbsp;</em>
    </li>
    <li>
    <em>
    <strong>uid</strong>&nbsp;и&nbsp;<strong>gid</strong>&nbsp;— идентификаторы пользователя и группы системной учетной записи (apache);&nbsp;</em>
    </li>
    <li>
    <em>
    <strong>/var/www</strong>&nbsp;— домашний каталог пользователя;&nbsp;</em>
    </li>
    <li>
    <em>
    <strong>/sbin/nologin</strong>&nbsp;— оболочка, запрещающая локальный вход пользователя в систему.</em>
    </li>
    </ul>

    <p style="display: none;">Изменим права для созданного файла с паролями:</p>

    <div class="console">
    <p>chmod 440 /etc/proftpd/ftpd.passwd</p>
    </div>

    <p style="display: none;">
    <em>* в противном случае, при запуске&nbsp;proftpd мы получим ошибку «...fatal: AuthUserFile: unable to use /etc/proftpd.d/ftpd.passwd: Operation not permitted...»</em>
    </p>

    <p style="display: none;">Открываем на редактирование конфигурационный файл proftpd:</p>

    <div class="console">
    <p>vi /etc/proftpd.conf</p>
    </div>

    <p style="display: none;">И редактируем следующее (комментируем):</p>

    <div class="editor">
    <p>#AuthOrder ...</p>
    </div>

    <p style="display: none;">Создадим конфигурационный файл со своими настройками:</p>

    <div class="console">
    <p>vi /etc/proftpd/conf.d/custom.conf</p>
    </div>

    <p style="display: none;">И добавим следующее:</p>

    <div class="editor">
    <p>UseIPv6 off<br>
    IdentLookups off<br>
    PassivePorts 60000 65535<br>
    <br>
    RequireValidShell off<br>
    AuthUserFile /etc/proftpd/ftpd.passwd<br>
    AuthPAM off<br>
    LoadModule mod_auth_file.c<br>
    AuthOrder mod_auth_file.c</p>
    </div>

    <p style="display: none;">
    <em>* где <strong>60000</strong>&nbsp;-&nbsp;<strong>65535</strong> — диапазон динамических портов для пассивного режима.</em>
    </p>

    <p style="display: none;">Разрешаем автозапуск FTP-серверу и запускаем его:</p>

    <div class="console">
    <p>systemctl enable proftpd --now</p>
    </div>

    <p style="display: none;">Пробуем подключиться к серверу, использую любые FTP-клиенты, например, FileZilla, Total Commander или тот же браузер.</p>

    <p style="display: none;">Это базовая и самая простая настройка ProFTPd, но если необходимо настроить TLS или хранить виртуальных пользователей в базе MySQL, читайте подробнее инструкцию по <a href="/instruktions.php?object=proftpd-centos7">настройке ProFTPd&nbsp;на CentOS</a>.</p>

    <h2>
    <a id="apache">
    </a>Apache (httpd)</h2>

    <p style="display: none;">Несмотря на то, что мы установили и настроили PHP-FPM,&nbsp;Apache нам понадобится, как минимум, по двум причинам. Во-первых, многие сайты используют файл .htaccess, который читает Apache. Во-вторых, последний включает большое число модулей, которые может использовать портал.</p>

    <p style="display: none;">В некоторых случаях, можно обойтись без Apache, но в данной инструкции мы опишем процедуру его установки и настройки.</p>

    <p style="display: none;">И так, устанавливаем httpd:</p>

    <div class="console">
    <p>dnf install httpd</p>
    </div>

    <p style="display: none;">Заходим в настройки:</p>

    <div class="console">
    <p>vi&nbsp;/etc/httpd/conf/httpd.conf</p>
    </div>

    <p style="display: none;">И редактируем следующее:</p>

    <div class="editor">
    <p>Listen 8080</p>
    </div>

    <p style="display: none;">
    <em>* наш веб-сервер будет слушать на порту <strong>8080</strong>, так как на 80 уже работает NGINX.</em>
    </p>

    <div class="editor">
    <p>&lt;IfModule dir_module&gt;<br>
    &nbsp; &nbsp; DirectoryIndex index.php index.html<br>
    &lt;/IfModule&gt;</p>
    </div>

    <p style="display: none;">
    <em>* если не указан конкретный скрипт, сначала веб-сервер пытается найти и запустить&nbsp;<strong>index.php</strong>, затем <strong>index.html</strong>
    </em>
    </p>

    <p style="display: none;">Добавляем:</p>

    <div class="editor">
    <p>&lt;Directory /var/www/*/www&gt;<br>
    &nbsp; &nbsp; AllowOverride All<br>
    &nbsp; &nbsp; Options Indexes ExecCGI FollowSymLinks<br>
    &nbsp; &nbsp; Require all granted<br>
    &lt;/Directory&gt;</p>
    </div>

    <p style="display: none;">
    <em>* где&nbsp;<strong>Directory</strong> — разрешенные каталоги для запуска из apache;&nbsp;<strong>Options</strong> — разрешенные опции;&nbsp;<strong>Require</strong> — с каких IP-адресов&nbsp;можно&nbsp;открывать сайты, определенные в данном каталоге. Итого, мы разрешаем все каталоги в&nbsp;<strong>/var/www</strong>, но только если следующий каталог будет <strong>www</strong>; разрешаем опции&nbsp;<strong>Indexes</strong> (возвращает список файлов, если нет индексного файла, например, index.php), <strong>ExecCGI</strong> (разрешены сценарии&nbsp;CGI), <strong>FollowSymLinks</strong> (включены&nbsp;символические&nbsp;ссылки&nbsp;в этом каталоге); доступ для данных каталогов разрешен со&nbsp;всех адресов (<strong>all granted</strong>).</em>
    </p>

    <p style="display: none;">Проверяем синтаксис конфигурационного файла httpd:</p>

    <div class="console">
    <p>apachectl configtest</p>
    </div>

    <p style="display: none;"&nbsp;если получаем ответ:</p>

    <div class="console-like" style="display: none;">
    <p>Syntax OK</p>
    </div>

    <p style="display: none;">... разрешаем автозапуск и запускаем службу:</p>

    <div class="console">
    <p>systemctl enable httpd</p>
    </div>

    <div class="console">
    <p>systemctl start httpd</p>
    </div>

    <p style="display: none;">Создаем php-файл со следующим содержимым:</p>

    <div class="console">
    <p>vi /var/www/html/index.php</p>
    </div>

    <div class="editor">
    <p>&lt;?php phpinfo(); ?&gt;</p>
    </div>

    <p style="display: none;">Открываем браузер и вводим в адресную строку IP-адрес нашего сервера и добавляем :8080 (<u>http://&lt;IP-адрес нашего сервера&gt;:8080</u>). Откроется привычная нам страница с информацией о PHP.&nbsp;В разделе «PHP Variables» мы должны увидеть Apache для опции $_SERVER['SERVER_SOFTWARE']:</p>

    <p style="display: none;">
    <img alt="Страницу с phpinfo загрузил Apache" src="https://www.dmosk.ru/img/instruktions/centos-mega-webserver-10.jpg" style="width: 494px; height: 95px;" title="Страницу с phpinfo загрузил Apache">
    </p>

    <h3>NGINX + Apache</h3>

    <p style="display: none;">Ранее нами была настроена связка nginx + php-fpm. Теперь проверяем совместную работу первого с apache.</p>

    <p style="display: none;">Открываем конфигурационный файл nginx:</p>

    <div class="console">
    <p>vi /etc/nginx/nginx.conf</p>
    </div>

    <p style="display: none;">Находим наш настроенный location для php-fpm:</p>

    <div class="editor">
    <p>...<br>
    &nbsp; &nbsp; location ~ \.php$ {<br>
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;set $root_path /usr/share/nginx/html;<br>
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fastcgi_pass unix:/run/php-fpm/www.sock;<br>
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fastcgi_index index.php;<br>
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;<br>
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; include fastcgi_params;<br>
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fastcgi_param DOCUMENT_ROOT $root_path;<br>
    &nbsp; &nbsp; }<br>
    ...</p>
    </div>

    <p style="display: none;">и меняем на:</p>

    <div class="editor">
    <p>...<br>
    &nbsp; &nbsp; location ~ \.php$ {<br>
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;proxy_pass http://127.0.0.1:8080;<br>
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;proxy_redirect &nbsp; &nbsp; off;<br>
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;proxy_set_header &nbsp; Host &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $host;<br>
    &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;proxy_set_header&nbsp; &nbsp;X-Forwarded-Proto $scheme;<br>
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;proxy_set_header &nbsp; X-Real-IP &nbsp; &nbsp; &nbsp; &nbsp;$remote_addr;<br>
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;proxy_set_header &nbsp; X-Forwarded-For &nbsp;$proxy_add_x_forwarded_for;<br>
    &nbsp;&nbsp; &nbsp;}<br>
    ...</p>
    </div>

    <p style="display: none;">Проверяем, есть ли файл:</p>

    <div class="console">
    <p>vi /etc/nginx/default.d/php.conf</p>
    </div>

    <p style="display: none;">... и если есть, комментируем его содержимое:</p>

    <div class="editor">
    <p>#index index.php index.html index.htm;<br>
    #<br>
    #location ~ \.(php|phar)(/.*)?$ {<br>
    # &nbsp; &nbsp;fastcgi_split_path_info ^(.+\.(?:php|phar))(/.*)$;<br>
    #<br>
    # &nbsp; &nbsp;fastcgi_intercept_errors on;<br>
    # &nbsp; &nbsp;fastcgi_index &nbsp;index.php;<br>
    # &nbsp; &nbsp;include &nbsp; &nbsp; &nbsp; &nbsp;fastcgi_params;<br>
    # &nbsp; &nbsp;fastcgi_param &nbsp;SCRIPT_FILENAME &nbsp;$document_root$fastcgi_script_name;<br>
    # &nbsp; &nbsp;fastcgi_param &nbsp;PATH_INFO $fastcgi_path_info;<br>
    # &nbsp; &nbsp;fastcgi_pass &nbsp; php-fpm;<br>
    #}</p>
    </div>

    <p style="display: none;">
    <em>* в данном примере мы отключили обработку всех php-файлов с помощью php-fpm, так как это у нас должен делать apache.</em>
    </p>

    <p style="display: none;">Проверяем и перезапускаем nginx:</p>

    <div class="console">
    <p>nginx -t</p>
    </div>

    <div class="console">
    <p>systemctl restart nginx</p>
    </div>

    <p style="display: none;">Пробуем снова открыть в браузере адрес <u>http://&lt;IP-адрес нашего сервера</u>&gt; (уже без 8080) — должна открыться та же страница, что при проверке Apache (с добавлением 8080):</p>

    <p style="display: none;">
    <img alt="Страницу с phpinfo загрузил Apache" src="https://www.dmosk.ru/img/instruktions/centos-mega-webserver-10.jpg" style="width: 494px; height: 95px;" title="Страницу с phpinfo загрузил Apache">
    </p>

    <h3>Apache Real IP</h3>

    <p style="display: none;">Так как все запросы на httpd приходят от NGINX, они воспринимаются как от IP-адреса 127.0.0.1. На практике, это может привести к проблемам, так как некоторым сайтам необходимы реальные адреса посетителей.</p>

    <p style="display: none;">Для решения проблемы будем использовать модуль&nbsp;mod_rpaf. Устанавливаем набор разработчика для apache:</p>

    <div class="console">
    <p>dnf install httpd-devel gcc unzip&nbsp;redhat-rpm-config</p>
    </div>

    <p style="display: none;">Переходим в каталог&nbsp;/usr/local/src:</p>

    <div class="console">
    <p>cd /usr/local/src</p>
    </div>

    <p style="display: none;">Скачиваем модуль:</p>

    <div class="console">
    <p>wget https://github.com/gnif/mod_rpaf/archive/stable.zip</p>
    </div>

    <p style="display: none;">Распаковываем его:</p>

    <div class="console">
    <p>unzip stable.zip</p>
    </div>

    <p style="display: none;">Переходим в распакованный каталог:</p>

    <div class="console">
    <p>cd mod_rpaf-stable/</p>
    </div>

    <p style="display: none;">Собираем модуль и устанавливаем его:</p>

    <div class="console">
    <p>make</p>
    </div>

    <div class="console">
    <p>make install</p>
    </div>

    <p style="display: none;">
    <em>* при возникновении ошибки&nbsp;<strong>./apxs.sh: line 15: -c: command not found</strong>, необходимо поставить <strong>which</strong> командой&nbsp;<strong>dnf install which</strong>.</em>
    </p>

    <p style="display: none;">Создаем конфигурационный файл со следующим содержимым:</p>

    <div class="console">
    <p>vi /etc/httpd/conf.d/mod_rpaf.conf</p>
    </div>

    <div class="editor">
    <p>LoadModule&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rpaf_module modules/mod_rpaf.so<br>
    RPAF_Enable&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; On<br>
    RPAF_ProxyIPs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 127.0.0.1<br>
    RPAF_SetHostName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;On<br>
    RPAF_SetHTTPS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; On<br>
    RPAF_SetPort&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;On<br>
    RPAF_ForbidIfNotProxy&nbsp;&nbsp; Off</p>
    </div>

    <p style="display: none;">Перезапускаем httpd:</p>

    <div class="console">
    <p>systemctl restart httpd</p>
    </div>

    <p style="display: none;">Для проверки открываем нашу страницу с phpinfo и&nbsp;находим $_SERVER['REMOTE_ADDR'] — его значение должно быть равно адресу компьютера, с которого мы открыли страницу:</p>

    <p style="display: none;">
    <img alt="Реальный IP-адрес при обращении к Apache" src="https://www.dmosk.ru/img/instruktions/centos-mega-webserver-11.jpg" style="width: 464px; height: 111px;" title="Реальный IP-адрес при обращении к Apache">
    </p>

    <h2>
    <a id="postfix">
    </a>Postfix</h2>

    <p style="display: none;">Устанавливаем postfix командой:</p>

    <div class="console">
    <p>dnf install postfix</p>
    </div>

    <p style="display: none;">Теперь нам необходимо сделать несколько простых настроек:</p>

    <div class="console">
    <p>vi /etc/postfix/main.cf</p>
    </div>

    <p style="display: none;">Редактируем:&nbsp;</p>

    <div class="editor">
    <p>...<br>
    myorigin = $mydomain<br>
    ...<br>
    inet_protocols = ipv4<br>
    ...</p>
    </div>

    <p style="display: none;">Добавляем:</p>

    <div class="editor">
    <p>smtp_generic_maps = hash:/etc/postfix/generic_map</p>
    </div>

    <p style="display: none;">
    <em>* <strong>myorigin</strong> — имя домена, которое будет подставляться всем отправляемым сообщениям без явного указания оного;&nbsp;<strong>inet_protocols</strong>&nbsp;— задает версию IP, с которой будет работать Postfix (если на нашем сервере используется&nbsp;ipv6,&nbsp;значение параметра стоит оставить <strong>all</strong>);&nbsp;<strong>smtp_generic_maps</strong>&nbsp;указывает на карту с общими правилами пересылки.&nbsp;</em>
    </p>

    <p style="display: none;">Открываем карту пересылки:</p>

    <div class="console">
    <p>vi&nbsp;/etc/postfix/generic_map</p>
    </div>

    <p style="display: none;">И добавляем:</p>

    <div class="editor">
    <p>@dmosk.local &nbsp; &nbsp;[email protected]</p>
    </div>

    <p style="display: none;">
    <em>* данной настройкой мы будем подставлять всем отправляемым письмам без поля FROM адрес&nbsp;<strong>[email protected]</strong>.</em>
    </p>

    <p style="display: none;">Создаем карту:</p>

    <div class="console">
    <p>postmap&nbsp;/etc/postfix/generic_map</p>
    </div>

    <p style="display: none;">Для применения настроек перезагружаем почтовый сервер:</p>

    <div class="console">
    <p>systemctl restart postfix</p>
    </div>

    <h2>
    <a id="tuning">
    </a>Тюнинг веб-сервера</h2>

    <h3>PHP</h3>

    <p style="display: none;">Открываем на редактирование следующий файл:</p>

    <div class="console">
    <p>vi /etc/php.ini</p>
    </div>

    <p style="display: none;">И правим следующее:</p>

    <div class="editor">
    <p>upload_max_filesize = 512M<br>
    ...<br>
    post_max_size = 512M<br>
    ...<br>
    short_open_tag = On<br>
    ...<br>
    date.timezone = "Europe/Moscow"</p>
    </div>

    <p style="display: none;">Перезапускаем php-fpm и httpd:</p>

    <div class="console">
    <p>systemctl restart php-fpm</p>
    </div>

    <div class="console">
    <p>systemctl restart httpd</p>
    </div>

    <h3>NGINX</h3>

    <p style="display: none;">Открываем на редактирование следующий файл:</p>

    <div class="console">
    <p>vi /etc/nginx/nginx.conf</p>
    </div>

    <p style="display: none;">И внутри секции http добавляем:</p>

    <div class="editor">
    <p>client_max_body_size 512M;</p>
    </div>

    <p style="display: none;">После перезапускаем nginx:</p>

    <div class="console">
    <p>systemctl restart nginx</p>
    </div>

    <p style="display: none;">Подробнее про тюнинг NGINX в статье&nbsp;<a href="/instruktions.php?object=kak-optimizirovat-veb-server-nginx">Практические советы по тюнингу веб-сервера NGINX</a>.</p>

    <h3>Postfix</h3>

    <p style="display: none;">Чтобы отправляемая почта меньше попадала в СПАМ, необходимо выполнить следующие шаги:</p>

    <ol style="display: none;">
    <li>Прописать <a href="/terminus.php?object=ptr">PTR-запись</a>.</li>
    <li>Создать <a href="/terminus.php?object=spf">запись SPF</a>.</li>
    <li>
    <a href="/instruktions.php?object=dkim-postfix">Настроить DKIM</a>.&nbsp;</li>
    </ol>

    <h2>
    <a id="firstsite">
    </a>Создание первого сайта</h2>

    <p style="display: none;">Задаем переменную, значение которой будет домен сайта:</p>

    <div class="console">
    <p>TMP_SITE=site1</p>
    </div>

    <p style="display: none;">
    <em>* где <strong>site1</strong> — имя домена. Нам будет намного удобнее копировать и вставлять команды с переменной (не придется править после копипасты).</em>
    </p>

    <p style="display: none;">Создаем новый файл виртуального домена NGINX:</p>

    <div class="console">
    <p>vi /etc/nginx/conf.d/$TMP_SITE.conf</p>
    </div>

    <p style="display: none;">
    <em>* обязательно на конце должен быть <strong>.conf</strong>, так как только такие файлы веб-сервер подгружает в конфигурацию.</em>
    </p>

    <p style="display: none;">И добавляем следующее содержимое.</p>

    <p style="display: none;">Для HTTP:</p>

    <div class="editor">
    <p>server {<br>
    &nbsp;&nbsp; &nbsp;listen &nbsp; &nbsp; &nbsp; 80;<br>
    &nbsp;&nbsp; &nbsp;server_name &nbsp;<strong>site1.local www.site1.local</strong>;<br>
    &nbsp;&nbsp; &nbsp;set $root_path /var/www/<strong>site1</strong>/www;<br>
    <br>
    &nbsp;&nbsp; &nbsp;access_log /var/www/<strong>site1</strong>/log/nginx/access_log;<br>
    &nbsp;&nbsp; &nbsp;error_log /var/www/<strong>site1</strong>/log/nginx/error_log;<br>
    &nbsp;&nbsp; &nbsp;<br>
    &nbsp;&nbsp; &nbsp;gzip &nbsp;on;<br>
    &nbsp;&nbsp; &nbsp;gzip_disable "msie6";<br>
    &nbsp;&nbsp; &nbsp;gzip_min_length 1000;<br>
    &nbsp;&nbsp; &nbsp;gzip_vary on;<br>
    &nbsp;&nbsp; &nbsp;gzip_proxied &nbsp; &nbsp;expired no-cache no-store private auth;<br>
    &nbsp;&nbsp; &nbsp;gzip_types &nbsp; &nbsp; &nbsp;text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;<br>
    <br>
    &nbsp; &nbsp;&nbsp;root &nbsp; $root_path;<br>
    <br>
    &nbsp;&nbsp; &nbsp;location / {<br>
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;proxy_pass http://127.0.0.1:8080/;<br>
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;proxy_redirect &nbsp; &nbsp; off;<br>
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;proxy_set_header &nbsp; Host &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $host;<br>
    &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;proxy_set_header&nbsp; &nbsp;X-Forwarded-Proto $scheme;<br>
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;proxy_set_header &nbsp; X-Real-IP &nbsp; &nbsp; &nbsp; &nbsp;$remote_addr;<br>
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;proxy_set_header &nbsp; X-Forwarded-For &nbsp;$proxy_add_x_forwarded_for;<br>
    &nbsp;&nbsp; &nbsp;}<br>
    &nbsp;&nbsp; &nbsp;<br>
    &nbsp;&nbsp; &nbsp;location ~* ^.+\.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|docx|xls|xlsx|exe|pdf|ppt|tar|wav|bmp|rtf|js)$ {<br>
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;expires&nbsp;modified&nbsp;+1w;<br>
    &nbsp;&nbsp; &nbsp;}<br>
    }</p>
    </div>

    <p style="display: none;">
    <em>* где&nbsp;<strong>site1.local</strong> — домен, для которого создается виртуальный домен;&nbsp;<strong>/var/www/site1</strong> — каталог, в котором будет размещаться сайт.<br>
    ** все запросы будут переводиться на локальный сервер, порт 8080, на котором работает apache, кроме обращений к статическим файла (jpg, png, css и так далее).<br>
    *** обратите внимание на выделения полужирным — здесь нужно подставить свои данные.</em>
    </p>

    <p style="display: none;">Для HTTPS:</p>

    <div class="editor">
    <p>server {<br>
    &nbsp;&nbsp; &nbsp;listen 80;<br>
    &nbsp;&nbsp; &nbsp;server_name <strong>site1.local www.site1.local</strong>;<br>
    &nbsp;&nbsp; &nbsp;return 301 https://$host$request_uri;<br>
    }<br>
    <br>
    server {<br>
    &nbsp;&nbsp; &nbsp;listen &nbsp; &nbsp; &nbsp; 443 ssl;<br>
    &nbsp; &nbsp; ssl on;<br>
    &nbsp; &nbsp; ssl_certificate /etc/nginx/ssl/cert.pem;<br>
    &nbsp; &nbsp; ssl_certificate_key /etc/nginx/ssl/cert.key;<br>
    <br>
    &nbsp;&nbsp; &nbsp;server_name &nbsp;<strong>site1.local www.site1.local</strong>;<br>
    &nbsp;&nbsp; &nbsp;set $root_path /var/www/<strong>site1</strong>/www;<br>
    <br>
    &nbsp;&nbsp; &nbsp;access_log /var/www/<strong>site1</strong>/log/nginx/access_log;<br>
    &nbsp;&nbsp; &nbsp;error_log /var/www/<strong>site1</strong>/log/nginx/error_log;<br>
    &nbsp;&nbsp; &nbsp;<br>
    &nbsp;&nbsp; &nbsp;gzip &nbsp;on;<br>
    &nbsp;&nbsp; &nbsp;gzip_disable "msie6";<br>
    &nbsp;&nbsp; &nbsp;gzip_min_length 1000;<br>
    &nbsp;&nbsp; &nbsp;gzip_vary on;<br>
    &nbsp;&nbsp; &nbsp;gzip_proxied &nbsp; &nbsp;expired no-cache no-store private auth;<br>
    &nbsp;&nbsp; &nbsp;gzip_types &nbsp; &nbsp; &nbsp;text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;<br>
    <br>
    &nbsp; &nbsp;&nbsp;root &nbsp; $root_path;<br>
    <br>
    &nbsp;&nbsp; &nbsp;location / {<br>
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;proxy_pass http://127.0.0.1:8080/;<br>
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;proxy_redirect &nbsp; &nbsp; off;<br>
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;proxy_set_header &nbsp; Host &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $host;<br>
    &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;proxy_set_header&nbsp; &nbsp;X-Forwarded-Proto $scheme;<br>
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;proxy_set_header &nbsp; X-Real-IP &nbsp; &nbsp; &nbsp; &nbsp;$remote_addr;<br>
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;proxy_set_header &nbsp; X-Forwarded-For &nbsp;$proxy_add_x_forwarded_for;<br>
    &nbsp;&nbsp; &nbsp;}<br>
    &nbsp;&nbsp; &nbsp;<br>
    &nbsp;&nbsp; &nbsp;location ~* ^.+\.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|docx|xls|xlsx|exe|pdf|ppt|tar|wav|bmp|rtf|js)$ {<br>
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;expires&nbsp;modified&nbsp;+1w;<br>
    &nbsp;&nbsp; &nbsp;}<br>
    }</p>
    </div>

    <p style="display: none;">
    <em>* в первой секции server мы перенаправляем все запросы по незащищенному <strong>http</strong> на <strong>https</strong>.<br>
    **&nbsp;<strong>ssl_certificate</strong> и&nbsp;<strong>ssl_certificate_key</strong> — пути к публичному и приватному ключам соответственно.<br>
    *** для получения бесплатного сертификата читайте статью&nbsp;<a href="/miniinstruktions.php?mini=get-letsencrypt">Получение бесплатного SSL сертификата Let's Encrypt</a>.</em>
    </p>

    <p style="display: none;">Теперь настроим&nbsp;виртуальный&nbsp;домен в Apache:</p>

    <div class="console">
    <p>vi /etc/httpd/conf.d/$TMP_SITE.conf</p>
    </div>

    <div class="editor">
    <p>&lt;VirtualHost *:8080&gt;<br>
    &nbsp;&nbsp; &nbsp;Define root_domain&nbsp;site1.local<br>
    &nbsp; &nbsp;&nbsp;Define root_path /var/www/site1<br>
    <br>
    &nbsp; &nbsp; ServerName ${root_domain}<br>
    &nbsp;&nbsp; &nbsp;ServerAlias www.${root_domain}<br>
    &nbsp;&nbsp; &nbsp;DocumentRoot ${root_path}/www<br>
    <br>
    &nbsp;&nbsp; &nbsp;ErrorLog &nbsp; &nbsp; ${root_path}/log/apache/error_log<br>
    &nbsp;&nbsp; &nbsp;TransferLog &nbsp;${root_path}/log/apache/access_log<br>
    &lt;/VirtualHost&gt;</p>
    </div>

    <p style="display: none;">Создаем каталоги для сайта:</p>

    <div class="console">
    <p>mkdir -p /var/www/$TMP_SITE/{www,tmp}</p>
    </div>

    <div class="console">
    <p>mkdir -p /var/www/$TMP_SITE/log/{nginx,apache}</p>
    </div>

    <p style="display: none;">Создаем индексный файл со следующим содержимым:</p>

    <div class="console">
    <p>vi&nbsp;/var/www/$TMP_SITE/www/index.php</p>
    </div>

    <div class="editor">
    <p>&lt;?php echo "&lt;h1&gt;Hello&nbsp;from site1&lt;/h1&gt;"; ?&gt;</p>
    </div>

    <p style="display: none;">Задаем права на папки:</p>

    <div class="console">
    <p>chown -R apache:apache&nbsp;/var/www/$TMP_SITE</p>
    </div>

    <div class="console">
    <p>chmod -R 775 /var/www/$TMP_SITE</p>
    </div>

    <p style="display: none;">Проверяем корректность настроек конфигурационных файлов:</p>

    <div class="console">
    <p>nginx -t</p>
    </div>

    <div class="console">
    <p>apachectl configtest</p>
    </div>

    <p style="display: none;">Перезапускаем веб-сервер:</p>

    <div class="console">
    <p>systemctl reload nginx</p>
    </div>

    <div class="console">
    <p>systemctl reload httpd</p>
    </div>

    <p style="display: none;">Открываем сайт в браузере.</p>

    <div class="note" style="display: none;">
    <p>Не забываем, что обращаться к сайту нужно по его доменному имени. Например, если мы создали сайт site1.local, то нужно в браузере набрать <u>http://site1.local</u>. При этом, данное имя должно разрешаться в IP-адрес с помощью DNS или локального файла hosts.</p>
    </div>

    <p style="display: none;">При необходимости, создаем базу данных.</p>

    <div class="console">
    <p>mysql -uroot -p</p>
    </div>

    <div class="console">
    <p>&gt;&nbsp;CREATE DATABASE site1 DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;</p>
    </div>

    <div class="console">
    <p>&gt;&nbsp;GRANT ALL PRIVILEGES ON site1.* TO dbuser@localhost&nbsp;IDENTIFIED BY 'password' WITH GRANT OPTION;</p>
    </div>

    <p style="display: none;">
    <em>* данными sql-командами мы создаем базу данных&nbsp;<strong>site1</strong> и предоставляем к ней доступ для учетной записи&nbsp;<strong>dbuser</strong> с паролем&nbsp;<strong>password</strong>. При желании сделать соединение более безопасным, можно убрать&nbsp;</em>
    <strong>WITH GRANT OPTION</strong>.</p>
    </div>
  3. numbnet created this gist Jun 13, 2021.
    472 changes: 472 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,472 @@
    NGINX + Apache (httpd) + MariaDB (MySQL) + PHP + PHP-FPM (fastCGI) + FTP + PHPMyAdmin + Memcached + Postfix на CentOS 8
    Описание
    Общая настройка системы
    Установка пакетов
    dnf update

    dnf install epel-release wget unzip

    Время
    \cp /usr/share/zoneinfo/Europe/Moscow /etc/localtime

    dnf install chrony

    systemctl enable chronyd

    systemctl start chronyd

    Настройка безопасности
    sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config

    setenforce 0

    firewall-cmd --permanent --add-port={80,443,8080}/tcp

    firewall-cmd --permanent --add-port={20,21,60000-65535}/tcp

    firewall-cmd --permanent --add-port={25,465,587}/tcp

    firewall-cmd --reload

    Установка NGINX
    dnf install nginx

    vi /etc/nginx/nginx.conf

    http {
    ...
    server_names_hash_bucket_size 64;
    ....
    }

    systemctl enable nginx

    systemctl start nginx

    Установка PHP и PHP-FPM
    dnf install php php-fpm

    systemctl enable php-fpm --now

    Настройка связки NGINX + PHP
    vi /etc/nginx/nginx.conf

    location / {
    index index.php index.html index.htm;
    }

    location ~ \.php$ {
    set $root_path /usr/share/nginx/html;
    fastcgi_pass unix:/run/php-fpm/www.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;
    include fastcgi_params;
    fastcgi_param DOCUMENT_ROOT $root_path;
    }

    vi /etc/php-fpm.d/www.conf

    listen = /run/php-fpm/www.sock

    systemctl restart php-fpm

    nginx -t

    systemctl restart nginx

    vi /usr/share/nginx/html/index.php

    <?php phpinfo(); ?>

    Установка MariaDB или MySQL
    dnf install mariadb mariadb-server

    systemctl enable mariadb --now

    mysqladmin -u root password

    PHP + MariaDB (MySQL)
    dnf install php-mysqli

    dnf install php-mysql

    systemctl restart php-fpm

    Установка phpMyAdmin
    wget https://files.phpmyadmin.net/phpMyAdmin/5.0.2/phpMyAdmin-5.0.2-all-languages.zip

    unzip phpMyAdmin-*-all-languages.zip

    mkdir /usr/share/phpMyAdmin

    mv phpMyAdmin-*-all-languages/* /usr/share/phpMyAdmin/

    chown -R apache:apache /usr/share/phpMyAdmin

    dnf install php-json php-mbstring php-mysqli

    head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo ''

    vi /usr/share/phpMyAdmin/config.inc.php

    <?php
    ...
    $cfg['blowfish_secret'] = 'jd7n6yIcHOl55ikE7l5HAdNaWwunSHvR';
    ?>

    vi /etc/nginx/conf.d/phpMyAdmin.conf

    server {
    listen 80;
    server_name phpmyadmin.dmosk.local;
    set $root_path /usr/share/phpMyAdmin;

    location / {
    root $root_path;
    index index.php;
    }

    location ~ \.php$ {
    fastcgi_pass unix:/run/php-fpm/www.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;
    include fastcgi_params;
    fastcgi_param DOCUMENT_ROOT $root_path;
    fastcgi_read_timeout 300;
    }
    }

    systemctl reload nginx

    systemctl restart php-fpm

    Установка Memcached
    Сервис memcached
    dnf install memcached libmemcached

    vi /etc/sysconfig/memcached

    PORT="11211"
    USER="memcached"
    MAXCONN="1024"
    CACHESIZE="512"
    OPTIONS="-l 127.0.0.1 -U 0"

    systemctl enable memcached --now

    Модуль для php
    wget http://pecl.php.net/get/memcached-3.1.5.tgz

    dnf install php-devel zlib-devel make

    dnf --enablerepo=PowerTools install libmemcached-devel

    tar -xvzf memcached-*.tgz

    cd memcached-*/

    phpize

    ./configure

    make

    cp modules/memcached.so /usr/lib64/php/modules/

    vi /etc/php.d/20-memcached.ini

    extension=memcached.so

    systemctl restart php-fpm

    php -m | grep memcached

    Установка и настройка FTP-сервера
    dnf install proftpd

    wget http://www.castaglia.org/proftpd/contrib/ftpasswd -P /etc/proftpd

    chmod +x /etc/proftpd/ftpasswd

    /etc/proftpd/ftpasswd --passwd --file=/etc/proftpd/ftpd.passwd --name=ftpwww --uid=48 --gid=48 --home=/var/www --shell=/sbin/nologin

    chmod 440 /etc/proftpd/ftpd.passwd

    vi /etc/proftpd.conf

    #AuthOrder ...

    vi /etc/proftpd/conf.d/custom.conf

    UseIPv6 off
    IdentLookups off
    PassivePorts 60000 65535

    RequireValidShell off
    AuthUserFile /etc/proftpd/ftpd.passwd
    AuthPAM off
    LoadModule mod_auth_file.c
    AuthOrder mod_auth_file.c

    systemctl enable proftpd --now

    Apache (httpd)
    dnf install httpd

    vi /etc/httpd/conf/httpd.conf

    Listen 8080

    <IfModule dir_module>
    DirectoryIndex index.php index.html
    </IfModule>

    <Directory /var/www/*/www>
    AllowOverride All
    Options Indexes ExecCGI FollowSymLinks
    Require all granted
    </Directory>

    apachectl configtest

    systemctl enable httpd

    systemctl start httpd

    vi /var/www/html/index.php

    <?php phpinfo(); ?>

    NGINX + Apache
    vi /etc/nginx/nginx.conf

    ...
    location ~ \.php$ {
    set $root_path /usr/share/nginx/html;
    fastcgi_pass unix:/run/php-fpm/www.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;
    include fastcgi_params;
    fastcgi_param DOCUMENT_ROOT $root_path;
    }
    ...

    ...
    location ~ \.php$ {
    proxy_pass http://127.0.0.1:8080;
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    ...

    vi /etc/nginx/default.d/php.conf

    #index index.php index.html index.htm;
    #
    #location ~ \.(php|phar)(/.*)?$ {
    # fastcgi_split_path_info ^(.+\.(?:php|phar))(/.*)$;
    #
    # fastcgi_intercept_errors on;
    # fastcgi_index index.php;
    # include fastcgi_params;
    # fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    # fastcgi_param PATH_INFO $fastcgi_path_info;
    # fastcgi_pass php-fpm;
    #}

    nginx -t

    systemctl restart nginx

    Apache Real IP
    dnf install httpd-devel gcc unzip redhat-rpm-config

    cd /usr/local/src

    wget https://github.com/gnif/mod_rpaf/archive/stable.zip

    unzip stable.zip

    cd mod_rpaf-stable/

    make

    make install

    vi /etc/httpd/conf.d/mod_rpaf.conf

    LoadModule rpaf_module modules/mod_rpaf.so
    RPAF_Enable On
    RPAF_ProxyIPs 127.0.0.1
    RPAF_SetHostName On
    RPAF_SetHTTPS On
    RPAF_SetPort On
    RPAF_ForbidIfNotProxy Off

    systemctl restart httpd

    Postfix
    dnf install postfix

    vi /etc/postfix/main.cf

    ...
    myorigin = $mydomain
    ...
    inet_protocols = ipv4
    ...

    smtp_generic_maps = hash:/etc/postfix/generic_map

    vi /etc/postfix/generic_map

    @dmosk.local [email protected]

    postmap /etc/postfix/generic_map

    systemctl restart postfix

    Тюнинг веб-сервера
    PHP
    vi /etc/php.ini

    upload_max_filesize = 512M
    ...
    post_max_size = 512M
    ...
    short_open_tag = On
    ...
    date.timezone = "Europe/Moscow"

    systemctl restart php-fpm

    systemctl restart httpd

    NGINX
    vi /etc/nginx/nginx.conf

    client_max_body_size 512M;

    systemctl restart nginx

    Postfix
    Создание первого сайта
    TMP_SITE=site1

    vi /etc/nginx/conf.d/$TMP_SITE.conf

    server {
    listen 80;
    server_name site1.local www.site1.local;
    set $root_path /var/www/site1/www;

    access_log /var/www/site1/log/nginx/access_log;
    error_log /var/www/site1/log/nginx/error_log;

    gzip on;
    gzip_disable "msie6";
    gzip_min_length 1000;
    gzip_vary on;
    gzip_proxied expired no-cache no-store private auth;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;

    root $root_path;

    location / {
    proxy_pass http://127.0.0.1:8080/;
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location ~* ^.+\.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|docx|xls|xlsx|exe|pdf|ppt|tar|wav|bmp|rtf|js)$ {
    expires modified +1w;
    }
    }

    server {
    listen 80;
    server_name site1.local www.site1.local;
    return 301 https://$host$request_uri;
    }

    server {
    listen 443 ssl;
    ssl on;
    ssl_certificate /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/cert.key;

    server_name site1.local www.site1.local;
    set $root_path /var/www/site1/www;

    access_log /var/www/site1/log/nginx/access_log;
    error_log /var/www/site1/log/nginx/error_log;

    gzip on;
    gzip_disable "msie6";
    gzip_min_length 1000;
    gzip_vary on;
    gzip_proxied expired no-cache no-store private auth;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;

    root $root_path;

    location / {
    proxy_pass http://127.0.0.1:8080/;
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location ~* ^.+\.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|docx|xls|xlsx|exe|pdf|ppt|tar|wav|bmp|rtf|js)$ {
    expires modified +1w;
    }
    }

    vi /etc/httpd/conf.d/$TMP_SITE.conf

    <VirtualHost *:8080>
    Define root_domain site1.local
    Define root_path /var/www/site1

    ServerName ${root_domain}
    ServerAlias www.${root_domain}
    DocumentRoot ${root_path}/www

    ErrorLog ${root_path}/log/apache/error_log
    TransferLog ${root_path}/log/apache/access_log
    </VirtualHost>

    mkdir -p /var/www/$TMP_SITE/{www,tmp}

    mkdir -p /var/www/$TMP_SITE/log/{nginx,apache}

    vi /var/www/$TMP_SITE/www/index.php

    <?php echo "<h1>Hello from site1</h1>"; ?>

    chown -R apache:apache /var/www/$TMP_SITE

    chmod -R 775 /var/www/$TMP_SITE

    nginx -t

    apachectl configtest

    systemctl reload nginx

    systemctl reload httpd

    mysql -uroot -p

    > CREATE DATABASE site1 DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
    > GRANT ALL PRIVILEGES ON site1.* TO dbuser@localhost IDENTIFIED BY 'password' WITH GRANT OPTION;