понедельник, 4 февраля 2019 г.

WordPress и SSL в ISPmanager

Пару лет назад я взялся поддерживать сайт товарищества собственников дома. Сайт работает на WordPress и хостится на одном из хостингов в РБ. Сделано это чтобы у бухгалтера не было возни с зарубежными хостингами и кроме того непонятно насколько президентский указ №60 относится к товариществу собственников.

На момент создания сайта товарищества Let's Encrypt еще не успел набрать популярность, а платить за воздух покупать платный SSL сертификат не было никакого желания. Теперь хостинг предлагает бесплатные SSL сертификаты от Let's Encrypt, но эта опция доступна только для новых тарифных планов. Помимо бесплатного SSL обещают поддержку PHP 7.2.x (в текущем тарифном плане доступен максимум PHP 7.0.x). Заодно пришло уведомление о скором истечении оплаченного периода и я решил потратить немного времени и попробовать перенести сайт на новый тариф и заодно включить поддержку SSL.

Стоит сказать что в качестве панели управления хостер предлагает ISPmanager какой-то лохматой версии. Если верить комментарию в HTML коде страницы это ISPmanager 4.4 Professional так что все ниже описанное будет относиться к этой версии.

Скопировал WordPress в новый аккаунт и поменял настройки для работы с тестовым именем сайта. Визуально все работает нормально и никаких проблем нет. Но после переключения URL с http:// на https:// оформление части страниц пропало. При это в web developer консоли валится много ошибок про попытку загрузить небезопасные ресурсы на безопасной странице. В список этих ресурсов попали все CSS и JavaScript файлы и поэтому оформление страниц отсутствует. Но почему только часть страниц, а не все? И почему wordpress выдает ссылки на ресурсы с "http://" вместо настроенного "https://"?

Для начала взял первую попавшуюся ссылку с проблемной страницы и поискал место в коде, где ее генерирует. Постепенно продвигаясь от функции к функии я добрался до функции is_ssl(). Чтобы подтвердить свою теорию добавляю в начало функции "return true;" и сайт магически начинает работать правильно. Дальше добавил вывод значения $_SERVER['HTTPS'] и выяснилось что для части страниц эта переменная устанавливается правильно, а для проблемных она отсутствует, но вместо нее есть переменная $_SERVER['REDIRECT_HTTPS'] которая содержит нужное значение.

Для окончательного теста создал отдельный сайт в корне которого только два файла: index.php и .htaccess.

index.php

<?php

ini_set('display_errors', 1);
ini_set('error_reporting', E_ALL);

$server_vars = array('HTTP_HOST', 'REQUEST_URI', 'HTTPS', 'REDIRECT_HTTPS');

foreach ($server_vars as $i) {
  $value = 'N/A';
  if (isset($_SERVER[$i])) {
    $value = $_SERVER[$i];
  }
  echo sprintf('$_SERVER[\'%s\'] = %s<br>', $i, $value);
}

.htaccess

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule (.*) /index.php [L]
</IfModule>

Если открывать сайт как test.example.com, test.example.com/index.php или test.example.com/index.php/test/123, то переменная $_SERVER['HTTPS'] устанавливается правильно, но если открыть его как test.example.com/test/123, то $_SERVER['HTTPS'] отсутствует, а взамен есть переменная $_SERVER['REDIRECT_HTTPS']

Теперь стало понятно почему только часть страниц отображалась неправильно. Завтра попробую озадачить техподдержку хостера - посмотрю что они ответят.

Добавлено 9/02/2019

В базе знаний хостинга нашлось описание проблемы WordPress и SSL - нужно добавить

SetEnvIf X-SSL-Emu on HTTPS=on

в .htaccess и все начинает работать.

1 комментарий: