Актуальность перевода сайта на защищенный протокол HTTPS возрастает с каждым днем. Браузеры уже вовсю грозятся в будущем помечать сайты работающие на HTTP как незащищенные и уже ограничивают их функциональность просто отключая возможность использования, например, веб-камеры и микрофона, а Google не так давно заявил о приоритете HTTPS-сайтов в выдаче. Эти сигналы позволяют предположить в ближайшем будущем массовую миграцию сайтов на работу по защищенному протоколу и если вы еще не сталкивались с переездом на него, то самое время рассмотреть такую возможность и хотя бы ознакомиться с алгоритмом такого переезда.
В данной заметке я опишу свой опыт и затрону решение некоторых неочевидных проблем. Как я понял, необходимость некоторого обобщения полученного опыта имеется, так как на самом деле, предложенная в интернет информация не всегда оказывалась актуальной и приходилось собирать ее из разных источников, а техподдержка хостинга в ответ на вопросы просто самоустранялась, отсылая на форум поддержки CMS.
Так как вопросом переезда на HTTPS я озадачился впервые, то прежде всего набросал небольшой план действий, который выглядел просто и вполне логично:
- приобретение и установка SSL-сертификата через панель управления хостинга
- переключение сайта на HTTPS-протокол, согласно рекомендаций для WordPress
- организация 301 редиректа страниц сайта с протокола HTTP на HTTPS через файл htaccess
- перевод внутренних ссылок сайта из абсолютных в относительные
- оформление переезда на новый протокол для поисковых сервисов через файл robots и панель управления самого сервиса
В таком порядке мы и будем продвигаться.
Приобретение и установка SSL-сертификата
Сам сайт размещается на хостинге Timeweb, предлагаю рассматривать это не как рекламу, а как данность, поэтому речь будет идти о панели управления этого хостинга. Именно через эту панель управления и осуществлялся процесс приобретения и установки SSL-сертификата. Каких то проблем при этом не возникло. Стоит только указать, что сам алгоритм нигде не прописан и первоначально вызвал у меня некоторые вопросы относительно своих действий на определенном этапе, поэтому опишу чуть подробнее, чем возможно, это будет некоторым интересно.
Перед оплатой заказа SSL-сертификата я создал почту admin@codeseller.ru, на которую позже будут приходить письма необходимые для подтверждения заказа на SSL-сертификат.
Сразу после произведенной оплаты SSL-сертификата, никаких дальнейших инструкций я не получил, поэтому решил написать в поддержку для их получения. Ребята с техподдержки что то похимичили, зачем то зачислили мне средства опять на счет, затем заново списали их в оплату SSL-сертификата, а заказ оформленный мной ранее удалили и через некоторое время на созданную почту пришло письмо со ссылкой подтверждения, по которой я перешел и подтвердил свой заказ на создание SSL-сертификата. Хм, сделал вывод, что я что то сделал неверно при первоначально оформленном заказе.
Итак, через некоторое время техподдержка сообщила, что все в порядке - сертификат успешно установлен.
Переключение WordPress-сайта в режим HTTPS
Сразу сообщу, что это наверное самый сложный этап из всего плана действий, поэтому рассмотрю его наиболее подробно.
Идем в панель управления хостинга и переключаем работу сайта в режим HTTPS, далее идем в общие настройки сайта и изменяем "Адрес WordPress (URL)" и "Адрес сайта (URL)" с учетом протокола HTTPS. После сохранения настроек сайт уходит в цикличную переадресацию или, как еще говорят, в луп.
Согласно полученной из различных источников информации в файле wp-config.php требуется также размещать код:
define('FORCE_SSL_ADMIN', true); if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) $_SERVER['HTTPS']='on';
Но у меня его размещение погоды не сделало, ничего не изменилось - сайт в жопе лупе.
На этом этапе поддержка хостинга послала меня куда подальше, а именно на форум поддержки WordPress, поэтому пришлось полагаться только на себя.
Опять полез в интернет, в том числе англоязычный, но предлагаемые решения не работали.
Пришлось включить мозги и начать анализировать ситуацию. Решил посмотреть, а что собственно возвращает фундаментальная для WP функция is_ssl() на данном этапе, в возвращала она false, т.е. говорила нам, что никакого HTTPS на сайте сейчас нет. Именно поэтому и возникла цикличная переадресация, WP не фиксировал, что HTTPS режим работает и перенаправлял на HTTP, а сервер гнул свою линию и с HTTP перенаправлял обратно на HTTPS.
Функция is_ssl() понимает, что сайт работает в режиме HTTPS, только если в глобальном массиве $_SERVER передается ключ "HTTPS" со значением "on". Стал смотреть, что передает действующий сервер в массиве $_SERVER, оказалось, что ключ HTTPS не передается, приехали.
В качестве выхода из сложившейся ситуации следует убедить функцию is_ssl() в том, что HTTPS у нас включен, поэтому необходимо в массив $_SERVER принудительно добавить данные о действующем режиме HTTPS.
Но нам надо как то отличать загружается наш сайт по HTTP или по HTTPS, стал выяснять как это сделать. Как оказалось в массиве $_SERVER этим отличием является ключ "HTTP_X_HTTPS", который передается сервером, и как я понял, характерен только для данного хостинга, если его значение 1, значит сайт загружается по протоколу HTTPS, если этого ключа нет, значит протокол HTTP.
Изменяю приведенный выше код в файле wp-config.php под существующие реалии:
define('FORCE_SSL_ADMIN', true); if (isset($_SERVER['HTTP_X_HTTPS'])&&$_SERVER['HTTP_X_HTTPS']==1) $_SERVER['HTTPS']='on';
Сайт заработал!
Ок, основная проблема решена, можно переходить к следующему этапу.
301 редирект через .htaccess
На данном этапе, наш сайт доступен как по HTTP, так и по HTTPS и основной задачей становиться организация редиректа со всех страниц с протоколом HTTP на те же самые страницы, но уже с протоколом HTTPS.
В интернете для решения этой задачи широко применяется код, размещаемый в файле .htaccess:
RewriteEngine On RewriteCond %{HTTPS} !'on' RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]100
Конечно же, этот код не работал у меня как нужно и отправлял сайт обратно в бесконечный луп. Если был сервер отправлял данные о включенном режиме HTTPS как $_SERVER['HTTPS']='on', то все заработало бы, но тут Timeweb детка, поэтому, зная нюансы описанные выше, приходится изворачиваться и менять общепринятый код редиректа таким образом:
RewriteEngine On RewriteCond %{HTTP:X-HTTPS} !1 RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]100
Вот так редирект замечательно заработал.
Вспомнив техподдержку хостинга еще раз, переходим к следующему этапу.
Переделываем внутренние ссылки из абсолютных в относительные
На этом этапе надо понимать, что сайт уже работает в режиме HTTPS, редирект настроен, но могут быть мелкие проблемы на каких то отдельных страницах сайта, где пути до отдельных скриптов, изображений или внутренних страниц сайта прописаны абсолютными ссылками с указанием старого протокола HTTPS. На таких страницах зеленый замок в адресной строке браузера не будет отображаться, а это будет означать, что безопасность на таких страницах является неполной. Для решения этой проблемы и необходимо перевести все внутренние ссылки в статьях и страницах сайта с абсолютных на относительные, например:
- http://codeseller.ru/polzovateli/ - абсолютная ссылка
- /polzovateli/ - относительная ссылка
В первую очередь, меня беспокоили пути до изображений в статьях сайта и отдельных страницах. Вручную мы ничего менять не будем, а лучше отправим SQL-запрос к базе данных для массового перевода ссылок в статьях и страницах сайта. Через phpmyadmin делаем запрос:
UPDATE `wp_posts` SET `post_content` = REPLACE (`post_content`, 'http://codeseller.ru/', '/')
После этого, все изображения и внутренние ссылки в статьях и страницах приобретут относительный путь, что нам и требовалось.
Далее, аналогичным образом решаем проблему с абсолютными путями до аватарок пользователей сохраненных через плагин WP-Recall и Ulogin. Для этого делаем два запроса:
UPDATE `wp_usermeta` SET `meta_value` = REPLACE (`meta_value`, 'http://codeseller.ru/', '/') WHERE `meta_key` = 'rcl_avatar' UPDATE `wp_usermeta` SET `meta_value` = REPLACE (`meta_value`, 'http://codeseller.ru/', '/') WHERE `meta_key` = 'ulogin_photo'
После этого, мне осталось лишь по мелочи поправить ссылки в футере, меню сайта и тп, чтобы можно было уже с уверенностью сказать, что о общем задача была решена.
Остался последний штрих.
Сообщаем поисковикам о переезде сайта на HTTPS
Для поисковиков сайт на HTTP и сайт с тем же самым доменом, но на HTTPS - два разных сайта, поэтому фактически мы не сообщаем о смене протокола, а сообщаем о совершенно новом сайте.
Для этого производим несколько несложных действий:
- прописываем в файле robots.txt новый host с протоколом HTTPS в качестве главного зеркала, например "Host: https://codeseller.ru"
- переходим в панель управления Яндекс.Вебмастера и вебмастера Google и указываем свое доменное имя на новом протоколе в качестве главного зеркала.
Вместе с настроенным выше 301 редиректом и этими настройками через некоторое время в результатах поиска все страницы с вашего сайта будут вести на страницы с протоколом HTTPS вместо HTTP. Правда, как предупреждают сами поисковики, сайт вполне может на некоторое время потерять свои позиции в поиске и поисковый трафик просядет, но затем позиции будут восстановлены.
UPD: Решение проблемы с работой крона
Чуть позже, после переезда на HTTPS, обнаружил проблему в работе wp-cron на сайте. Пока проблема в работе крона от WordPress работающего в обычном режиме не решена, решил использовать альтернативный вариант, прописав в файле wp-config.php:
define( 'ALTERNATE_WP_CRON', true );
События крона стали выполняться, но были замечены некоторые проблемы с работой определенных событий. В результате анализа выявил некорректную работу(?) стандартной wp-функции get_posts(), которая вызывалась внутри этих событий. В качестве решения пришлось написать прямой запрос к БД на получение необходимых данных из таблицы wp_posts. После этого проблему в работе крона на сайте можно было считать решенной.
Хотя, возможно чуть позже, удастся выявить причину неработоспособности крона в обычном режиме. Если кому то будет интересно, то удалось выявить проблему в работе функции wp_remote_post(), которая используется в обычном режиме. Работа функции заканчивается ошибкой и возвращает сообщение о слишком большой кол-ве переадресаций, причину этого выявить пока не удалось.
Мы подошли к концу статьи, надеюсь кто то найдет ее полезной. Во всяком случае, я бы хотел наткнуться на нее во время своих поисков. Если у кого то будут замечания по содержанию или вопросы жду в комментариях.
Удачи с переездом на HTTPS.
почему-то при обновлении страницы через F5 или ctrl+F5 замок исчезает, https остается, но становится серым. В чем может быть причина? заранее большое спасибо за ответ. статья Ваша очень полезная, делали по ней, но вот такая проблема...
Это значит что какие то ресурсы загружаются без https (например картинки скрипты, css-стили, метрики/аналитики), посмотрите в исходном коде страницы. Делайте поиск http:// и все что найдете - или убирайте или меняйте на https