Установка WordPress Multisite на Fedora Server 29
Сегодня будем устанавливать WordPress Multisite в режиме поддоменов на Fedora Server 29. Также добавим SSL через HAProxy.
Вводные
Сеть будет состоять из трёх серверов: веб, БД, прокси.
- Веб-сервер Apache 2.4 с CMS WordPress, IP 192.168.10.10.
- Сервер баз данных MariaDB 10.3, IP 192.168.10.20.
- Прокси сервер HAProxy 1.5, IP 192.168.10.30.
Сайт сети — wp.example.local, дочерний сайт — site1.example.local.
Подготовка Fedora Server
Устанавливаем PHP и Apache:
# dnf install php php-fpm php-mysqlnd httpd
Разрешаем веб-серверу подключаться к удалённой БД и отправлять электронную почту:
# setsebool -P httpd_can_network_connect_db=1
# setsebool -P httpd_can_sendmail=1
Разрешаем входящие соединения к веб-серверу:
# firewall-cmd --permanent --zone=public --add-service=http
# firewall-cmd --reload
Активируем автозапуск и запускаем веб-сервер:
# systemctl enable httpd.service
# systemctl start httpd.service
Подготовка СУБД
Подключаемся к MySQL, создаём БД, раздаём права:
# mysql
MariaDB [(none)]> CREATE DATABASE wp_db;
MariaDB [(none)]> GRANT ALL PRIVILEGES ON wp_db.* TO "wp_u"@"192.168.10.10" IDENTIFIED BY "password";
MariaDB [(none)]> FLUSH PRIVILEGES;
MariaDB [(none)]> \q
Установка WordPress
Установка и первичная настройка
Устанавливаем из репозитория:
# dnf install wordpress
Настраиваем подключение к БД в /etc/wordpress/wp-config.php:
define('DB_NAME', 'wp_db');
define('DB_USER', 'wp_u');
define('DB_PASSWORD', 'password');
define('DB_HOST', '192.168.10.20');
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');
Генерируем ключи аутентификации, соль на сайте api.wordpress.org и вставляем в конфигурационный файл:
define('AUTH_KEY', '3w-]qNBC3Om~la+q_nojC-PRlTfI$Bh4 H3+c-]|x%e[+3I<UFdakvy|3}--v<)~');
define('SECURE_AUTH_KEY', '[oMg1to}[^%)z(jPqBD|N.!;qMIv*anGt{JP:))ky2N$8{CV]69on6{Vy;$Nb]+-');
define('LOGGED_IN_KEY', '35=g{#$/Y_-w20XDV!?Qd2*%-K^toYR1` ?DT]8p>G/EZi*bSO_<HykSJ+V_V|/H');
define('NONCE_KEY', 's3W:3_k}TL##wC41H+@!!6nd[:*+@a?^.gj^)ii=AoP`I#w9WjPx~zf_|nFVi]->');
define('AUTH_SALT', '*C;QEcgf-825M(HcGt5Keg#sRRys8Z5G$E{7.O^j1[N.k ETo13(=wB+gc(uCFNm');
define('SECURE_AUTH_SALT', 'EwoRm8/(C;YhdOYk7t=[d,QcP-zKa(|4b!EP -|j;;k|5;pLDz@PYe:@bvR}fKy]');
define('LOGGED_IN_SALT', '- )e|NLpe6T~|@+E <xx1+wprfHu5$|qcBx+!yp6>hI4}%Tp-f4Tx]h`r[)#|rYt');
define('NONCE_SALT', '{l{fkCNV;gbn[/wl~M0o[-` XIm*bg]<O2cU-y!k^o&/^L7y%;p4-F{?b7{H+Ps7');
Подготовка окружения
Настраиваем WordPress на веб-сервере в /etc/httpd/conf.d/wordpress.conf.
Т. к. делаем сеть сайтов в режиме поддоменов, то переносим WordPress в корень:
Alias / /usr/share/wordpress/
Слэш в конце обязателен.
Разрешаем внешние соединения:
<Directory /usr/share/wordpress>
AllowOverride Options
<IfModule mod_authz_core.c>
# Apache 2.4
<strong>Require all granted</strong>
</IfModule>
<IfModule !mod_authz_core.c>
# Apache 2.2
Order Deny,Allow
Deny from All
Allow from 127.0.0.1
Allow from ::1
</IfModule>
</Directory>
Перезапускаем веб-сервер:
# systemctl restart httpd.service
Настройте DNS для WordPress. Для примера буду использовать wp.example.local.
Инициализация
Заходим на http://wp.example.local. Откроется веб-мастер установки:

Вводим заголовок сети сайтов, логин, пароль и email администратора. Жмём Install WordPress.

Главный сайт создан. Далее преобразуем экземпляр в сеть сайтов.
Создание сети
Преобразование инсталляции в сеть
Сеть будем делать в режиме поддоменов.
Включим режим сети в /etc/wordpress/wp-config.php:
/* Multisite */
define( 'WP_ALLOW_MULTISITE', true );
/* That's all, stop editing! Happy blogging. */
Логинимся как network_admin. Переходим в Administration > Tools > Network Setup. Выбираем режим поддоменов, вводим название сети, email администратора и нажимаем Install:


Добавляем настройки сети в /etc/wordpress/wp-config.php:
/* Multisite */
define( 'WP_ALLOW_MULTISITE', true );
define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', true);
define('DOMAIN_CURRENT_SITE', 'wp.example.local');
define('PATH_CURRENT_SITE', '/');
define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);
/* That's all, stop editing! Happy blogging. */
Добаляем правила URL преобразований в /etc/httpd/conf.d/wordpress.conf:
<Directory /usr/share/wordpress>
...
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteRule ^wp-admin$ wp-admin/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^(wp-(content|admin|includes).*) $1 [L]
RewriteRule ^(.*\.php)$ $1 [L]
RewriteRule . index.php [L]
</Directory>
Перезапускаем веб-сервер:
# systemctl restart httpd.service
Перелогиниваемся в wp.example.local. В меню появился выбор между администрированием сети или главного сайта:

Создание дочернего сайта
Создадим сайт site1.wp.example.local.
Переходим в My Sites > Network Admin, жмём Create a New Site:

Вводим адрес и название сайта, email администратора нового сайта и жмём Add Site:

Вместе с сайтом создался пользователь site1. Чтобы зайти в админку site1.wp.example.local нужно пользователю site1 задать пароль. Для этого переходим в My Sites > Network Admin > Sites. Редактируем site1.wp.example.local. Переходим в редактирование пользователя site1 и меняем ему пароль:

Изменение адреса сайта
Создался сайт site1.wp.example.local. Если мы хотели site1.example.local, то нужно отредактировать адрес сайта. Для этого переходим в My Sites > Network Admin > Sites:

Для исправления ошибки при логине в site1.example.local нужно добавить в /etc/wordpress/wp-config.php:
/* Fix login for other domains. */
define( 'COOKIE_DOMAIN', '' );
define( 'ADMIN_COOKIE_PATH', '/' );
define( 'COOKIEPATH', '/' );
define( 'SITECOOKIEPATH', '/' );
/* That's all, stop editing! Happy blogging. */
Также почистите куки.
Установка плагинов
Плагины устанавливаются вручную.
Установим плагин WP User Avatar:
# cd /usr/share/wordpress/wp-content/plugins
# wget https://downloads.wordpress.org/plugin/wp-user-avatar.zip
# unzip wp-user-avatar.zip
# rm -f wp-user-avatar.zip
Активируем плагин для сети сайтов в My Sites > Network Admin > Plugins. Жмём Network Activate. Плагин стал доступен сайтам сети. Для каждого сайта настраивается отдельно в своей админке.
SSL
SSL трафик идёт на HAProxy, здесь терминируется. Далее идёт нешифрованный на веб-сервер с WordPress.
WordPress
В админке меняем адрес сайтов с http:// на https://:

Переводим WordPress на использование SSL:
/** Enable SSL */
define('FORCE_SSL_ADMIN', true);
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)
$_SERVER['HTTPS']='on';
/* That's all, stop editing! Happy blogging. */
База данных
Для исправления старых записей в БД используем скрипт:
USE wp_db;
UPDATE wp_options SET option_value = replace(option_value, 'http://', 'https://') WHERE option_name = 'home' OR option_name = 'siteurl';
UPDATE wp_posts SET guid = REPLACE (guid, 'http://', 'https://');
UPDATE wp_posts SET post_content = REPLACE (post_content, 'http://', 'https://');
UPDATE wp_postmeta SET meta_value = REPLACE (meta_value, 'http://','https://');
Для site1 делаем аналогичную процедуру, только названия таблиц будут с другим префиксом.
HAProxy
Перенаправляем домены wp.example.local и site1.example.local на адрес HAProxy сервера.
Кладём сертификаты в /etc/ssl/certs/.
Терминируем SSL на сервере HAProxy:
# Frontend
frontend front
bind 192.168.10.30:80
bind 192.168.10.30:443 ssl crt /etc/ssl/certs/wp.example.local.pem
bind 192.168.10.30:443 ssl crt /etc/ssl/certs/site1.example.local.pem
mode http
acl wordpress_acl hdr_dom(host) -i wp.example.local
acl site1_acl hdr_dom(host) -i site1.example.local
redirect scheme https if !{ ssl_fc }
use_backend wordpress_back if wordpress_acl
use_backend wordpress_back if site1_acl
# WordPress backend
backend wordpress_back
server wordpress_srv 192.168.10.10:80
http-request add-header X-Forwarded-Proto https if { ssl_fc }