wpssl.ru wordpress WPSSL.ru

Настройка SSL и заголовков прокси в WordPress: решение проблем с правильно переданным HTTPS

При использовании WordPress за обратным прокси-сервером или балансировщиком нагрузки часто возникают проблемы с корректным определением HTTPS-протокола. Это приводит к ошибкам смешанного контента, неправильному формированию URL и другим проблемам, связанным с SSL. В этой статье подробно разберём, как правильно настроить WordPress для работы с SSL в условиях прокси, используя заголовки, такие как X-Forwarded-Proto, и как избежать распространённых ошибок.

Почему возникают проблемы с SSL за прокси

Прокси-серверы часто принимают HTTPS-запросы от клиента, а затем пересылают их на внутренний сервер по HTTP. В результате для WordPress запрос выглядит как незащищённый (HTTP), хотя на самом деле клиент подключился по HTTPS. Это приводит к тому, что WordPress генерирует URL с http://, а не https://, что вызывает ошибки смешанного контента и проблемы с безопасностью.

Одним из способов решения этой проблемы является использование заголовка X-Forwarded-Proto, который прокси передаёт внутреннему серверу, указывая, был ли исходный запрос через HTTPS или HTTP.

Однако WordPress по умолчанию не учитывает этот заголовок, поэтому необходимо вручную настроить обработку этого сигнала.

Настройка WordPress для корректного определения HTTPS за прокси

Для правильной работы нужно добавить в файл wp-config.php следующий код, который проверит заголовок X-Forwarded-Proto и установит флаг HTTPS:

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
}

Этот простой блок кода заставит WordPress считать, что запрос защищён, если прокси сообщил, что исходный протокол был HTTPS.

Если используется другой заголовок, например X-Forwarded-Ssl или Front-End-Https, то код можно расширить:

if ((isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') ||
    (isset($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] === 'on') ||
    (isset($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) === 'on')) {
    $_SERVER['HTTPS'] = 'on';
}

Использование фильтров WordPress для более гибкой настройки

Если вы хотите более изящно решить проблему, можно использовать фильтр wpssl_filter_ssl_detect (префикс "wpssl" добавлен для избежания конфликтов) в файле плагина или в functions.php темы:

add_filter('wpssl_filter_ssl_detect', function($is_ssl) {
    if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
        $is_ssl = true;
    }
    return $is_ssl;
});

Чтобы использовать этот фильтр, нужно переопределить функцию проверки SSL в WordPress, например, через плагин:

function wpssl_is_ssl() {
    $is_ssl = false;
    if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] == 1)) {
        $is_ssl = true;
    } elseif (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443) {
        $is_ssl = true;
    }
    $is_ssl = apply_filters('wpssl_filter_ssl_detect', $is_ssl);
    return $is_ssl;
}

// Использовать эту функцию вместо is_ssl() внутри вашего кода

Это даёт централизованный контроль и позволяет в одном месте менять логику определения HTTPS.

Конфигурация прокси-сервера для передачи заголовков

Важно, чтобы прокси действительно передавал необходимые заголовки. В зависимости от используемого прокси (Nginx, Apache, HAProxy, Cloudflare) это делается по-разному.

  • Nginx: Добавьте в конфигурацию прокси-передачи:
proxy_set_header X-Forwarded-Proto $scheme;
  • Apache с модулем mod_proxy:
RequestHeader set X-Forwarded-Proto "expr=%{REQUEST_SCHEME}"

Без этих заголовков WordPress не сможет правильно определить протокол.

Дополнительные советы по решению проблем с SSL за прокси

  • Проверьте, что в настройках WordPress в Settings > General указаны URL с https://
  • Используйте плагин Clearfy Pro, который помогает управлять безопасностью и оптимизацией, включая корректную работу HTTPS.
  • Если используете WooCommerce, убедитесь, что в настройках включён HTTPS для страниц оформления заказа и личного кабинета.
  • Проверяйте смешанный контент с помощью инструментов браузера и плагинов, например, WPRemark, который помогает выявлять незащищённые ресурсы.

Пример кода для принудительного редиректа на HTTPS с учётом прокси

function wpssl_force_https_redirect() {
    if (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] !== 'on') {
        if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
            return; // Уже HTTPS через прокси
        }
        $redirect_url = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
        wp_redirect($redirect_url, 301);
        exit();
    }
}
add_action('template_redirect', 'wpssl_force_https_redirect');

Этот код проверяет, не является ли текущий запрос HTTPS, учитывая заголовок прокси, и при необходимости выполняет редирект на HTTPS.

Выводы

Правильная настройка SSL и заголовков прокси в WordPress — ключ к стабильной работе сайта за обратным прокси или балансировщиком нагрузки. Использование X-Forwarded-Proto и аналогичных заголовков, а также небольшие доработки в wp-config.php или плагинах помогут избежать множества проблем с безопасностью и отображением сайта.

×

AI-плагин от WPShop.ru

анализирует конкурентов

пишет статьи

готовит SEO

генерирует изображения

и еще кое-что...
WPGPT
Плагин, который наполняет ваш сайт WordPress
Узнать больше