Настройка HTTPS редиректов и HSTS: полное руководство 2026

Настройка HTTPS-редиректов и HSTS — одна из тех задач, которая выглядит простой на бумаге, но на практике регулярно ломает сайты, портит SEO и создаёт дыры в безопасности. За 10 лет работы я разгребал последствия неправильных редиректов не один десяток раз — и всякий раз убеждался, что дьявол в деталях.

Почему это всё ещё актуально в 2026 году

Казалось бы, HTTPS уже давно стал стандартом. Chrome с 2018 года показывает «Небезопасно» для HTTP-сайтов, Let's Encrypt раздаёт бесплатные сертификаты, хостинги научились выдавать SSL в один клик. Но проблемы не исчезли — они просто стали другими.

На прошлой неделе ко мне обратился клиент с интернет-магазином на Битриксе. Сертификат есть, HTTPS работает, но Google Search Console показывает тысячи смешанных URL — часть страниц индексируется как HTTP, часть как HTTPS. Результат: позиции упали, PageSpeed на мобильных просел до 34 баллов, а в консоли браузера — постоянные предупреждения о mixed content. Причина оказалась банальной: редиректы настроены на уровне CMS, но не на уровне сервера, и часть запросов проскакивала мимо.

Или другой случай — клиент настроил HSTS с директивой includeSubDomains, не проверив, что на поддомене old.site.ru живёт HTTP-версия тестового сервера без сертификата. После добавления в preload-список браузеры намертво заблокировали весь трафик на поддомен, а откатиться было уже нельзя — HSTS preload list обновляется месяцами. Пришлось экстренно выпускать сертификат и поднимать HTTPS на тестовом сервере.

Если вас интересует базовая теория, я рекомендую сначала прочитать статью про SSL-сертификаты — там подробно разобрано, как работает TLS и зачем он нужен. А здесь я буду говорить именно о практической настройке редиректов и HSTS.

Как работает HTTPS-редирект: механика и уровни

Редирект с HTTP на HTTPS — это ответ сервера с кодом 301 (постоянный) или 302 (временный). Для SEO и безопасности нужен именно 301. Браузер получает этот ответ, запоминает новый адрес и больше не обращается по старому (в теории). На деле — первый запрос всегда идёт по HTTP, и это окно уязвимости, которое закрывает как раз HSTS.

Редиректы можно настроить на нескольких уровнях, и это важно понимать:

Грубо говоря, правило такое: чем ниже уровень редиректа — тем хуже. Всегда старайтесь выносить это на уровень Nginx или Apache.

Настройка редиректа в Nginx

Nginx — мой основной инструмент на большинстве серверных проектов. Вот правильная конфигурация для перенаправления HTTP → HTTPS:

server {
    listen 80;
    listen [::]:80;
    server_name example.ru www.example.ru;

    # Редирект всего трафика на HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.ru www.example.ru;

    ssl_certificate /etc/letsencrypt/live/example.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.ru/privkey.pem;

    # Современные настройки TLS
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    # HSTS — подробнее об этом ниже
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # Редирект www → без www (или наоборот, по вашему выбору)
    if ($host = www.example.ru) {
        return 301 https://example.ru$request_uri;
    }

    root /var/www/example.ru/public;
    index index.php index.html;

    # ... остальная конфигурация
}

Несколько моментов, на которые обращаю внимание. Во-первых, я использую return 301 вместо rewrite — это быстрее и семантически правильнее. Во-вторых, $host вместо $server_name — это важно, если у вас несколько доменов на одном сервере. В-третьих, http2 прямо в listen — с Nginx 1.25+ рекомендуют использовать отдельную директиву http2 on, но старый синтаксис пока работает.

После изменений не забывайте проверять конфиг и перезагружать Nginx:

nginx -t && systemctl reload nginx
⚠️
Частая ошибка: Если вы используете Cloudflare или другой CDN/прокси, редирект с HTTP на HTTPS может создать бесконечный цикл. Cloudflare по умолчанию может слать запросы на ваш сервер по HTTP, а сервер отвечает редиректом — и так по кругу. Решение: в Cloudflare установите SSL-режим «Full (strict)» и убедитесь, что между Cloudflare и вашим сервером тоже работает HTTPS.

Настройка редиректа в Apache и .htaccess

Apache встречается реже на современных серверах, но на шаред-хостингах — до сих пор норма. И там обычно только .htaccess без доступа к основному конфигу. Вот рабочий вариант:

RewriteEngine On

# Редирект HTTP → HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

# Редирект www → без www (опционально)
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]

# HSTS через Header

    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

Обратите внимание: HSTS-заголовок через .htaccess работает только если включён модуль mod_headers. На большинстве хостингов он есть, но лучше проверить. Также важно, что директива Header always set — именно always, а не просто set. Без always заголовок не будет отправляться с 3xx и 4xx ответами.

Ещё один нюанс для WordPress: если у вас уже стоит файл .htaccess от WordPress с блоком # BEGIN WordPress, вставляйте правила редиректа до этого блока. Иначе WordPress rewrite rules могут перехватить запрос раньше.

Что такое HSTS и почему его недостаточно просто включить

HSTS (HTTP Strict Transport Security) — это HTTP-заголовок, который говорит браузеру: «Этот сайт всегда работает по HTTPS, больше не пробуй HTTP». Браузер запоминает это на время, указанное в max-age, и все последующие запросы автоматически переводит на HTTPS ещё до отправки — без дополнительного round-trip к серверу. Это закрывает атаки типа SSL-stripping.

Выглядит заголовок так:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

Разберём каждую часть:

HSTS preload — отдельная история. Это статический список доменов, который зашит прямо в браузер (Chrome, Firefox, Safari, Edge). Даже если пользователь никогда не посещал ваш сайт, браузер уже знает, что он работает только по HTTPS. Список ведёт Google, добавить домен можно на hstspreload.org.

⚠️
Осторожно с preload: Добавление в HSTS preload list — это практически необратимое действие. Удаление из списка занимает месяцы, и всё это время браузеры будут блокировать HTTP на вашем домене и всех поддоменах. Не добавляйте в preload, если не уверены на 100%, что все поддомены работают по HTTPS.

Я рекомендую такую стратегию внедрения HSTS:

  1. Сначала запустите без HSTS вообще — просто HTTPS-редирект. Убедитесь, что всё работает.
  2. Добавьте HSTS с маленьким max-age=300 (5 минут). Проверьте в браузере, что нет проблем.
  3. Увеличьте до max-age=86400 (1 день). Снова проверьте.
  4. Через неделю поднимите до max-age=2592000 (30 дней).
  5. Через месяц — max-age=31536000 (1 год).
  6. Только после этого, если действительно нужно, добавляйте preload и регистрируйтесь на hstspreload.org.

Mixed content: скрытая проблема после перехода

Вы настроили редирект, включили HSTS, всё работает — но PageSpeed всё равно ругается, и в консоли браузера красные предупреждения. Скорее всего, это mixed content: страница загружается по HTTPS, но внутри неё есть ресурсы (картинки, скрипты, стили), которые подключаются по HTTP.

Браузеры делят mixed content на два типа. Пассивный — картинки, видео, аудио по HTTP. Современные браузеры просто блокируют их без предупреждения. Активный — скрипты, стили, iframes по HTTP. Это критическая угроза, браузер блокирует жёстко.

Как это лечить? Для WordPress есть плагин Really Simple SSL — он автоматически заменяет HTTP на HTTPS в контенте базы данных. Но я предпочитаю делать это вручную через SQL, чтобы понимать что именно меняется:

-- Для WordPress: замена HTTP на HTTPS в контенте
UPDATE wp_posts 
SET post_content = REPLACE(post_content, 'http://example.ru', 'https://example.ru')
WHERE post_content LIKE '%http://example.ru%';

-- Также нужно обновить опции сайта
UPDATE wp_options 
SET option_value = REPLACE(option_value, 'http://example.ru', 'https://example.ru')
WHERE option_value LIKE '%http://example.ru%';

-- И мета-данные постов
UPDATE wp_postmeta 
SET meta_value = REPLACE(meta_value, 'http://example.ru', 'https://example.ru')
WHERE meta_value LIKE '%http://example.ru%';
💡
Совет: Перед выполнением SQL-запросов обязательно сделайте бэкап базы данных. Я всегда делаю дамп прямо перед такими операциями. О том, как правильно организовать резервное копирование, читайте в статье про бэкапы сайта.

Для Битрикса ситуация немного другая — там URL часто хранятся в кеше и в настройках компонентов. После смены протокола нужно сбросить кеш полностью: через административную панель в разделе «Настройки → Инструменты → Кеш», а также вручную очистить папку /bitrix/cache/ и /bitrix/managed_cache/.

Ещё один источник mixed content, о котором часто забывают — внешние ресурсы. Если вы подключаете шрифты Google Fonts, скрипты аналитики или виджеты через HTTP-ссылки в коде темы или шаблона — это тоже mixed content. Проверяйте все хардкодированные URL.

Редиректы www и без www: выбираем одну версию

Это отдельная тема, которую часто путают с HTTPS-редиректами. На деле это два независимых редиректа, и их нужно настраивать вместе. Правила простые: выберите одну каноническую версию домена и перенаправляйте на неё всё остальное.

Я предпочитаю версию без www — она короче, и большинство современных сайтов используют именно её. Но это вкусовщина, главное — последовательность. Если у вас site.ru в Google Search Console добавлен без www, а редирект стоит на www — вы теряете сигналы и запутываете поисковики.

В Nginx правильная схема выглядит так: четыре варианта входящего трафика → один канонический. http://www.site.ruhttps://site.ru, http://site.ruhttps://site.ru, https://www.site.ruhttps://site.ru. И только https://site.ru обслуживается нормально.

Для этого я обычно делаю два server-блока для HTTP (с www и без) и один отдельный server-блок для https://www, который редиректит на канонический вариант. Это чище, чем городить сложные if-условия в одном блоке.

По теме SEO-редиректов — рекомендую почитать подробную статью про 301 редиректы, там разобраны все нюансы передачи ссылочного веса.

Как проверить правильность настройки

После настройки редиректов и HSTS нужно убедиться, что всё работает как задумано. Вот мой чек-лист.

Проверка цепочки редиректов. Используйте curl в терминале — это самый надёжный способ:

# Проверяем редирект с HTTP
curl -I http://example.ru

# Должны увидеть:
# HTTP/1.1 301 Moved Permanently
# Location: https://example.ru/

# Проверяем редирект www
curl -I https://www.example.ru

# Должны увидеть:
# HTTP/1.1 301 Moved Permanently
# Location: https://example.ru/

# Проверяем HSTS заголовок
curl -I https://example.ru | grep -i strict

# Должны увидеть:
# strict-transport-security: max-age=31536000; includeSubDomains

Также использую онлайн-инструменты: SSL Labs (ssllabs.com/ssltest) даёт полный анализ SSL-конфигурации с оценкой A/B/C. Цель — оценка A+. securityheaders.com проверяет все заголовки безопасности, включая HSTS. redirect-checker.org показывает полную цепочку редиректов визуально.

Обратите внимание на длину цепочки редиректов. Каждый дополнительный редирект — это дополнительный round-trip и задержка. Идеально: один редирект с HTTP на HTTPS. Если у вас цепочка из трёх и более редиректов — это проблема для скорости и SEO. Подробнее о влиянии на скорость загрузки читайте в статье почему сайт медленно работает.

ℹ️
Для WordPress: Если вы используете плагин для HTTPS-редиректов (типа Really Simple SSL), убедитесь, что на уровне сервера редирект тоже настроен. Плагин — это страховка, но не основной механизм. При деактивации плагина сайт не должен «разваливаться». Если хотите разобраться с комплексной безопасностью WordPress, загляните на страницу поддержки WordPress-сайтов — там можно заказать аудит.

Особенности для Битрикс и Laravel

С Битриксом есть одна специфика: он любит самостоятельно управлять заголовками и иногда перезаписывает HSTS. Я видел случаи, когда Битрикс добавлял свой Strict-Transport-Security с max-age=0 — то есть фактически отключал HSTS. Это происходит в некоторых версиях ядра при определённых настройках безопасности.

Решение: либо настраивать HSTS в Nginx с директивой always (она перезаписывает заголовки из приложения), либо явно прописывать нужный заголовок в настройках Битрикса через /bitrix/.settings.php или через модуль «Безопасность» в административной панели.

Для Laravel всё намного чище. В Laravel 10+ есть middleware SecureHeaders, но честно говоря, я предпочитаю настраивать HSTS на уровне Nginx, а не в PHP-коде. Это быстрее и надёжнее. Если всё же нужно через Laravel — в app/Http/Middleware/TrustProxies.php добавьте нужные заголовки, а в конфиге session.php убедитесь, что 'secure' => true.

Ещё важный момент для Laravel: если приложение стоит за reverse proxy (Nginx → PHP-FPM), Laravel может не определить HTTPS корректно. Тогда генерируемые URL будут с HTTP, и вы получите mixed content несмотря на все настройки. Фикс — в AppServiceProvider:

Для Битрикса аналогичная проблема решается в /bitrix/php_interface/dbconn.php или через константу SITE_SERVER_NAME в конфигурации. Если работаете с Битриксом на постоянной основе, загляните на страницу поддержки Битрикс — такие вещи я часто разбираю в рамках технического аудита.

SEO-аспекты: что важно не упустить

После перехода на HTTPS и настройки редиректов нужно обновить ряд вещей с точки зрения SEO. Во-первых — Google Search Console. Добавьте HTTPS-версию домена как отдельный ресурс (если ещё не добавлена) и запросите переиндексацию. Google обычно подхватывает переезд на HTTPS быстро — за 2-4 недели, но лучше ускорить процесс через подачу sitemap.

Во-вторых — sitemap.xml. Убедитесь, что в нём все URL с HTTPS. Если генерируется автоматически (WordPress плагином, Битриксом), проверьте настройки домена в CMS. В-третьих — canonical теги. Они должны указывать на HTTPS-версию.

В-четвёртых — внешние ссылки и обратные ссылки. Это вы контролировать не можете, но редирект 301 передаёт большую часть ссылочного веса (по данным Google — практически весь, хотя исторически считалось, что теряется 10-15%).

По опыту: сайты, правильно переехавшие на HTTPS с одним чистым 301-редиректом, восстанавливают позиции в течение 2-6 недель. Сайты с кривой цепочкой редиректов или mixed content могут просесть на несколько месяцев. Так что делайте правильно с первого раза.

Если планируете комплексный технический аудит после перехода, обратите внимание на услугу доработки сайта — я помогаю разобраться с техническими проблемами, которые влияют на SEO и скорость.

Типичные ошибки, которые я вижу постоянно

За годы практики собрал целый зоопарк косяков. Перечислю самые частые.

Редирект только главной страницы. Настраивают редирект для example.ru, но забывают про example.ru/catalog/ и example.ru/blog/. Правило должно покрывать все пути — $request_uri в Nginx делает это автоматически.

Смешанные редиректы. На уровне Nginx редирект с HTTP на HTTPS, на уровне CMS — редирект с www на без www. В итоге получается цепочка из двух редиректов вместо одного. Всегда объединяйте логику редиректов в одном месте.

HSTS на HTTP-сервере. Видел такое несколько раз — добавляют HSTS-заголовок в HTTP server-блок. Это бессмысленно: браузер получает заголовок по небезопасному соединению и игнорирует его. HSTS работает только если отправляется по HTTPS.

Забытые поддомены. Включают includeSubDomains, не проверив все поддомены. Особенно часто страдают mail.*, ftp.*, dev.* и другие служебные поддомены без SSL-сертификата.

Короткий max-age на продакшене. Оставляют max-age=300 с тестирования и забывают поднять. В результате HSTS не даёт реального эффекта — браузер запоминает правило только на 5 минут.

Не обновлённые хардлинки в коде. В шаблоне или компонентах прописаны абсолютные URL вида http://example.ru/images/logo.png. После перехода на HTTPS это mixed content, который браузер заблокирует. Используйте относительные пути или protocol-relative URLs (//example.ru/...).

Честно говоря, большинство этих ошибок возникают не от незнания, а от спешки. Переход на HTTPS — это не «поставил галочку и забыл», это полноценная миграция, требующая тестирования. Прочитайте также полный чек-лист перехода на HTTPS — там я собрал всё, что нужно проверить перед и после переезда.

Итог: порядок действий

Подытожу правильный порядок настройки для нового сайта или при переезде существующего.

  1. Выпустите SSL-сертификат (Let's Encrypt через Certbot или от хостинга).
  2. Настройте HTTPS server-блок в Nginx/Apache и убедитесь, что сайт открывается по https://.
  3. Проверьте mixed content — откройте DevTools, вкладка Console и Network, фильтр по «Mixed Content».
  4. Устраните mixed content в базе данных, коде шаблона, внешних ресурсах.
  5. Добавьте 301-редирект с HTTP на HTTPS на уровне сервера.
  6. Настройте редирект www ↔ без www (выберите одну версию).
  7. Добавьте HSTS с max-age=300, проверьте в браузере.
  8. Постепенно увеличивайте max-age до 31536000.
  9. Обновите sitemap, canonical теги, настройки в Search Console.
  10. Через месяц стабильной работы решите, нужен ли preload.

Это не быстрый процесс, но именно такой подход позволяет избежать проблем. Я видел слишком много сайтов, где HTTPS «настроен», но на деле — полуработающий редирект, mixed content на каждой второй странице и HSTS с max-age=60. Делайте по-человечески с первого раза — сэкономите себе нервы и деньги на исправление.

Хотите защитить свой сайт с помощью HTTPS и HSTS?

Наши специалисты настроят безопасные редиректы и HSTS-политику для вашего сайта быстро и без ошибок.

П
Павел
Веб-разработчик · 10+ лет опыта · Bitrix, WordPress, Laravel

Читайте также

Настройка мультидоменного сайта: полное руководство 2026 Настройка cron jobs: автоматические задачи на сайте в 2026 Как исправить ошибки на сайте: чек-лист