Мы — долго запрягаем, быстро ездим, и сильно тормозим.
www.lissyara.su —> статьи —> FreeBSD —> программы —> Apache, PHP, nginx, MySQL/phpMyAdmin, PostgreSQL/phpPgAdmin

Установка Apache, PHP, nginx, MySQL/phpMyAdmin и PostgreSQL/phpPgAdmin

Автор: Fomalhaut.


Заметка сделана для себя (вечно какая-то важная мелочь забывается :) и молодого коллеги, дабы давать на изучение и приучение к FreeBSD/Linux. :)
Описываемое актуально для FreeBSD 11.x / Scientific Linux 7.x (далее - SL7), Apache 2.4 / nginx 1.10, MySQL 5.7 / PostgreSQL 9.6, PHP 7.0 и phpMyAdmin 4.6 / phpPgAdmin 5.1 (изначально писалось под более старые версии, но вот руки добрались переработать). Не проверял, но уверен, что всё или почти всё, описанное для MySQL, подойдёт и для MariaDB 10.0/10.1.

ОГЛАВЛЕНИЕ

Установка ПО
Настройка ПО

  • PHP
  • PHP-FPM
  • Apache
  • Nginx
  •   1) Базовая настройка
  •   2) Настройка HTTPS
  •   3) Ограничение доступа паролем
  •   4) Работа с модулями
  • MySQL + phpMyAdmin
  • PostgreSQL + phpPgAdmin
    Последние штрихи
    МЕЛОЧИ
  • Мелочь №1: Сброс забытого пароля пользователя root для MySQL
  • Мелочь №2: Кодировка в Apache
  • Мелочь №3: Перекодирование текста в БД
  • Мелочь №4: Nginx: 503 ошибка, в его логах upstream sent too big header while reading response header from upstream
  • Мелочь №5: Встроенные переменные Nginx
    Настройка 2-х узлового кластера PostgreSQL 11 в синхронном режиме master-slave с потоковой репликацией данных и кластерным IP
    Настройка Apache Kafka

    Установка ПО

    1) ------------— Apache:
    Установка - штатно:
    ### для системы с FreeBSD
    $ cd /usr/ports/www/apache24
    $ make config && make install clean
    ### для системы с SL7
    $ yum install httpd
    

    Для автозапуска:
    1) в случае FreeBSD: в файл /etc/rc.conf прописываем:
    apache24_enable="YES"
    

    а в файл конфигурации загрузчика /boot/loader.conf добавляем строку:
    accf_http_load="YES"
    

    2) в случае SL7:
    $ systemctl enable httpd
    

    Больше пока ничего не делаем.

    2) ------------— nginx
    ### для системы с FreeBSD
    $ cd /usr/ports/www/nginx
    $ make config && make install clean
    ### для системы с SL7
    $ yum install nginx
    


    При необходимости/желании использовать nginx, собранный его разработчиками, воспользуемся их репозиториями.
    Создадим repo-файл /etc/yum.repos.d/nginx.repo такого содержания:
    [nginx]
    name=nginx repo
    baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
    enabled=1
    gpgcheck=1
    gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-nginx
    

    Импортируем ключи для проверки пакетов:
    $ wget https://nginx.org/keys/nginx_signing.key -O /etc/pki/rpm-gpg/RPM-GPG-KEY-nginx
    $ rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-nginx
    

    Перед установкой обновляем кэш метаданных:
    $ yum clean all && yum makecache
    

    Установка/обновление проводятся штатно.



    Для автозапуска:
    1) в случае FreeBSD: в файл /etc/rc.conf прописываем:
    nginx_enable="YES"
    

    2) в случае SL7:
    $ systemctl enable nginx
    

    Больше пока ничего не делаем.

    3) ------------— PHP
    С FreeBSD всё проще: в портах и пакетах есть уже версия 7.0. PHP ставится двумя пакетами: базовый пакет - php70, пакет с дополнениями - php70-extensions. При сборке php70 для Apache можно ставить "по умолчанию" или выбрать какие-либо необходимые параметры, а для nginx обязательно указываем поддержку FPM:
    [x] FPM      Build FPM version
    

    При сборке php70-extensions для обоих web-серверов указываем поддержку выбранной СУБД:
    # для поддержки PostgreSQL
    [x] PGSQL         PostgreSQL database support
    # для поддержки MySQL / MariaDB
    [x] MYSQLI        MySQLi database support
    

    Ну и сама установка:
    # основные пакеты
    $ cd /usr/ports/lang/php70
    $ make config && make install clean
    $ cd /usr/ports/lang/php70-extensions
    $ make config && make install clean
    

    В случае с SL7 всё сложней: на момент написания в официальных репозиториях нет версии 7.0, поэтому воспользуемся сторонними. Например:
    а) IUS Community Project
    $ yum install https://centos7.iuscommunity.org/ius-release.rpm
    $ rpm --import /etc/pki/rpm-gpg/IUS-COMMUNITY-GPG-KEY
    

    б) Webtatic
    $ yum install https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
    

    Здесь и в дальнейшем будем всё делать на основе сборок IUS Community Project:
    $ yum install php70u php70u-fpm-nginx php70u-cli
    

    Больше пока ничего не делаем.

    4) ------------— MySQL
    -== FreeBSD ==-
    Устанавливаем MySQL:
    $ cd /usr/ports/databases/mysql57-server/
    $ make config && make install clean
    

    Создаём необходимые системные таблицы и устанавливаем права:
    $ /usr/local/bin/mysql_install_db
    $ chown -R mysql:mysql /var/db/mysql
    

    Создаём файл логов и права на него:
    $ touch /var/log/mysql.log
    $ chown mysql:mysql /var/log/mysql.log
    

    Добавляем в /etc/rc.conf строку автозапуска:
    mysql_enable="YES"
    

    Запускам сервер MySQL:
    $ /usr/local/etc/rc.d/mysql-server start
    

    Задаём пароль администратора и делаем необходимые настройки безопасности (на более старых версиях MySQL для этого приходилось ставить отдельно порт скриптов, например, /usr/ports/databases/mysql51-scripts/):
    $ cd /usr/local/ # (или /usr/local/bin)
    $ mysql_secure_installation
    

    Больше пока ничего не делаем.

    5) ------------— PostgreSQL

    6) ------------— phpMyAdmin
    Поддержку MySQL в PHP в FreeBSD мы установили, когда устанавливали php70-extensions, поэтому теперь описываем установку соотв. пакетов для SL7:
    $ yum install php70u-mysqlng
    

    Устанавливаем непосредственно phpMyAdmin:
    # для системы с FreeBSD
    $ cd /usr/ports/databases/phpmyadmin/
    $ make install clean
    # для системы с SL7
    $ yum install phpmyadmin
    

    Установка закончена.

    7) ------------— phpPgAdmin
    Поддержку PostgreSQL в PHP в FreeBSD мы установили, когда устанавливали php70-extensions, поэтому теперь описываем установку соотв. пакетов для SL7:
    $ yum install php70u-pgsql
    

    Устанавливаем непосредственно phpPgAdmin:
    # для системы с FreeBSD
    $ cd /usr/ports/databases/phppgadmin/
    $ make install clean
    # для системы с SL7
    $ yum install phppgadmin
    

    Установка закончена.

    Настройка ПО

    PHP

    После установки создадим файл конфигурации php.ini на основе шаблона, удалив комментарии:
    # для системы с FreeBSD
    $ cd /usr/local/etc/
    $ cat php.ini-production | grep -v ";" |  sed '/./!d' > php.ini
    # для системы с SL7
    $ cd /etc/
    $ cp php.ini php-ini-0
    $ cat php.ini-0 | grep -v ";" |  sed '/./!d' > php.ini
    

    и добавим в него в блок [Date] параметр временной зоны:
    [Date]
    date.timezone = Europe/Moscow
    

    И проверяем в блоке [PHP] установку кодировки "по умолчанию":
    [PHP]
    default_charset = "UTF-8"
    

    Базовая настройка PHP завершена.

    PHP-FPM

    FPM необходим для работы nginx (Apache умеет работать напрямую: об этом в его настройке ниже), хотя и Apache может использовать. Но рассматриваем здесь PHP-FPM именно в связке с nginx.
    Создадим файлы конфигураций на основе шаблонов, удалив комментарии:
    # для системы с FreeBSD
    $ cd /usr/local/etc
    $ cat php-fpm.conf.default | grep -v ";" |  sed '/./!d' > php-fpm.conf
    $ cat php-fpm.d/www.conf.default | grep -v ";" |  sed '/./!d' > php-fpm.d/www.conf
    # для системы с SL7
    $ cd /etc/
    $ cp php-fpm.conf php-fpm.conf-0
    $ cat php-fpm.conf-0 | grep -v ";" |  sed '/./!d' > php-fpm.conf
    $ cp php-fpm.d/www.conf php-fpm.d/www.conf-0
    $ cat php-fpm.d/www.conf-0 | grep -v ";" |  sed '/./!d' > php-fpm.d/www.conf
    

    Теперь вносим коррективы, чтобы получить следующее (указаны только основные параметры):
    1) файл php-fpm.conf:
    # для системы с FreeBSD - в /usr/local/etc/
    include=/usr/local/etc/php-fpm.d/*.conf
    
    [global]                                
    pid = /var/run/php-fpm.pid
    error_log = /var/log/php-fpm/error.log
    daemonize = yes
    # для системы с SL7 - в /etc/
    include=/etc/php-fpm.d/*.conf
    
    [global]
    pid = /run/php-fpm/php-fpm.pid
    error_log = /var/log/php-fpm/error.log
    daemonize = yes
    

    2) файл www.conf (по умолчанию прослушивается TCP-сокет 127.0.0.1:9000, но unix-сокет более быстрый):
    # для системы с FreeBSD - в /usr/local/etc/php-fpm.d/
    [www]
    user = www
    group = www
    listen = /tmp/php-fpm.sock
    listen.backlog = -1
    listen.owner = www
    listen.group = www
    ; отключаем параметр
    ;listen.mode = 0660
    
    ping.path = /ping
    pm.status_path = /status
    pm = dynamic
    pm.max_children = 5
    pm.start_servers = 2
    pm.min_spare_servers = 1
    pm.max_spare_servers = 3
    pm.max_requests = 0
    
    slowlog = /var/log/php-fpm/www-slow.log
    php_admin_value[error_log] = /var/log/php-fpm/www-error.log
    php_admin_flag[log_errors] = on
    php_value[session.save_handler] = files
    php_admin_value[output_buffering] = Off
    
    # для системы с SL7 - в /etc/php-fpm.d/
    [www]
    user = nginx
    group = nginx
    listen = /var/run/php-fpm.sock
    listen.backlog = -1
    listen.owner = nginx
    listen.group = nginx
    listen.mode = 0660
    
    ping.path = /ping
    pm.status_path = /status
    pm = dynamic
    pm.max_children = 5
    pm.start_servers = 2
    pm.min_spare_servers = 1
    pm.max_spare_servers = 3
    pm.max_requests = 0
    
    env[HOSTNAME] = $HOSTNAME
    env[PATH] = /usr/local/bin:/usr/bin:/bin
    env[TMP] = /tmp
    env[TMPDIR] = /tmp
    env[TEMP] = /tmp
    
    slowlog = /var/log/php-fpm/www-slow.log
    php_admin_value[error_log] = /var/log/php-fpm/www-error.log
    php_admin_flag[log_errors] = on
    php_value[session.save_handler] = files
    php_admin_value[output_buffering] = Off
    

    Указанные в файле www.conf пользователь и группа должны существовать в системе. Обычно они создаются при установке соответствующего web-сервера:
    - FreeBSD: www:www при установке и Nginx и Apache;
    - SL7: nginx:nginx при установке Nginx; apache:apache - при установке Apache.
    Проверяем файлы конфигураций PHP-FPM на ошибки:
    $ php-fpm -t
    [04-Dec-2016 11:41:45] NOTICE: configuration file /usr/local/etc/www.conf test is successful
    

    Если всё в норме (т.е. successful, как в примере) - прописываем в автозапуск и запускаем:
    1) в случае FreeBSD - в файл /etc/rc.conf добавляем:
    php_fpm_enable="YES"
    

    И запускаем:
    $ service php-fpm start
    

    2) в случае SL7:
    $ systemctl enable php-fpm
    $ systemctl start php-fpm
    

    Проверяем наличие в системе активных unix-сокетов:
    ### для системы с FreeBSD
    $ sockstat | grep php-fpm
    www      php-fpm    674 0  stream /tmp/www.sock
    root     php-fpm    673 4  stream -> ??
    root     php-fpm    673 8  stream /tmp/www.sock
    ### для системы с SL7
    $ ss -a | grep php-fpm
    u_str  LISTEN     0      128    /var/run/www.sock 29311                 * 0
    

    Если всё это высветилось, значит PHP-FPM мы успешно настроили и запустили.

    Apache

    В конфигурационный файл (/usr/local/etc/apache24/httpd.conf для FreeBSD и /etc/httpd/conf/httpd.conf для SL7) прописываем имя сервера и адрес админа:
    ...
    ServerAdmin admin@mydomain.su
    ...
    ServerName mysite.domain.tld:80
    ...
    

    Запускаем наш Apache:
    ### для системы с FreeBSD
    # апачевской управлялкой
    $ apachectl start
    # системной утилитой
    $ service apache24 start
    ### для системы с SL7
    $ systemctl start httpd
    

    При запуске файл конфигурации проверяется на ошибки:
    # для FreeBSD
    $ service apache24 start
    Performing sanity check on apache24 configuration:
    Syntax OK
    Starting apache24.
    

    До версии PHP 5.4.27 модуль сопряжения входил в базовый пакет PHP и для включения поддержки достаточно было в конфиге Apache 2.2 указать две строчки в /usr/local/etc/apache22/httpd.conf в блоке <IfModule mime_module>:
    <IfModule mime_module>
    ...
    	AddType application/x-httpd-php .php
    	AddType application/x-httpd-php-source .phps
    ...
    <IfModule mime_module>
    

    В установленной версии PHP 7.0 для обеспечения поддержки PHP в Apache необходимо первоначально установить модуль сопряжения, выделенный в отдельное приложение:
    ### для системы с FreeBSD
    $ cd /usr/ports/www/mod_php70
    $ make config && make install clean
    ### для системы с SL7
    $ yum install mod_php70u
    

    По окончании установки на экран будет выведена информация по необходимым параметрам, которые необходимо прописать в конфиг Apache. Сделаем, как указано: добавим в конфигурационный файл httpd.conf в блоке <IfModule mime_module>:
    <IfModule mime_module>
    ...
    	<FilesMatch "\.php$">
    		SetHandler application/x-httpd-php
    	</FilesMatch>
    	<FilesMatch "\.phps$">
    		SetHandler application/x-httpd-php-source
    	</FilesMatch>
    ...
    <IfModule mime_module>
    

    Для проверки работы Apache в связке с PHP создаём конфигурационный файл тестового сайта (/usr/local/etc/apache24/Includes/test.conf - для FreeBSD, /etc/httpd/conf/Includes/test.conf для SL7), куда добавляем параметр DirectoryIndex в блок <Directory />, чтобы получилось следующее (подробней о настройке прав доступа здесь и здесь) и не забываем добавить IP или имя своего узла в соответствующий параметр Require:
    <Directory />
    	DirectoryIndex index.php index.html
    ###=-- Права доступа
    ### до версии 2.4
    	AllowOverride None
    	Order deny,allow
    	Deny from all
    ### с версии 2.4
    ### по IP адресу
    	Require ip 192.168.1.4/24 192.168.2.43
    ### по имени
    	Require host mycomp.domain.zone
    # сложные, совмещённые разных типов
    	<RequireAll>
    		Require group alpha beta
    		Require not group reject
    	</RequireAll>
    </Directory>
    

    Перезапустим Apache:
    $ apachectl restart
    

    Для проверки нормальных подключения и работы модуля поддержки PHP можно открыть в браузере по ссылке http://xxx.xxx.xxx.xxx/index.php предварительно созданный файл /usr/local/www/apache24/data/index.php следующего содержания:
    <?php
    	phpinfo( );
    ?>
    

    Если всё сделано правильно - в браузере увидим информацию по PHP.

    Nginx

    1) Базовая настройка

    Готовим шаблон конфигурации:
    ### для системы с FreeBSD
    $ cd /usr/local/etc
    $ mv nginx/nginx.conf nginx/nginx.conf-0
    $ cat nginx/nginx.conf-0 | grep -v "#" |  sed '/./!d' > nginx/nginx.conf
    ### для системы с SL7
    $ cd /etc
    $ mv nginx/nginx.conf nginx/nginx.conf-0
    $ cat nginx/nginx.conf-0 | grep -v "#" |  sed '/./!d' > nginx/nginx.conf
    

    Сделаем конфигурационный файл nginx-а модульным: для удобства конфигурирования:
    Основной файл конфигурации (nginx.conf) приводим к виду (пример для SL7: для FreeBSD надо адаптировать данный файл):
    include                 /usr/share/nginx/modules/*.conf;
    
    user                    nginx;
    pid                     /run/nginx.pid;
    worker_processes        1;
    ###=-- Обработка событий
    error_log               /var/log/nginx/error.log;
    # access_log            /var/log/nginx/access.log  main;
    events {
        worker_connections  1024;
    }
    
    http {
        log_format          main '$remote_addr - $remote_user [$time_local] "$request" '
                            '$status $body_bytes_sent "$http_referer" '
                            '"$http_user_agent" "$http_x_forwarded_for"';
        sendfile            on;
        tcp_nopush          on;
        tcp_nodelay         on;
        keepalive_timeout   65;
        types_hash_max_size 2048;
        server_tokens       off;
        charset             utf-8;
        include             /etc/nginx/mime.types;
        default_type        application/octet-stream;
        upstream mysite-php {
            # server        127.0.0.1:9000;
            server          unix:/var/run/php-fpm.sock;
        }
    #    include            /etc/nginx/conf.d/*.conf;
        include             /etc/nginx/server.d/*.conf;
    }
    

    Создаём каталог, где будут находиться конфигурационные файлы отдельных сайтов и файл сайта в нём:
    $ mkdir /etc/nginx/server.d/
    $ touch /etc/nginx/server.d/mysite.conf
    

    При приводим файл конфигурации /etc/nginx/server.d/mysite.conf нашего сайта к виду (при необходимости вносим изменения):
        server {
            listen          80;
    #       resolver                127.0.0.1;
            set             $basepath "/usr/share/nginx/html";
    #       include         /etc/nginx/default.d/*.conf;
    ###=-- Все ссылки заканчивать "/": ссылка без слеша будет перенаправляться на ссылку со слешем
            rewrite         ^([^.]*[^/])$ $1/ permanent;
    ###=-- Перенаправление ссылки с индексных файлов (index.php, index.html) на URL без них
            if ($request_uri ~* index.(php|html)) {
                rewrite ^(.+)index.php $scheme://$host$1 permanent;
            }
    ###=-- Разбор имени узла из строки запроса, формирование пути к файлам сайта
    ###=-- и 404, если такового нет (нет каталога, содержащего файлы запрашиваемого сайта)
            server_name     mysite.domain.tld www.mysite.domain.tld;
            set             $rootpath "${basepath}/mysite.domain.tld";
            if (!-d $rootpath/) {
                return      404;
            }
    ###=-- Обработка событий
            error_page 404 /404.html;
            location = /40x.html {
            }
            error_page 500 502 503 504 /50x.html;
            location = /50x.html {
                root        /usr/share/nginx/html;
            }
    ###=-- Установка базовой конфигурации
            location / {
                index       index.php;
                root        $rootpath/;
                try_files   $uri $uri/ =404;
            }
            location = /favicon.ico {
                access_log          off;
                log_not_found       off;
            }
            location = /robots.txt {
                access_log          off;
                log_not_found       off;
            }
    ###=-- Обработка PHP скриптов
            location ~ \.php$ {
                fastcgi_split_path_info     ^(.+\.php)(/.+)$;
                fastcgi_index               index.php;
    #            fastcgi_pass                unix:/var/run/php-fpm.sock;
                fastcgi_pass                mysite-php;
                include                     fastcgi_params;
                fastcgi_buffers             4       256k;
                fastcgi_buffer_size         128k;
                fastcgi_intercept_errors    on;
                fastcgi_ignore_client_abort off;
                fastcgi_connect_timeout     60;
                fastcgi_send_timeout        180;
                fastcgi_read_timeout        180;
                fastcgi_busy_buffers_size   256k;
                fastcgi_temp_file_write_size        256k;
            }
        }
    

    Проверяем параметры поддержки PHP в файле /etc/nginx/fastcgi_params. Можно оставить "умолчальные", но для себя я немного поправил.
    Сначала сохраним копию "умолчальных" параметров:
    $ mv nginx/fastcgi_params nginx/fastcgi_params-0
    $ cat nginx/fastcgi_params-0 | grep -v "#" |  sed '/./!d' > nginx/fastcgi_params
    

    А теперь приведём файл в такому виду:
    fastcgi_param   DOCUMENT_ROOT           $rootpath/;
    fastcgi_param   SCRIPT_FILENAME         $rootpath/$fastcgi_script_name;
    fastcgi_param   PATH_TRANSLATED         $rootpath/$fastcgi_script_name;
    fastcgi_param   PATH_INFO               $fastcgi_path_info;
    fastcgi_param   QUERY_STRING            $query_string;
    fastcgi_param   REQUEST_METHOD          $request_method;
    fastcgi_param   CONTENT_TYPE            $content_type;
    fastcgi_param   CONTENT_LENGTH          $content_length;
    

    Базовая настройка nginx завершена.
    Проверяем конфигурацию:
    $ nginx -t
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful

    И запускаем nginx, если явных ошибок нет:
    $ systemctl start nginx
    

    Для проверки нормальных подключения к nginx и работы модуля поддержки PHP создаём файл /usr/share/nginx/html/mysite.domain.tld/index.php следующего содержания:
    <?php
    	phpinfo( );
    ?>
    

    Проверяем работоспособность подключением к нашему сайту по адресу:
    http://mysite.domain.tld/index.php
    # или
    http://www.mysite.domain.tld/index.php
    

    Дополнительная информация:
    1 - официальная документация;
    2 - Встроенные переменные nginx;
    3 - Name-based virtual hosting with Nginx (динамическое создание сайтов в Nginx);
    4 - FreeBSD - Настройка Nginx + PHP-FPM в chroot;
    5 - Веб-сервер на основе Nginx и PHP-FPM.

    2) Настройка HTTPS (на примере SL7)

        Запрос сертификата Let's Encrypt
    Для запроса сертификата достаточно установить утилиту поддержки certbot:
    $ yum install certbot
    

    Запускаем генерацию сертификатов:
    # для одного сайта
    certbot certonly --webroot -w /usr/share/nginx/html/mysite.domain.tld -d mysite.domain.tld -m admin@domain.tld
    # для двух сайтов
    certbot certonly --webroot -w /usr/share/nginx/html/mysite1.domain.tld -d mysite1.domain.tld \
                     -w /usr/share/nginx/html/mysite2.domain.tld -d mysite2.domain.tld -m admin@domain.tld
    

    и следуем указаниям.
    Если всё нормально, то в каталоге /etc/letsencrypt/live появятся файлы ключей (точнее - ссылки на них, а сами файлы будут в /etc/letsencrypt/archive).

        Продление сертификатов
    Let's Encrypt выдаёт сертификаты на 3 месяца. Т.е. как минимум четырежды в год надо запрашивать обновление сертификата. Естественно, это лучше делать с помощью cron. Но предварительно надо проверить, что всё нормально:
    # Тестовое подключение
    $ certbot renew --dry-run
    # Непосредственно обновление
    $ certbot renew
    

    Если всё нормально, то настроим соответственно cron:
    $ crontab -e
    30 2 * * 1 certbot renew --quiet >> /var/log/certbot-renew.log && systemctl restart nginx
    

        Настройка nginx на поддержку HTTPS
    Меняем файл конфигурации сайта, добавив в него соответствующие строки:
        server {
           listen          80;
           server_name     site.domain.tld www.site.domain.tld;
           return          301 https://$host$request_uri;
        }
    
        server {
           listen          443 ssl http2;
    ###=-- Если этот параметр включить, то будут проблемы с обновлением сертификатов
    #       ssl             on;
    
    ###=-- Поддержка браузеров
            ssl_protocols           TLSv1 TLSv1.1 TLSv1.2;
    ###=-- только современных
    #       ssl_ciphers             kEECDH+AES128:kEECDH:kEDH:kRSA+AES128:!EXPORT:!LOW:!SEED:!aNULL:!eNULL:\
    #                               !MD5:!SHA1:!3DES:!RC4:!IDEA:!DSS:!PSK:!SRP:!SSLv2:!SSLv3;
    ###=-- старых...
    #       ssl_ciphers             ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES265-SHA:\
    #                               EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:\
    #                               EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:RC4:\
    #                               kEECDH+AES128:kEECDH:kEDH:kRSA+AES128:!kEDH+3DES:!DES-CBC3-SHA:!RC4:\
    #                               !aNULL:!eNULL:!MD5:!EXPORT:!LOW:!SEED:!IDEA:!PSK:!SRP:!SSLv2:!DSS:!3DES;
    ###=-- ..., кроме в Android 2.3
            ssl_ciphers             kEECDH:kEDH:kRSA+AES128:!EXPORT:!LOW:!SEED:!aNULL:!eNULL:!MD5:!3DES:!RC4:\
                                    !IDEA:!DSS:!PSK:!SRP:!SSLv2;
    
            ssl_certificate         /etc/letsencrypt/live/site.domain.tld/fullchain.pem;
            ssl_certificate_key     /etc/letsencrypt/live/site.domain.tld/privkey.pem;
            ssl_trusted_certificate /etc/letsencrypt/live/site.domain.tld/chain.pem;
            ssl_dhparam             /etc/pki/nginx/dhparam.pem;
            ssl_prefer_server_ciphers       on;
            ssl_session_cache       shared:SSL:10m;
            ssl_session_timeout     10m;
    ###=-- OCSP stapling: прикрепляем OCSP-ответы, уменьшая время загрузки страниц у пользователей
            ssl_stapling            on;
            ssl_stapling_verify     on;
            resolver                127.0.0.1;
            add_header              Strict-Transport-Security max-age=15768000;
    [...]
        }
    

    Генерируем файл параметров DH:
    $ openssl dhparam -out /etc/pki/nginx/dhparam.pem 4096
    

    Проверяем конфигурацию:
    $ nginx -t
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful

    И перезапускаем nginx, если явных ошибок нет:
    $ systemctl restart nginx
    

    Для OCSP stapling нужен кеширующий DNS сервер (в nginx.conf параметр resolver). Наиболее простой вариант - установить dnsmasq и настроить его:
    # Устанавливаем
    $ yum install dnsmasq
    # Создаём конфигурационный файл
    $ tee /etc/dnsmasq.d/localhost <<EOF
    listen-address=127.0.0.1
    bind-interfaces
    EOF
    

    Проверяем конфигурацию
    $ dnsmasq --test
    dnsmasq: syntax check OK.

    и запускаем его:
    $ systemctl enable dnsmasq
    $ systemctl start dnsmasq
    $ dig +short site.domain.tld @localhost
    

    Для проверки настройки поддержки HTTPS в nginx подключаемся к нашему сайту по адресу:
    https://mysite.domain.tld/index.php
    # или
    https://www.mysite.domain.tld/index.php
    

    Если всё нормально открылось, то проверяем безопасность настроек HTTPS двумя сервисами (первые две ссылки в "Дополнительная информация"). Хорошая конфигурация даст результат - A+ (зелёный).
    Можно провести проверку цепочки сертификатов:
    $ openssl s_client -connect mysite.domain.tld:443
    

    Так же можно проверить настройки безопасности:
    - по ниже приведённым ссылкам на профильные сайты;
    - используя сканер безопасности nmap:
    $ nmap --script ssl-enum-ciphers -p 443 <server_name_/_server_IP>
    

    Дополнительная информация:
    1 - Проверка настройки HTTPS;
    2 - Проверка безопасности HTTPS;
    3 - CertBot;
    4 - Соответствие наименований алгоритмов в OpenSSL и RFC.

    3) Ограничение доступа паролем

    Ограничение доступа реализовано через модуль HttpAuthBasic (директивы auth_basic_*).
    Используется утилита htpasswd из пакета httpd-tools:
    $ yum install httpd-tools
    

    Для её использования:
    # создаём файл паролей
    $ touch /etc/nginx/htpasswd
    # запускаем саму утилиты, указывая пользователя и его пароль
    $ htpasswd -b /etc/nginx/htpasswd UserName P@S$w0rD
    

    Можно воспользоваться OpenSSL:
    $ openssl passwd -apr1
    

    После ввода и проверки пароля будет выведен, например, такой хэш $apr1$FxTYeccb$De85YYIB9Sxc58.pD1Dxo1. Записываем в наш файл /etc/nginx/htpasswd в формате:
    UserName:$apr1$FxTYeccb$De85YYIB9Sxc58.pD1Dxo1
    

    В конфигурацию сайта добавляем строки
    location / {
    # или
    location ^~ /folder/ {
    # или
    location /log-tomcat/ {
        alias                   /var/lib/docker/_log_tomcat/;
        autoindex               on;
        autoindex_format        html;
        autoindex_exact_size    off;
        autoindex_localtime     on;
        auth_basic              "Restricted Area";
        auth_basic_user_file    /etc/nginx/htpasswd;
    }
    

    Перезагружаем новую конфигурацию и проверяем доступ.

    4) Работа с модулями

    Просмотр списка подключённых модулей:
    $ nginx -V 2>&1 | xargs -n1 | grep module
    

    MySQL + phpMyAdmin

    Создаём конфигурационный файл /usr/local/etc/my.cfg с одним параметром (для начала):
    [mysqld]
    log = /var/log/mysql.log
    

    Создаём конфигурационный файл phpMyAdmin.conf для Apache в каталоге /usr/local/etc/apache24/Includes/ и вписываем туда:
    Alias /phpmyadmin/ "/usr/local/www/phpMyAdmin/"
    <Directory "/usr/local/www/phpMyAdmin/">
    	DirectoryIndex index.php
    #	Options none
    	AllowOverride Limit
    # по IP адресу
    	Require ip 192.168.1.4/24 192.168.2.43   # Разрешаем только доверенным
    </Directory>
    

    Открываем конфигурационный файл /usr/local/www/phpMyAdmin/config.inc.php и прописываем следущее:
    <?php
        $i = 0;
        $i++;
        $cfg['Servers'][$i]['host'] = 'localhost';
        $cfg['Servers'][$i]['extension'] = 'mysqli';
        $cfg['Servers'][$i]['connect_type'] = 'tcp';
        $cfg['Servers'][$i]['compress'] = false;
        $cfg['Servers'][$i]['auth_type'] = 'config';
        $cfg['Servers'][$i]['user'] = 'root';
        $cfg['Servers'][$i]['password'] = '<пароль_root-а>';
        $cfg['blowfish_secret']='gh7ThGrf6J'; // Любая фраза
    ?>
    

    Заходим на страницу phpMyAdmin по ссылке:
    http://<наш_сервер>/phpmyadmin/
    

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

    И начинаем делать то, что написано в "здесь".
    Создадим необходимые таблицы указанным скриптом create_tables.sql и обновим созданные структуры скриптом upgrade_tables_mysql_4_1_2+.sql (т.к. у нас более новая версия MySQL сервера):
    $ cd /usr/local/www/phpMyAdmin/examples
    $ cat create_tables.sql upgrade_tables_mysql_4_1_2+.sql | mysql -u root -p
    

    Переоткроем страницу phpMyAdmin, чтобы изменения считались (иногда требует перезапуска браузера: может не отображаться, например, пункт меню "Пользователи").
    Следующим шагом необходимо создать специального пользователя с именем "pma" и наделить его соответствующими правами, для чего нажмите "Privileges" ("Привилегии"), на открывшейся странице нажмите ссылку "Add a new User" ("Добавить нового пользователя"), в разделе "Login Information" ("Информация учетной записи") заполните поля следующим образом:
    User name (Имя пользователя): pma
    Host (Хост): localhost
    Password (Пароль): <пароль_для_pma>
    Нажмите кнопку "Go" ("OK").
    

    На открывшейся странице, в разделе "Database-specific privileges" ("Привилегии уровня базы данных") из ниспадающего меню "Add privileges on the following database:" ("Добавить привилегии на следующую базу") выберите "phpmyadmin". Откроется следующая страница, где в разделе "Databasespecific privileges" ("Привилегии уровня базы данных"), в блоке "Data" ("Данные"), поставьте галочки рядом с опциями: SELECT, INSERT, UPDATE, DELETE и нажмите "Go" ("OK").
    Снова открываем конфигурационный файл /usr/local/www/phpMyAdmin/config.inc.php и к ранее прописанному добавляем:
        $cfg['Servers'][$i]['controlhost'] = 'localhost';
        $cfg['Servers'][$i]['controluser'] = 'pma';
        $cfg['Servers'][$i]['controlpass'] = '<пароль_для_pma>';
        $cfg['Servers'][$i]['pmadb'] = 'phpmyadmin';
        $cfg['Servers'][$i]['bookmarktable'] = 'pma_bookmark';
        $cfg['Servers'][$i]['relation'] = 'pma_relation';
        $cfg['Servers'][$i]['table_info'] = 'pma_table_info';
        $cfg['Servers'][$i]['table_coords'] = 'pma_table_coords';
        $cfg['Servers'][$i]['pdf_pages'] = 'pma_pdf_pages';
        $cfg['Servers'][$i]['column_info'] = 'pma_column_info';
        $cfg['Servers'][$i]['history'] = 'pma_history';
        $cfg['Servers'][$i]['tracking'] = 'pma_tracking';
        $cfg['Servers'][$i]['designer_coords'] = 'pma_designer_coords';
        $cfg['Servers'][$i]['userconfig'] = 'pma_userconfig';
        $cfg['Servers'][$i]['recent'] = 'pma_recent';
        $cfg['Servers'][$i]['table_uiprefs'] = 'pma_table_uiprefs';
    

    Можно эти исправления делать вручную, но советуют пользоваться
    http://<наш_сервер>/phpmyadmin/setup/
    

    , там же можно добавить необходимые параметры для дополнительных функций.
    И последнее: необходимо защитить этой конфигурационный файл от изменений:
    $ chmod 640 config.inc.php
    

    и запретить к нему достуа по web, создав в каталоге /usr/local/www/phpMyAdmin файл .htaccess с таким содержимым:
    Require ip 192.168.1.4/24 192.168.2.43   # Разрешаем только доверенным IP
    <Files config.inc.php>   # запрет доступа к config.inc.php
    	Require all denied
    </Files>
    

    Всё, настройка (базовая) закончена: переоткрыв страницу с phpMyAdmin (или перезапустив браузер) получаем полный доступ. Правда, чтобы получить некоторые дополнительные возможности программы придётся ещё немного его настроить.

    Последние штрихи

    Чтобы не засорять систему, для логов Apache и MySQL настроим ежедневную ротацию с глубиной хранения 31 день, добавив в файл /etc/newsyslog.conf три строчки:
    /var/log/httpd-access.log               640  31    *    @T00  C
    /var/log/httpd-error.log                640  31    *    @T00  C
    /var/log/mysql.log                      640  31    *    @T00  C
    

    PostgreSQL + phpPgAdmin

    МЕЛОЧИ

    Мелочь №1: Сброс забытого пароля пользователя root для MySQL
    Остановим MySQL сервер:
    $ /usr/local/etc/rc.d/mysql-server stop
    Stopping mysql.
    Waiting for PIDS: 1022.
    

    Запустим сервер MySQL, но уже в "защищённом режиме":
    $ mysqld_safe --skip-grant-tables --user=root &
    

    Войдём под пользователей root, но без пароля:
    $ mysql -u root
    mysql> use mysql;
    mysql> update user set password=PASSWORD("<новый_пароль>")
           where User='root';
    mysql> flush privileges;
    mysql> quit
    

    Остановим сервер MySQL:
    $ /usr/usr/local/etc/rc.d/mysql-server stop
    mysql not running? (check /var/db/mysql/fbsd9zfs.homed.local.pid).
    

    Запустим сервер MySQL в обычном режиме:
    $ /usr/local/etc/rc.d/mysql-server start
    Starting mysql.
    

    и проверим наш новый пароль:
    $ mysql -u root -p
    Enter password: 
    ...
    mysql> quit
    

    Мелочь №2: Кодировка в Apache
    Зачастую разработчики и администраторы не верно указывают кодировку на заголовке страниц и в настройках web-серверов.
    Особенно часто это касается кодировки UTF-8, коту очень часто указывают в форме UTF8.
    Поэтому надо следить, чтобы это, например, для Apache было так:
    <Directory /path/to/site/>
           AddDefaultCharset UTF-8
    </Directory>
    

    А для nginx так:
    http {
           charset utf-8;
    }
    # или 
    server {
           charset utf-8;
    }
    

    Правда бывают и исключения, заложенные разработчиками используемого ПО. Например, в MySQL для указания в какой кодировке обращаться к БД используется запрос:
    SET NAMES utf8
    

    Вероятно это либо просто ошибка, либо "дань моде на ошибку".
    Подробней о кодировках: здесь.

    Мелочь №3: Перекодирование текста в БД
    В случае проблем с кодировкой текста в записях в БД это можно исправить средствами самого MySQL.
    Например, если видим такое:
    $ echo 'select * from test;' | mysql -t tmp
    +--------------------------+
    | a |
    +--------------------------+
    | &#208;±&#208;»&#208;°&#208;±&#208;»&#208;° |
    +--------------------------+
    $

    Воспользуемся командой convert:
    $ echo 'select convert(convert(a using latin1) using binary) from test;' | mysql -t tmp
    +-----------------------------------------------+
    | convert(convert(a using latin1) using binary) |
    +-----------------------------------------------+
    | блабла |
    +-----------------------------------------------+
    $

    Ещё пример, с кодировкой KOI-8R:
    $ echo 'select * from test;' | mysql -t tmp
    +--------------------------------+
    | a |
    +--------------------------------+
    | п&#9568;п&#9577;п&#9567;п&#9568;п&#9577;п&#9567; |
    +--------------------------------+
    $

    И тут всё аналогично:
    $ echo 'select convert(convert(a using koi8r) using binary) from test;' | mysql -t tmp
    +----------------------------------------------+
    | convert(convert(a using koi8r) using binary) |
    +----------------------------------------------+
    | блабла |
    +----------------------------------------------+
    $

    Полезное: ссылка1, ссылка2, ссылка3.

    Мелочь №4: Nginx: 503 ошибка, в его логах upstream sent too big header while reading response header from upstream

    Проблема решается добавлением в основной файл nginx.conf в раздел http{} строк:
    fastcgi_buffers		16 64k;
    fastcgi_buffer_size	128k;
    proxy_buffer_size	128k;
    proxy_buffers		4 256k;
    proxy_busy_buffers_size	256k;
    

    Мелочь №5: Встроенные переменные Nginx

    Переменная
    Описание
    $args аргументы в строке запроса
    $arg_name аргумент name в строке запроса
    $binary_remote_addr адрес клиента в бинарном виде (длина её значения всегда 4 байта)
    $content_length строка 'Content-Length' в заголовке запроса
    $content_type строка 'Content-Type' в заголовке запроса
    $cookie_name cookie name
    $document_root значение директивы root для текущего запроса
    $document_uri аналогично $uri
    $host строка 'Host' в заголовке запроса или имени сервера-получателя запроса при отсуствии этой строки
    $hostname имя хоста
    $http_name строка name в заголовке запроса
    $is_args содержит '?' при наличии аргументов в строке запроса и пустую строку при их отсутствии
    $limit_rate установка ограничения скорости соединения
    $pid номер рабочего процесса
    $request_method метод запроса (обычно это “GET или POST)
    $remote_addr адрес клиента
    $remote_port порт клиента
    $remote_user имя пользователя (используемого в Basic аутентификации)
    $realpath_root значение директивы root для текущего запроса (все символические ссылки преобразованы в реальные пути)
    $request_filename путь к файлу для текущего запроса (формируется из директив root или alias и URI запроса)
    $request_body тело запроса (значение переменной появляется в location (обрабатываемых директивами proxy_pass и fastcgi_pass))
    $request_body_file имя временного файла с телом запроса (по завершению работы файл необходимо удалить). Для постоянной записи тела запроса клиента в файл указывается client_body_in_file_only on. При передаче имени в проксированном запросе или в запросе к FastCGI-серверу следует запретить передачу самого тела директивами “proxy_pass_request_body off или fastcgi_pass_request_body off соответственно
    $request_uri полный первоначальный URI вместе с аргументами
    $query_string аналогично $args
    $scheme схема запроса ('http' или 'https')
    $server_protocol протокол запроса (обычно 'HTTP/1.0' или'“HTTP/1.1')
    $server_addr адрес сервера-получателя запроса. Обычно для получения значения этой переменной делается один системный вызов. Для избежания системного вызова указывают адреса в директивах listen и используют параметр bind
    $server_name именя сервера-получателя запроса
    $server_port порт сервера-получателя запроса
    $uri текущий URI в запросе (может отличаться от первоначального при использовании внутренних редиректов или при использовании индексных файлов)

    Настройка 2-х узлового кластера PostgreSQL 12 в синхронном режиме master-slave с потоковой репликацией данных и кластерным IP

    Инструкция основана и является продолжением инструкции "Установка базового сервера на основе CentOS 7/8", по которой установлены 2 сервера на основе CentOS 8. Следует иметь в виду, что оба сервера должны быть максимально идентичны друг другу как по характеристикам, так и по установленному ПО и параметрам его конфигурирования (особенно всё, что связано с работой PostgreSQL). Версионность самого PostgreSQL должна полностью совпадать (смена версий должна происходить при остановленной работе серверов).
    Имена и IP, используемые в инструкции:
    Имя
    IP адрес
    Описание
    srv-psql.mydomain.local 192.168.1.100 кластерный IP (по которому должны будут подключаться приложения)
    srv-psql-p1.mydomain.local 192.168.1.109 узел в режиме master
    srv-psql-p2.mydomain.local 192.168.1.111 узел в режиме slave

    Назначаем имена серверам:
    # узел - master
    hostnamectl set-hostname srv-psql-p1.mydomain.local
    # узел - реплика
    hostnamectl set-hostname srv-psql-p2.mydomain.local
    

    Регистрируем в DNS все адреса из таблицы.
    Все дальнейшие действия делаем на обоих серверах. При необходимости делать действия, разные для каждого сервера - это будет обговорено.
    В файл /etc/hosts тоже их запишем, чтобы избежать проблем в случае сбоя DNS или потери доступа к нему:
    192.168.1.100   srv-psql srv-psql.mydomain.local      
    192.168.1.109   srv-psql-p1 srv-psql-p1.mydomain.local
    192.168.1.111   srv-psql-p2 srv-psql-p2.mydomain.local
    

    Если сервер готовился по инструкции "Установка базового сервера на основе CentOS 7/8", то подготовим партицию для БД (для примера: "сжав" /dev/mapper/centos-opt до 4ГБ и создав из освободившегося места /dev/mapper/centos-var_lib_psql):
    $ umount /opt
    $ e2fsck -f /dev/mapper/centos-opt
    $ resize2fs -p /dev/mapper/centos-opt 4G
    $ lvreduce -L 4G /dev/mapper/centos-opt
    $ e2fsck -f /dev/mapper/centos-opt
    $ lvcreate -l +100%FREE -n var_lib_pgsql centos
    $ mkfs.ext4 /dev/mapper/centos-var_lib_pgsql
    

    Пропишем указанную партицию в /etc/fstab:
    /dev/mapper/centos-var_lib_pgsql                 /var/lib/pgsql  ext4    defaults        0 2
    

    Не забываем удалить или закомментировать строку для /dev/mapper/centos-opt, если /opt у нас больше не будет отдельной партицией.
    Создаём и монтируем каталог /var/lib/pgsql:
    $ mkdir -p /var/lib/pgsql
    $ mount -a
    

    Устанавливаем репозиторий, если не был установлен ранее:
    $ dnf install https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
    # отключаем репозитории всех версий, кроме 12
    $ yum-config-manager --disable pgdg94 --disable pgdg95 --disable pgdg96 --disable pgdg10 --disable pgdg11
    

    Активируем модуль PostgreSQL требуемой версии:
    
    # смотрим список модулей
    $ dnf module list postgresql
    # отключаем версию "по умолчанию"
    $ dnf module disable postgresql:10
    # активируем требуемую версию
    $ dnf module enable postgresql:12
    

    После этого, или если были оба пакета - ставим PostgreSQL:
    $ dnf install postgresql12-server postgresql12-contrib
    

    Если права на каталог /var/lib/pgsql при установке сервера PostgeSQL не выставились:
    # проверяем права
    $ ls -laZ /var/lib/pgsql
    # если не postgres:postgres, 700, postgresql_db_t - восстанавливаем
    $ chown postgres:postgres /var/lib/pgsql
    $ chmod 700 /var/lib/pgsql
    $ restorecon -Rv /var/lib/pgsql
    

    Инициализируем кластер (только на MASTER!):
    $ /usr/pgsql-12/bin/postgresql-12-setup initdb
    

    Конфигурируем каталог журналов (только на MASTER!):
    $ mkdir -p /var/log/postgresql
    $ rmdir /var/lib/pgsql/12/data/log
    $ ln -s /var/log/postgresql /var/lib/pgsql/11/data/log
    $ chmod -R 700 /var/log/postgresql
    $ chown -R postgres:postgres /var/log/postgresql
    $ restorecon -Rv /var/log/postgresql
    

    Создаём файл параметров bash с домашнем каталоге пользователя postgres:
    cat <<EOF > /var/lib/pgsql/.bashrc
    export PATH=\$PATH:/usr/pgsql-11/bin
    export PGDATA="\$HOME/11/data"
    EOF
    

    Или внесём эти строки в файл /var/lib/pgsql/.bashrc (если он уж был создан):
    export PATH=$PATH:/usr/pgsql-12/bin
    export PGDATA="$HOME/12/data"
    

    На MASTER узле:
    а) сохраняем имеющийся файл конфигурации сервера PostgreSQL /var/lib/pgsql/12/data/postgresql.conf:
    $ mv /var/lib/pgsql/12/data/postgresql.conf /var/lib/pgsql/12/data/postgresql.conf-base
    

    И вместо него создаём новый, с таким содержанием:
    ###=-- Подключение ----------------------------------
    # listen_addresses = 'localhost'
    listen_addresses = '*'
    port = 5432
    max_connections = 1000
    unix_socket_directories = '/var/run/postgresql'
    unix_socket_permissions = 0777
    bonjour = off
    
    ###=-- Репликация и восстановление ------------------
    wal_level = replica
    max_wal_senders = 2
    wal_keep_segments = 32
    hot_standby = on
    
    ###=-- Статистика
    shared_preload_libraries = 'pg_stat_statements, pg_buffercache'
    pg_stat_statements.max = 10000
    pg_stat_statements.track = all
    
    ###=-- Безопасность и аутентификация ----------------
    authentication_timeout = 1min
    ssl = off
    password_encryption = on
    
    ###=-- Параметры работы в памятью -------------------
    shared_buffers = 128MB
    dynamic_shared_memory_type = posix
    
    ###=-- Журналирование -------------------------------
    log_destination = 'stderr'
    logging_collector = on
    log_directory = '/var/log/postgresql'
    log_filename = 'postgresql-%a.log'
    log_truncate_on_rotation = on
    log_rotation_age = 1d
    log_rotation_size = 0
    #log_line_prefix = '< %m > '
    log_line_prefix = '%m [%p] '
    log_timezone = 'Europe/Moscow'
    
    ###=-- Установки времени и локализации --------------
    datestyle = 'iso, mdy'
    timezone = 'Europe/Moscow'
    lc_messages = 'ru_RU.UTF-8'
    lc_monetary = 'ru_RU.UTF-8'
    lc_numeric = 'ru_RU.UTF-8'
    lc_time = 'ru_RU.UTF-8'   
    default_text_search_config = 'pg_catalog.russian'
    
    ###=-- Уборка мусора (VACUUM) ----
    autovacuum = on
    vacuum_freeze_table_age = 0
    

    Установим ему правила SELinux (если он не отключён):
    $ restorecon -Rv /var/lib/pgsql/12/data/postgresql.conf
    

    И запустим сервер:
    $ systemctl enable postgresql-12 --now
    

    б) создаём пользователя для репликации:
    Подключаемся к нашему серверу:
    $ sudo -u postgres psql
    

    создаём пользователя:
    CREATE USER u_replica REPLICATION LOGIN CONNECTION LIMIT 2 ENCRYPTED PASSWORD 'P@s$w0rD';
    

    в) сохраняем копию файла управления доступом /var/lib/pgsql/12/data/pg_hba.conf:
    $ cp /var/lib/pgsql/12/data/pg_hba.conf /var/lib/pgsql/12/data/pg_hba.conf-base
    

    И добавляем в конец файла строки:
    host    replication     u_replica       192.168.1.100/32        md5
    host    replication     u_replica       192.168.1.109/32        md5
    host    replication     u_replica       192.168.1.111/32        md5
    

    без перезагрузки сервера БД даём ему указание обновить информацию о настройках доступа из файла pg_hba.conf:
    $ su postgres
    $ pg_ctl reload
    $ exit
    

    На SLAVE узле:
    а) производим загрузку баз с MASTER:
    $ sudo -u postgres pg_basebackup -P -R -X stream -c fast -h 192.168.1.109 -U u_replica -D /var/lib/pgsql/11/data
    

    На запрос пароля укажем пароль от созданного на MASTER узле пользователя для репликации.
    По окончании синхронизации и на SLAVE конфигурируем каталог журналов:
    $ mkdir -p /var/log/postgresql
    $ ln -s /var/log/postgresql /var/lib/pgsql/12/data/log
    $ chmod -R 700 /var/log/postgresql
    $ chown -R postgres:postgres /var/log/postgresql
    $ restorecon -Rv /var/log/postgresql
    

    При репликации данных в MASTER был создан файл /var/lib/pgsql/12/data/recovery.conf, куда надо добавить строку:
    trigger_file = '/tmp/failover_psql'
    

    При появлении в каталог /tmp/ файла failover_psql сервер PostgreSQL перейдёт из режима SLAVE в MASTER и перестанет принимать данные от старого MASTER.
    Запустим сервер:
    $ systemctl enable postgresql-12
    $ systemctl start postgresql-12
    

    Проверяем состояние репликации (через psql):
    # на мастере
    =# select * from pg_stat_replication;
    # на реплике
    =# select * from pg_stat_wal_receiver;
    

    На обоих серверах устанавливаем keepalived:
    $ yum install keepalived
    

    в) сохраняем имеющийся файла конфигурации /etc/keepalived/keepalived.conf:
    $ mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf-base
    

    Создаём новый файл конфигурации /etc/keepalived/keepalived.conf со следующим содержимым (указано, какие строки брать для MASTER, а какие - для SLAVE):
    ### Configuration File for keepalived
    
    vrrp_script chk_pgsql-server {
    # для MASTER
            script "/usr/pgsql-11/bin/pg_isready --dbname=keepalived_test --host=192.168.1.109 --port=5432"
    # для SLAVE
            script "/usr/pgsql-11/bin/pg_isready --dbname=keepalived_test --host=192.168.1.111 --port=5432"
            interval 2
            fall 3
            rise 3
            timeout 2
    # для MASTER
            weight 20
    # для SLAVE
            weight 15
    }
    
    global_defs {
            notification_email {
                    devops@mydomain.org
                    username@mydomain.org
            }
            notification_email_from pgsql_ha@mydomain.org
            script_user keepalived_script
            enable_script_security
            smtp_server smtp-server.mydomain.org
            smtp_connect_timeout 30
            lvs_sync_daemon eth0
    # для MASTER
            router_id LVS_PGS1
    # для SLAVE
            router_id LVS_PGS2
            vrrp_skip_check_adv_addr
            vrrp_garp_interval 0
            vrrp_gna_interval 0
    }
    
    vrrp_instance VI_PSQL {
            debug 4
    # для MASTER
            state MASTER
    # для SLAVE
            state BACKUP
            interface eth0
            virtual_router_id 130
    # для MASTER
            priority 33
    # для SLAVE
            priority 30
            advert_int 1
    # для MASTER
            unicast_src_ip 192.168.1.109
    # для SLAVE
            unicast_src_ip 192.168.1.111
            unicast_peer {
    # для MASTER
                    192.168.1.111
    # для SLAVE
                    192.168.1.109
            }
            authentication {
                    auth_type PASS
                    auth_pass P@s$w0rD
            }
            virtual_ipaddress {
                    192.168.1.100
            }
            track_script {
                    chk_pgsql-server
            }
            smtp_alert
    #       notify_master "/etc/keepalived/to_zabbix.sh MASTER"
    #       notify_backup "/etc/keepalived/to_zabbix.sh BACKUP"
    #       notify_fault "/etc/keepalived/to_zabbix.sh FAULT"
    }
    

    Создаём пользователя, под которым будут исполняться скрипты keealived:
    $ useradd -d /dev/null -g users -s /bin/false keepalived_script
    

    Создаём БД, по которой будет проверяться работа сервера PostgreSQL и соответствующего пользователя:
    $ sudo -u postgres psql
    CREATE USER keepalived_script WITH LOGIN CONNECTION LIMIT 2 ENCRYPTED PASSWORD 'P@s$w0rDka';
    CREATE DATABASE keepalived_test OWNER TO keepalived_script;
    

    Запускаем keealived:
    $ systemctl enable keepalived --now
    

    Если у нас включён SELinux - проверяем его логи и создаём политику для keepalived:
    $ cat /var/log/audit/audit.log | grep denied | grep keepalived | grep -E "setgid|setuid" | audit2allow -M keepalived_script
    $ semodule -i keepalived_script.pp
    

    Перезагружаем keepalived:
    $ systemctl restart keepalived
    

    Проверить работу keepalived можно по его записям в системный журнал /var/log/messages.

    Настройка Apache Kafka

    Подготовительный (необязательный) этап: организуем отдельную LVM партицию для хранения данных (считается, что у нас есть свободное пространство в группе томов centos):
    # Выделяем 30 ГБ (индивидуально для задачи)
    $ lvcreate -L +30G -n opt_kafka_data centos
    $ mkfs.ext4 /dev/mapper/centos-opt_kafka_data
    $ mkdir -p /opt/kafka/data
    

    В /etc/fstab прописываем:
    /dev/mapper/centos-opt_kafka_data              /opt/kafka/data   ext4    defaults        0 2
    

    И сразу монтируем его:
    $ mount -a
    

    Устанавливаем JRE 1.8:
    $ dnf install java-1.8.0-openjdk
    

    Скачиваем и распаковываем в /opt/kafka актуальную версию:
    $ wget http://apache-mirror.rbc.ru/pub/apache/kafka/2.3.1/kafka_2.11-2.3.1.tgz
    $ tar xfvz kafka_2.11-2.3.1.tgz
    $ mv kafka_2.11-2.3.1 /opt/kafka
    

    Создаём профиль пользователя, под которым будет работать Kafka и устанавливаем права на его каталог:
    $ groupadd kafka
    $ useradd -M -s /bin/nologin -g kafka -d /opt/kafka/ kafka
    $ passwd kafka -l
    $ cd /opt/kafka/
    $ chmod -R g+r config
    $ chmod g+x config
    

    Создаём каталоги для хранилищ kafka и zookeeper:
    $ mkdir -p /opt/kafka/data/kafka
    $ mkdir -p /opt/kafka/data/zookeeper
    

    Исправляем права на /opt/kafka:
    $ chown -R kafka:kafka /opt/kafka
    $ chmod 770 /opt/kafka
    

    Создаём каталог для журналов и сами журналы:
    $ mkdir -p /var/log/kafka
    $ rmdir /opt/kafka/logs
    $ ln -s /var/log/kafka /opt/kafka/logs
    $ chmod -R 700 /var/log/kafka
    $ chown -R kafka:kafka /var/log/kafka
    $ restorecon -Rv /var/log/kafka
    $ touch /var/log/kafka/kafka.log
    $ touch /var/log/kafka/zookeeper.log
    $ touch /var/log/kafka/kafka-connect.log
    $ chown -R kafka:kafka /var/log/kafka
    

    Создаём файлы systemd юнитов:
    1) /etc/systemd/system/zookeeper.service:
    [Unit]
    Description=Apache Zookeeper server (Kafka-embedded)
    Documentation=http://zookeeper.apache.org
    Requires=network.target remote-fs.target
    After=network.target remote-fs.target
    
    [Service]
    Type=simple
    User=kafka
    Group=kafka
    ExecStart=/bin/sh -c '/opt/kafka/bin/zookeeper-server-start.sh /opt/kafka/config/zookeeper.properties >> /var/log/kafka/zookeeper.log 2>&1'
    ExecStop=/bin/sh -c '/opt/kafka/bin/zookeeper-server-stop.sh >> /var/log/kafka/zookeeper.log 2>&1'
    Restart=on-abnormal
    
    [Install]
    WantedBy=multi-user.target
    

    2) /etc/systemd/system/kafka.service:
    [Unit]
    Description=Apache Kafka server (broker)
    Documentation=http://kafka.apache.org/documentation.html
    Requires=zookeeper.service
    After=zookeeper.service
    
    [Service]
    Type=simple
    User=kafka
    Group=kafka
    ExecStart=/bin/sh -c '/opt/kafka/bin/kafka-server-start.sh /opt/kafka/config/server.properties >> /var/log/kafka/kafka.log 2>&1'
    ExecStop=/bin/sh -c '/opt/kafka/bin/kafka-server-stop.sh >> /var/log/kafka/kafka.log 2>&1'
    Restart=on-abnormal
    
    [Install]
    WantedBy=multi-user.target
    

    Перечитываем параметры юнитов:
    $ systemctl daemon-reload
    # И можно проверить, как они встроились в systemd
    $ systemctl --all list-dependencies
    

    В файле /opt/kafka/config/zookeeper.properties указываем директорию:
    dataDir=/opt/kafka/data/zookeeper
    

    В файл /opt/kafka/config/server.properties:
    # добавляем
    delete.topic.enable=true
    # изменяем каталог
    log.dirs=/opt/kafka/data/kafka
    

    В firewalld создаём правило для сервиса kafka:
    $ firewall-cmd --permanent --new-service=kafka
    $ firewall-cmd --permanent --service=kafka --add-port=2181/tcp
    $ firewall-cmd --permanent --service=kafka --add-port=9092/tcp
    $ firewall-cmd --permanent --zone=work --add-service=kafka
    $ firewall-cmd --reload
    

    Запускаем сервис kafka:
    # запуск сервиса и установка автозапуска
    $ systemctl enable kafka.service --now
    # проверка работы сервисов
    $ systemctl status kafka.service zookeeper.service
    

    Kafka настроен как зависящий от Zookeeper, поэтому вначале запускается zookeeper.service, а затем kafka.service.

    Дополнительные действия

    №1 Подключение к PostgreSQL
    Если необходимо подключение в СУБД, то необходимо настроить коннектор для соответствующей СУБД. Для этого идём на сайт проекта debezium.io и скачиваем актуальную версию для PostgreSQL (для примера):
    $ wget https://repo1.maven.org/maven2/io/debezium/debezium-connector-postgres/0.10.0.Final/debezium-connector-postgres-0.10.0.Final-plugin.tar.gz
    # распаковываем библиотеки в каталог [b]/opt/kafka/libs[/b]:
    $ tar xvfz debezium-connector-postgres-0.10.0.Final-plugin.tar.gz --strip-components 1 -C /opt/kafka/libs *jar
    

    Создаём файл systemd юнита /etc/systemd/system/kafka-connect.service:
    [Unit]
    Description=Apache Kafka server (Connector)
    Documentation=https://kafka.apache.org/documentation/#connect_running
    Requires=kafka.service
    After=kafka.service
    
    [Service]
    Type=simple
    User=kafka
    Group=kafka
    ExecStart=/bin/sh -c '/opt/kafka/bin/connect-standalone.sh /opt/kafka/config/connect-standalone.properties /opt/kafka/config/connector/connect1.properties >> /var/log/kafka/kafka-connect.log 2>&1'
    Restart=on-abnormal
    
    [Install]
    WantedBy=multi-user.target
    

    Создаём каталог для конфигураций подключений:
    $ mkdir -P /opt/kafka/config/connector/
    

    И файлы конфигураций подключения к СУБД (по примеру: /opt/kafka/config/connector/connect1.properties, но их можно создавать несколько и добавлять в строку запуска в файле /etc/systemd/system/kafka-connect.service, разделяя пробелами):
    name=server-pgsql-1
    plugin.name=wal2json
    connector.class=io.debezium.connector.postgresql.PostgresConnector
    tasks.max=1
    database.hostname=server-pgsql-1.local
    database.port=5432
    database.user=u_name1
    database.password=P@s$w0rD
    database.dbname=db_name1
    database.server.name=DBNAME1
    database.whitelist=public
    table.whitelist=public.table1,public.table2,public.table3,public.table4,public.table5,public.table6
    slot.name=debezium_dbname1
    

    где public.table1-public.table6 - названия таблиц, из которых импортируются данные.
    Устанавливаем на эти файлы права доступа:
    $ chown -R kafka:kafka /opt/kafka/config/connector
    

    Запускаем коннектор:
    $ systemctl enable kafka-connect.service --now
    

    Проверяем успешность запуска через файл /opt/kafka/logs/kafka-connect.log.

    Дополнительная информация

    1) Setup a single Apache Kafka node on CentOS 7
    2) Установка Kafka в Unix/Linux
    3) How to Install Apache Kafka on CentOS 7
    4) How To Install Apache Kafka on CentOS 7



    размещено: 2012-07-29,
    последнее обновление: 2020-09-19,
    автор: Fomalhaut


    mfog, 2012-08-09 в 15:59:41

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

    Fomalhaut, 2012-08-13 в 14:15:09

    Они установятся, как зависимость для phpMyAdmin.

    Dr. Pi, 2012-10-07 в 19:26:52

    строка DirectoryIndex index.php index.html
    дожна быть вписана в секцию <IfModule dir_module>, а не в секцию <Directory> :))

    PathFounder, 2013-01-01 в 12:48:27

    Грандмерси за статью - самому написать было лень, а когда консультировал или сам "по-быстрому" ставил - всё время на всяких мелочах ловил грабли :)

    Fomalhaut, 2013-01-01 в 15:02:32

    PathFounder: Поэтому и написал: надоело многократно наступать на одни и те же грабли. :)

    ail-man, 2013-01-15 в 12:49:11

    Спасибо автору, все работает =)

    SkiNNi, 2013-03-05 в 10:33:45

    Корректировки по моей установке, если кто  напорется:
    1. При конфигурировании установки PHP выбрать модуль APACHE он у меня не был выбран.
    2. У меня не заработал скрипт mysql_secure_installation поэтому делать как: Мелочь №1: Сброс забытого пароля пользователя root для MySQL
    3.каталог phpMyAdmin переписать в /usr/local/www/apache22/data т.к. каталог по умолчанию.
    Большое спс автору.

    Fomalhaut, 2013-03-10 в 14:56:08

    SkiNNi: Принято:
    1) исправлено: это мой недосмотр - по умолчанию модуль Apache не указан;
    2) а текущий каталог точно был /usr/local/ ? я вот тоже напарывался, пока поиском расположение не нашёл; или опять что-то в дистрибутиве поменялось (раньше вообще все обслуживающие скрипты были в отдельном порту (mysql55-scripts, примерно, не помню точно);
    3) это уже детали, так или иначе настройка вся в httpd.conf.

    Anatoly, 2013-06-11 в 17:21:44

    конфигурационный файл mysql /usr/local/etc/my.cnf

    Витя, 2013-07-03 в 12:32:32

    Отличный мануал, большое спасибо.
    Только не советую конфигурационный файл /usr/local/www/phpMyAdmin/config.inc.php править руками. Куда проще воспользоваться http://ip-servera/phpmyadmin/setup/ там же можно добавить необходимые параметры для доп. функций.

    Artym, 2014-09-09 в 10:26:14

     в связи с тем, что все обновилось, с выхода статьи, пришлось кое-что корректировать.
    с /usr/local/etc/apache22/ на /usr/local/etc/apache24/
    и для phpmyadmin
    cd phpmyadmin
    # mkdir config
    # chmod o+rw config
    # cp config.sample.inc.php config/config.inc.php
    # chmod o+w config/config.inc.php

    Cebers, 2014-10-05 в 22:26:45

    Прикольно было бы для приручения юного админа к FreeBSD, если расписать что значит каждая команда.

    Fomalhaut, 2014-10-05 в 23:26:51

    Юного админа надо не приРучать, а приучать. :)
    Т.е. надо учить, направлять, что в Unix/Linux значить учить самому искать информацию: в man-ах, руководствах и пр. Если бы это было сложно - другой вопрос, но описания в Сети найти не проблема совершенно. Иначе можно получить недоадмина, который на всё готовое только реагировать.

    Jelev, 2015-06-09 в 9:40:29

    "По окончании установки на экран будет выведена информация по необходимым параметрам, которые необходимо прописать в конфиг Apache. Сделаем, как указано: добавим в /usr/local/etc/apache22/httpd.conf в блоке <IfModule mime_module>:"

    Хотя выше:

    "$ cd /usr/ports/www/apache24"

    Xumuk, 2015-11-11 в 12:38:04

    после смены пароля root'a, mysql не останавливается
    # /usr/local/etc/rc.d/mysql-server stop
    Stopping mysql.
    kill: 66356: Operation not permitted



  •  

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

    © lissyara 2006-10-24 08:47 MSK

    Время генерации страницы 0.1066 секунд
    Из них PHP: 76%; SQL: 24%; Число SQL-запросов: 76 шт.
    У Вас отключено GZIP-сжатие в браузере. Размер страницы 193764