// Engineering Log
HTTP, HTTPS и TLS: Часть 7 — Переход на HTTPS: редиректы, HSTS, HTTPS-First и заголовок Upgrade
Опубликовано 09.10.2026
// Быстрый маршрут
Эта статья относится к теме Серверы и инфраструктура.
Пользователь набирает в адресной строке example.ru без схемы, переходит по старой ссылке http://… или открывает закладку десятилетней давности. Во всех этих случаях первый запрос может уйти по открытому HTTP, и задача владельца сайта — чтобы дальше всё шло по HTTPS, а в идеале — чтобы открытого запроса не было вовсе. Для этого существует несколько механизмов, которые работают на разных этапах: редирект на сервере, HSTS, встроенный список preload, режим HTTPS-First в браузере, DNS-запись типа HTTPS. Отдельно разобран заголовок Upgrade, с которым часто путают «HTTPS upgrade»: он переключает соединение на другой протокол, например WebSocket.
Редирект с HTTP на HTTPS
Базовый уровень — сервер на порту 80 отвечает перенаправлением на тот же адрес по HTTPS:
server {
listen 80;
listen [::]:80;
server_name example.ru www.example.ru;
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt; # проверка Let's Encrypt HTTP-01
}
location / {
return 301 https://$host$request_uri;
}
}Что важно:
- 301 или 308. Оба — постоянные редиректы, поисковики переносят на новый адрес вес страницы. 308 сохраняет метод и тело запроса; при 301 браузер превращает POST в GET. Для сайта разница незаметна, для API, куда клиенты по ошибке шлют POST на
http://, лучше 308. - Сохраняйте путь.
$request_uriсодержит путь и параметры. Редирект всех страниц на главную ломает ссылки и поисковую выдачу. - Один шаг. Цепочка
http://example.ru→https://example.ru→https://www.example.ru— два лишних круга. Сразу направляйте на итоговый адрес. - Let’s Encrypt HTTP-01 следует редиректам, поэтому отдельный
locationдляacme-challengeне обязателен, но избавляет от сюрпризов при нестандартных настройках.
Слабое место редиректа: первый запрос всё равно идёт открыто. Злоумышленник в той же сети (например, в публичном Wi-Fi) может перехватить его и не пускать пользователя на HTTPS, отдавая ему сайт по HTTP через себя. Этот приём называется SSL stripping, и защищает от него HSTS.
HSTS
HSTS (HTTP Strict Transport Security, RFC 6797) — заголовок ответа, которым сайт сообщает браузеру: «в течение указанного срока обращайся ко мне только по HTTPS».
Strict-Transport-Security: max-age=31536000; includeSubDomainsmax-age— срок в секундах (31536000 — один год). Каждый ответ с заголовком продлевает срок;includeSubDomains— правило распространяется на все поддомены;preload— согласие на включение в список preload (ниже).
Получив заголовок, браузер:
- сам переписывает любые
http://ссылки на этот сайт вhttps://ещё до отправки запроса — редирект сервера больше не нужен (в инструментах разработчика это видно как307 Internal Redirect); - не даёт пользователю пропустить ошибку сертификата: кнопки «Всё равно перейти» нет.
Правила:
- браузер принимает заголовок только по HTTPS; в ответе по HTTP он игнорируется;
- начинайте с небольшого
max-age(300, потом 86400, потом неделя) и увеличивайте, когда убедитесь, что всё работает по HTTPS. Отменить HSTS быстро нельзя: браузеры, запомнившие заголовок, будут требовать HTTPS до конца срока; includeSubDomainsпроверяйте особенно внимательно: если у вас естьintranet.example.ruилиprinter.example.ruбез HTTPS, после этого они перестанут открываться у всех, кто посетил основной сайт.
В Nginx:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;Список HSTS preload
HSTS начинает действовать после первого визита по HTTPS. Первый визит остаётся незащищённым. Чтобы закрыть и его, существует список preload — перечень доменов, который встроен в Chrome, Firefox, Safari и Edge. Для доменов из списка браузер использует только HTTPS с самого первого запроса.
Требования для включения (hstspreload.org):
- действующий сертификат;
- редирект с HTTP на HTTPS на том же имени хоста;
- все поддомены доступны по HTTPS;
- заголовок на основном домене:
max-ageне меньше 31536000,includeSubDomainsиpreload.
Подать заявку можно на hstspreload.org, попадание в стабильные версии браузеров занимает недели. Удаление из списка занимает месяцы и не действует на старые версии браузеров, поэтому preload — решение необратимое на практике. Некоторые доменные зоны включены в список целиком: все сайты в .dev, .app, .page работают только по HTTPS.
HTTPS-First в браузерах
Браузеры не ждут, пока сайт настроит HSTS, и сами пробуют HTTPS.
- Chrome с версии 115 (2023) при переходе на
http://сначала пробует HTTPS и при неудаче откатывается на HTTP (HTTPS-Upgrades). Настройка «Всегда использовать безопасные подключения» (Always Use Secure Connections) дополнительно предупреждает перед открытием сайта по HTTP. Google объявил, что в Chrome 154 (октябрь 2026 года) эта настройка будет включена по умолчанию: браузер будет спрашивать пользователя перед первым заходом на публичный сайт без HTTPS и не станет повторять предупреждение для сайтов, которые пользователь посещает регулярно. Для пользователей с усиленным режимом Safe Browsing она включена с апреля 2026 года. - Firefox с версии 136 (март 2025) работает в режиме HTTPS-First по умолчанию: пробует HTTPS и откатывается на HTTP, если сайт не отвечает. Отдельно есть более строгий режим HTTPS-Only.
- Safari также пробует HTTPS для адресов без схемы.
Что это значит для владельца сайта: если по HTTPS на вашем домене открывается что-то другое, чем по HTTP (заглушка хостинга, чужой сайт на том же IP, ошибка сертификата), пользователи всё чаще будут видеть именно это. HTTPS должен работать на всех именах, которые вы публикуете, а сайты без HTTPS будут сопровождаться предупреждением.
Upgrade-Insecure-Requests и смешанное содержимое
Смешанное содержимое (mixed content) — страница по HTTPS, которая загружает скрипты, стили или картинки по HTTP. Браузеры блокируют такие скрипты, стили и фреймы, а картинки, видео и аудио пытаются загрузить по HTTPS, и если не получается — не показывают.
Две похожие по названию вещи:
Заголовок запроса
Upgrade-Insecure-Requests: 1. Браузер отправляет его при переходе на страницу, сообщая: «я предпочитаю HTTPS». Сервер может ответить на него редиректом на HTTPS. На практике для этого достаточно обычного редиректа, заголовок используется редко.Директива CSP
upgrade-insecure-requests. Заголовок ответа, который велит браузеру переписать всеhttp://ресурсы на странице вhttps://перед загрузкой:Content-Security-Policy: upgrade-insecure-requestsПолезно при переносе старого сайта, в базе которого тысячи ссылок на картинки с
http://: пока ссылки не исправлены, директива убирает предупреждения. Ресурсы должны быть доступны по HTTPS — директива не создаёт HTTPS там, где его нет.
DNS-запись HTTPS
Запись типа HTTPS (RFC 9460) сообщает клиенту параметры подключения до первого запроса:
example.ru. 3600 IN HTTPS 1 . alpn="h3,h2" ipv4hint=192.0.2.10- само наличие записи говорит браузеру, что сайт доступен по HTTPS: Chrome и Firefox в этом случае сразу идут на
https://, минуя открытый HTTP, так же как при HSTS; alpn— какие протоколы поддерживаются; сh3браузер может сразу подключаться по HTTP/3;ech— ключ для Encrypted Client Hello;ipv4hint,ipv6hint— адреса, чтобы не ждать ответа на A/AAAA.
Запись поддерживают Cloudflare (создаёт её автоматически) и часть DNS-хостингов. Проверка: dig HTTPS example.ru.
Заголовок Upgrade: переключение протокола
Upgrade — механизм HTTP/1.1 для перехода с HTTP на другой протокол внутри того же TCP-соединения. Клиент предлагает, сервер соглашается ответом 101 Switching Protocols, и дальше по соединению идёт уже новый протокол.
WebSocket (RFC 6455) — главный пример. Чем WebSocket отличается от SSE и long polling и когда какой выбирать — в статье «WebSockets, Long Polling и SSE». Здесь — как выглядит сам переход:
GET /ws HTTP/1.1
Host: example.ru
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=Адрес wss:// — это WebSocket поверх TLS, то есть сначала устанавливается HTTPS, а внутри него — Upgrade.
Upgrade и Connection — заголовки одного участка пути, и прокси их не передаёт дальше. Поэтому для WebSocket за Nginx нужна явная настройка:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
location /ws/ {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s; # по умолчанию 60 с — простаивающее соединение закроется
}
}Без этих строк клиент получит 400 или 426, а в журнале приложения будет обычный GET без Upgrade.
В HTTP/2 и HTTP/3 заголовка Upgrade нет. WebSocket в них открывается через расширенный метод CONNECT (RFC 8441 для HTTP/2, RFC 9220 для HTTP/3) с псевдозаголовком :protocol: websocket. Браузеры и серверы договариваются об этом сами; Nginx с приложением по-прежнему общается по HTTP/1.1.
Другие применения Upgrade:
Upgrade: h2c— переход на HTTP/2 без шифрования. Браузеры его никогда не поддерживали, а RFC 9113 (2022) признал этот способ устаревшим. Прокси, которые пропускаютUpgrade: h2cк приложению, иногда позволяют обойти их правила доступа (h2c smuggling) — такие заголовки лучше отбрасывать на входе;Upgrade: TLS/1.0— переход на TLS внутри HTTP-соединения (RFC 2817). В вебе не прижился; вместо него используется отдельный порт 443.
Если сервер требует перехода на другой протокол, он отвечает кодом 426 Upgrade Required с заголовком Upgrade, где указан нужный протокол.
Порядок перевода сайта на HTTPS
- Выпустить сертификат на все используемые имена, включая
www, и настроить автоматическое продление. - Проверить, что сайт полностью работает по HTTPS: внутренние ссылки, картинки, формы, сторонние виджеты. Для старых ссылок в содержимом — CSP
upgrade-insecure-requests. - Включить редирект 301 с HTTP на HTTPS, сохраняя путь.
- Указать
https://в канонических адресах, карте сайта, в Яндекс Вебмастере и Google Search Console. - Включить HSTS с коротким
max-age, через несколько недель — год иincludeSubDomains. - Если уверены во всех поддоменах — подать домен в список preload.
Типичные ошибки
- Бесконечный редирект: приложение за прокси не видит
X-Forwarded-Proto: httpsи снова отправляет на HTTPS; то же бывает с Cloudflare в режиме Flexible. - HSTS с
includeSubDomainsна основном домене при поддоменах без HTTPS — внутренние сервисы перестают открываться. - Заголовок HSTS отдаётся по HTTP — браузер его игнорирует, защиты нет.
- Редирект на главную вместо той же страницы.
- WebSocket за Nginx без
proxy_http_version 1.1и заголовковUpgrade/Connection, либо сproxy_read_timeoutпо умолчанию — соединения рвутся раз в минуту.
// Похожая задача
Если у вас похожая ситуация
Эта статья относится к одной из рабочих тем. Можно продолжить чтение по теме, перейти на главную, чтобы понять, чем я занимаюсь, или сразу открыть услуги.
Тема статьи
Серверы и инфраструктура
VPS, Linux, веб-стек, миграции, хостинг, базы данных и базовая эксплуатация.
Часто с этим приходят
- Перенести сайт или сервис на новый сервер
- Настроить Linux, Nginx, базу данных и бэкапы
- Разобраться, почему всё работает нестабильно
// Следующий шаг
Если вам нужна не только статья, а помощь по этой теме, удобнее сразу перейти в услугу. Главная и подборка материалов остаются рядом.
Открыть услуги// Reviews
Отзывы по теме
Спасибо Михаилу за отзывчивость. Созвонились, объяснил как сделать самому. Обращаюсь уже второй раз, все супер и оперативно.
Спасибо Михаилу за отзывчивость. Созвонились, объяснил как сделать самому. Обращаюсь уже второй раз, все супер и оперативно.
Хочу выразить огромную благодарность специалисту, который настроил мне ЧПУ на OpenCart. Настроить ЧПУ оказалось легко и просто, и я рад, что наконец нашел профессионала, который сделал всё качественно и без лишних сложностей. До этого я сменил четырёх специалистов, и каждый раз возникали проблемы с настройкой, но этот человек справился с задачей идеально.
Хочу выразить огромную благодарность специалисту, который настроил мне ЧПУ на OpenCart. Настроить ЧПУ оказалось легко и просто, и я рад, что наконец нашел профессионала, который сделал всё качественно и без лишних …
Отличная работа, обращаюсь не первый раз, находит решения к сложным задачам. Рекомендую.
Отличная работа, обращаюсь не первый раз, находит решения к сложным задачам. Рекомендую.
Отличная работа! Выполнил поставленную задачу в срок и без ошибок. Было приятно сотрудничать, рекомендую.
Отличная работа! Выполнил поставленную задачу в срок и без ошибок. Было приятно сотрудничать, рекомендую.
Отличный специалист, вник в проблему, разобрался, исправил. Рекомендую.
Отличный специалист, вник в проблему, разобрался, исправил. Рекомендую.
Нужно было решить проблему с SSL сертификатом на сервере, который был выпущен через Ngnix Proxy manager. Михаил уточнил все детали, как у меня все устроено, попросил доступы чтобы оценить реальность решения задачи, т. к. до этого не сталкивался с подобным сервисом. Быстро разобрался и решил мою проблему. Идеальное сотрудничество)
Нужно было решить проблему с SSL сертификатом на сервере, который был выпущен через Ngnix Proxy manager. Михаил уточнил все детали, как у меня все устроено, попросил доступы чтобы оценить реальность решения задачи, т. …
Диагностика Nginx Proxy Manager в docker контейнере и решение проблемы
15.03.2024 · ★ 5/5
// Contact
Нужна помощь?
Свяжись со мной и я помогу решить проблему
Написать в TelegramОтвечаю в течение рабочего дня (03:00–13:00 GMT)
Или оставьте заявку здесь:
// Related