Как перенаправить все HTTP-запросы в HTTPS


294

Я пытаюсь перенаправить все незащищенные HTTP-запросы на моем сайте (например http://www.example.com) в HTTPS ( https://www.example.com). Я использую PHP, кстати. Могу ли я сделать это в .htaccess?


1
Вы можете (и должны) сделать это через ваш httpd, а не через PHP.
drudge

2
@jnpcl, хотя я согласен с тем, что решение httpd лучше, чем решение на основе PHP, я не думаю, что систематическое перенаправление является хорошей практикой в ​​целом. Если вы хотите постоянно перенаправлять своих пользователей на HTTPS, отправляйте их туда из «точки входа» (первой ссылки на ваш сайт), не делайте этого на полпути, что может привести к утечке некоторых данных, которые вы считаете защищен (если вы не заметите, что мгновенное перенаправление).
Бруно

@Bruno: я больше думал о дублированных HTTP-запросах, о вероятности потерянных строк запросов и о возможности ввода вручную пользователемhttp://
drudge

@jnpcl это хорошая точка зрения. Я просто предположил, что, хотя люди, как правило, просят такого рода перенаправление для повышения безопасности своего сайта, часто это не улучшается (так как это не мешает тому же запросу сначала пройти через простой HTTP) ,
Бруно

8
@outis: первая ссылка, которую вы разместили, - это вопрос.
Мэй

Ответы:


305

Обновление: хотя этот ответ был принят несколько лет назад, обратите внимание, что его подход в настоящее время рекомендуется в документации Apache. Используйте Redirectвместо. Смотрите этот ответ .


RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

24
@Cat, как я уже говорил в своем ответе / комментариях, если вы пытаетесь «перенаправить все небезопасные HTTP [...] на HTTPS», этот подход не сделает эти запросы безопасными, он просто заставит их делать браузер дважды, один раз небезопасный и один раз безопасный.
Бруно

13
Что вы действительно должны делать, так это использовать HSTS вместе с этим.
Риз Мур

3
Это может быть ошибкой в ​​моей версии apache (2.4.6, упакованной в Centos 7), но у меня есть проблемы с некоторыми URL. Например, http://server/foo?email=someone%40example.comпереадресация на https://server/foo?email=someone%2540example.comт. Е. Знак "@" получает URL-кавычки дважды . Использование метода в ответе @ ssc не имеет этой проблемы.
psmears

2
Неправильный ответ. Он будет перенаправлять только базовые URL-адреса, а не URL-адреса в подпапках. RewriteRule (. *) Https: //% {HTTP_HOST}% {REQUEST_URI} [R = 301, L] - правильный ответ
FredTheWebGuy

7
Они не обязательно рекомендуют против этого:In the case of the http-to-https redirection, the use of RewriteRule would be appropriate if you don't have access to the main server configuration file, and are obliged to perform this task in a .htaccess file instead.
Адам

338

Документы Apache рекомендуют не использовать переписывание:

Чтобы перенаправить httpURL-адреса https, выполните следующие действия:

<VirtualHost *:80>
    ServerName www.example.com
    Redirect / https://www.example.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName www.example.com
    # ... SSL configuration goes here
</VirtualHost>

Этот фрагмент должен входить в основной файл конфигурации сервера, а не в то, .htaccessчто задано в вопросе.

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


11
Это должен быть текущий ответ. Но что именно входит в «конфигурацию SSL»? Полный пример был бы действительно полезен.
Бен

6
@Ben: это другой вопрос, который подробно документирован в Интернете; кстати, я только вчера добавил почти полный пример: serverfault.com/q/597012/26210, который может дать вам представление о том, что происходит в конфигурации SSL
ssc

46
Это отличный намек. Но в документации Apache также упоминается: «В случае перенаправления http-to-https использование RewriteRule было бы целесообразно, если у вас нет доступа к главному файлу конфигурации сервера, и вы обязаны выполнить эту задачу в вместо этого файл .htaccess. " Что касается меня ...
peter_the_oak

4
@ user1844933 Если вы используете permanentключевое слово, эффект тот же (браузер получает перенаправление 301). Например:Redirect permanent "/" "https://example.com"
BeetleJuice

2
@Whitecat В Centos 6 файл находится по адресу /etc/httpd/conf/httpd.conf
dstonek

141

Я бы рекомендовал с 301 редиректом:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

7
спасибо, это работает для меня, принятого ответа нет .. вероятно, из-за отсутствия[L]
billynoah

1
Ага. Это правильный ответ, поскольку он также направляет все URL-адреса в подпапках
FredTheWebGuy

Это на верхнем уровне файла htaccess?
CodyBugstein

1
@CodyBugstein Вот где я всегда его размещаю, и это всегда работает.
Даан ван ден Берг

3
Во всех ответах отсутствует одна вещь - любой код для перенаправления должен быть помещен в самом начале вашего файла .htaccess, ДО чего-либо еще, если вы хотите, чтобы все страницы были перенаправлены на https.
Вадим Анисимов

35

Как я уже говорил в этом вопросе , я бы посоветовал вам не перенаправлять все HTTP-запросы к их HTTPS-эквиваленту вслепую, так как это может вызвать у вас ложное впечатление о безопасности. Вместо этого вам, вероятно, следует перенаправить «корень» вашего сайта HTTP в корень вашего сайта HTTPS и ссылаться оттуда только на HTTPS.

Проблема заключается в том, что если какая-либо ссылка или форма на сайте HTTPS заставляет клиента отправить запрос на сайт HTTP, его содержимое будет видно до перенаправления.

Например, если одна из ваших страниц, обслуживаемых по HTTPS, имеет форму, которая сообщает <form action="http://example.com/doSomething">и отправляет некоторые данные, которые не следует отправлять в незашифрованном виде, браузер сначала отправит полный запрос (включая сущность, если это POST) на сайт HTTP первый. Перенаправление будет немедленно отправлено в браузер, и, поскольку большое количество пользователей отключает или игнорирует предупреждения, оно, вероятно, будет проигнорировано.

Конечно, ошибка предоставления ссылок, которые должны быть на сайт HTTPS, но которые в конечном итоге принадлежат сайту HTTP, может вызвать проблемы, как только вы услышите что-то, прослушивающее порт HTTP на том же IP-адресе, что и ваш сайт HTTPS. Тем не менее, я думаю, что сохранение этих двух сайтов в качестве «зеркала» только увеличивает вероятность ошибок, поскольку вы можете предположить, что он самокорректируется, перенаправляя пользователя на HTTPS, в то время как часто бывает слишком поздно. (В этом вопросе были похожие обсуждения . )


1
При принятии решения обслуживать весь сайт как HTTPS такое перенаправление имеет смысл. Я не хочу, чтобы пользователь получил 403, потому что он указал http для своей целевой страницы. Я согласен, если кто-то УКАЗЫВАЕТ http в ссылке и использует его для производства, которое НЕ ПРАВИЛЬНО. Это ДОЛЖНО быть поймано во время тестирования, даже с перенаправлением на месте. Мне не нравится аргумент «мог», потому что это могло бы произойти без перенаправления. Симптомы одинаковы при тестировании в безопасном браузере, за исключением того, что он подтверждает отправку открытым текстом, который он перенаправляет вместо получения 403.
Дерек Лиц

Да, я вижу преимущество в том, чтобы терпеть неудачу, если кто-то по ошибке вводит http в действие формы, но в большинстве случаев важнее проявлять снисходительность при вводе URL-адресов.
Даниэль Любаров

4
@ Даниэль, я согласен, что полезно быть снисходительным, когда пользователи вводят URL. Я бы сказал, что это один из случаев, когда лучше отключить эту функцию во время разработки / тестирования, но включить ее на производстве (или на последних этапах разработки / тестирования).
Бруно

почему бы не сделать http в https на днс.
Мухаммед Умер

1
@MuhammadUmer, потому что это не имеет ничего общего с DNS. В целом они будут использовать одно и то же имя хоста, но даже с другим именем хоста вам все равно придется изменить протокол и порт.
Бруно

18

Я обнаружил, что лучший способ для https и www на домене

RewriteCond %{HTTPS} off 
RewriteCond %{HTTPS_HOST} !^www.example.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]

Это не будет перенаправлять, http://www.example.com/...потому что два условия неявно AND'd. Вместо этого они должны быть OR, т.е. включите ORфлаг в первое условие (и не забывайте избегать буквальных точек в регулярном выражении). Но если вы реализуете HSTS, то вы не хотите перенаправлять на HTTPS и www в одном перенаправлении, вам следует сначала перенаправить на HTTPS .
MrWhite

Где я могу разместить этот текст?
Аарон Франке

По схожему типу вопроса. Кто-нибудь может помочь с вопросом ниже? stackoverflow.com/questions/59503217/…
appsntech

14

Это подход html redirect, он работает, но не самый лучший.

 <meta http-equiv="Refresh" content="0;URL=https://www.example.com" />

PHP подход

<?php
function redirectTohttps() {
    if ($_SERVER['HTTPS']!="on") {
        $redirect= "https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
        header("Location:$redirect"); 
    } 
}
?>

.htaccess

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

скопировано с: www.letuslook.org


Куда .htaccessидет? Кроме того, эта ссылка не работает.
Аарон Франке

8

Мне нравится этот метод перенаправления с http на https. Потому что мне не нужно редактировать его для каждого сайта.

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

Где я могу разместить этот текст?
Аарон Франке

6

Использование следующего кода в вашем файле .htaccess автоматически перенаправляет посетителей на HTTPS-версию вашего сайта:

RewriteEngine On

RewriteCond %{HTTPS} off

RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Если у вас есть файл .htaccess:

Не дублируйте RewriteEngine On.

Убедитесь, что строки, начинающиеся с RewriteCond и RewriteRule, следуют сразу за уже существующим RewriteEngine On.


Что означают L и R?
Аарон Франке

5

Это правильный метод перенаправления HTTP на HTTPS с использованием .htaccess в соответствии с GoDaddy.com. Первая строка кода не требует пояснений. Вторая строка кода проверяет, отключен ли HTTPS, и, если это так, перенаправляет HTTP на HTTPS, выполняя третью строку кода, в противном случае третья строка кода игнорируется.

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

https://www.godaddy.com/help/redirect-http-to-https-automatically-8828


5

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

Если вы работаете с веб-сервером Apache и можете изменить его конфигурацию, следуйте документации Apache :

<VirtualHost *:80>
    ServerName www.example.com
    Redirect "/" "https://www.example.com/"
</VirtualHost>

<VirtualHost *:443>
    ServerName www.example.com
    # ... SSL configuration goes here
</VirtualHost>

Но вы также спросили, можете ли вы сделать это в .htaccessфайле. В этом случае вы можете использовать Apache RewriteEngine :

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L]

Если все работает нормально и вы хотите, чтобы браузеры запомнили это перенаправление, вы можете объявить его постоянным, изменив последнюю строку на:

RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Но будьте осторожны, если вы можете изменить свое мнение об этом перенаправлении. Браузеры запоминают это очень долго и не проверят, изменилось ли оно.

Вам может не понадобиться первая строка RewriteEngine On зависимости от конфигурации веб-сервера.

Если вы ищете решение PHP, посмотрите на массив $ _SERVER и функцию header :

if (!$_SERVER['HTTPS']) {
    header("Location: https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); 
} 

Кажется, что документация Apache рекомендует против переписать маршрут. Как насчет Redirect? Что еще может пойти в.htaccess файл?
Аарон Франке

Да, Redirect является предпочтительным и может использоваться в .htaccess. Но вы не можете добавить условие только для перенаправления http трафика на https. Он также перенаправляет https -> бесконечный цикл перенаправления. Я перечислил это в директиве VirtualHost, используемой для http (порт 80) выше, .htaccess не поддерживает эту директиву и, следовательно, Redirect не может быть использован здесь.
Майкл

4

Добавьте следующий код в файл .htaccess:

Options +SymLinksIfOwnerMatch
RewriteEngine On
RewriteCond %{SERVER_PORT} !=443
RewriteRule ^ https://[your domain name]%{REQUEST_URI} [R,L]

Где [ваше доменное имя] является доменным именем вашего сайта.

Вы также можете перенаправить определенные папки с вашего доменного имени, заменив последнюю строку кода выше на:

RewriteRule ^ https://[your domain name]/[directory name]%{REQUEST_URI} [R,L]

Что означают L и R?
Аарон Франке

4

Сделайте все, что описано выше для перенаправления. Просто добавьте «HTTP Strict Transport Security» в свой заголовок. Это позволит избежать человека в середине атаки.

Отредактируйте ваш файл конфигурации apache (например, /etc/apache2/sites-enabled/website.conf и /etc/apache2/httpd.conf) и добавьте следующее в VirtualHost:

# Optionally load the headers module:
LoadModule headers_module modules/mod_headers.so

<VirtualHost 67.89.123.45:443>
    Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
</VirtualHost>

https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security


2

Чтобы перенаправить все httpзапросы https, вы можете использовать:

RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [NE,L,R]

Если mod-rewrite не включен и вы используете apache 2.4, вы также можете использовать директиву Redirectinside ifдля перенаправления httpзапросов https.

Апач 2.4.

<if "%{HTTPS} !~ /on/">
Redirect / https://www.example.com/
</if>

2

Если вы находитесь в ситуации, когда вы не можете получить доступ к конфигурации apache напрямую для своего сайта, поскольку многие размещенные платформы по-прежнему ограничены таким образом, то я бы фактически рекомендовал двухэтапный подход. Причина, по которой сами Apache документируют, что вы должны использовать их параметры конфигурации в первую очередь над mod_rewrite для HTTP к HTTPS.

Во-первых, как упоминалось выше, вы должны настроить свои правила .htaccess mod_rewrite:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Затем в ваших файлах PHP (вам нужно делать это там, где это будет уместно для вашей ситуации, некоторые сайты направляют все запросы через один файл PHP, другие обслуживают различные страницы в зависимости от своих потребностей и выполняемого запроса. ):

<?php if ($_SERVER['HTTPS'] != 'on') { exit(1); } ?>

Выше необходимо запустить ДО любого кода, который потенциально может предоставить защищенные данные в незащищенной среде. Таким образом, ваш сайт использует автоматическое перенаправление через HTACCESS и mod_rewrite, в то время как ваши скрипты гарантируют, что выходные данные не будут предоставлены, если к ним нет доступа через HTTPS.

Я думаю, что большинство людей так не думают, и поэтому Apache рекомендует не использовать этот метод, где это возможно. Однако для обеспечения безопасности данных вашего пользователя требуется дополнительная проверка в конце разработки. Надеемся, что это поможет кому-то еще, кому, возможно, придется изучить использование нерекомендованных методов из-за ограничений нашего хостинга.


1

Через .htaccess это поможет.

RewriteEngine On


RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]

RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]

Кроме того, обратитесь к этому для более подробной информации. Как перенаправить Http в Https?


1
Это готовое решение для тех, кто получает сообщение «Ошибка слишком большого числа перенаправлений» и не может изменить свойство allowOverride.
Evochrome

1

Если вам не нужен mod_rewrite для других целей, использование основной директивы IF Apache будет чище и быстрее:

<If "%{HTTPS} == 'off'">
Redirect permanent / https://yoursite.com/
</If>

Вы можете добавить дополнительные условия в директиву IF, например, обеспечить один канонический домен без префикса www:

<If "req('Host') != 'myonetruesite.com' || %{HTTPS} == 'off'">
Redirect permanent / https://myonetruesite.com/
</If>

В использовании mod_rewrite для всего есть много инерции знакомства, но посмотрите, работает ли это для вас.

Дополнительная информация: https://httpd.apache.org/docs/2.4/mod/core.html#if.

Чтобы увидеть его в действии (попробуйте без www. Или https: //, или с .net вместо .com): https://nohodental.com/ (сайт, над которым я работаю).


1

Возьми этот код тебе .htaccess файл Перенаправь HTTP на HTTPS автоматически

RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]


Привет, спасибо за ответ, что добавляет ваш ответ, чего нет у других существующих ответов?
Грайси

По схожему типу вопроса. Кто-нибудь может помочь с вопросом ниже? stackoverflow.com/questions/59503217/…
appsntech

0

Я нашел способ заставить все страницы моего сайта перенаправлять с http на аналог страниц на https, которые работают для меня.

RewriteEngine On 
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

0
 Redirect 301 / https://example.com/

(работал для меня, когда ни один из приведенных выше ответов не работал)

Бонус:

ServerAlias www.example.com example.com

(исправлено: https: // www .example.com не найдено)


0

Это перенаправляет все URL-адреса на https и www

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTPS_HOST} !^www.example.com$ [NC,OR]
RewriteCond %{HTTP_HOST} !^www.example.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]

0

Если вы хотите сделать это с сервера Tomcat, выполните следующие действия

На автономном HTTP-сервере Apache Tomcat (8.5.x) его можно настроить таким образом, чтобы, если пользователь вводит www.domain.com, они автоматически перенаправлялись на сайт https (www.domain.com).

Двухэтапный метод включения следующего в ваш [Tomcat_base] /conf/web.xml перед закрывающим тегом

step 1: 
<security-constraint>
<web-resource-collection>
<web-resource-name>HTTPSOnly</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>

и настройте параметры коннектора [Tomcat_base] /conf/server.xml:

step 2:
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="80" protocol="HTTP/1.1" redirectPort="443"/>
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="[keystorelocation]" type="RSA" />
</SSLHostConfig>
</Connector>

Примечание. Если вы уже выполнили настройку https и пытаетесь перенаправить, выполните только шаг 1.



-1

Другое преимущество этой проблемы - когда в игру вступает балансировщик нагрузки.

Ситуация выглядит следующим образом: - Трафик между браузером и балансировщиком нагрузки и обратно - это (должен быть) HTTPS - Трафик между балансировщиком нагрузки и реальным WebServer - HTTP.

Итак, все переменные запроса сервера в PHP или Apache показывают, что соединение является просто HTTP. И каталоги HTTP и HTTPS на Сервере одинаковы.

RewriteCondition в утвержденном ответе не работает. Это дает либо цикл, либо он просто не работает.

Вопрос: как заставить это работать на Балансировщике Нагрузки.

(Или неправильно настроен балансировщик нагрузки. На это я и надеюсь, потому что тогда я смогу перенести проблему в компанию WebHosting :-))


Перенаправление просто должно произойти на балансировщике нагрузки. В зависимости от типа балансировщика нагрузки это должно быть возможно в конфигурации, или это сам экземпляр apache, где принятый ответ будет работать. Только не делайте этого на отдельных узлах.
marc82ch

-1

Если вы используете Elastic Load Balancer Amazon Web Services, который принимает трафик https и направляет его на ваш сервер (ы) с http, правильный способ перенаправления всего трафика http на https описан здесь: https://aws.amazon. ком / premiumsupport / знание-центр / редирект-клиент по протоколу HTTPS-ELB

Используйте заголовок X-Forwarded-Proto (содержит http или https), который всегда включен в http-запросы от балансировщика нагрузки, как описано здесь: https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x- пересылаются-headers.html

В файле httpd.conf:

<VirtualHost *:80>

RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]

</VirtualHost>

Или в вашем корневом .htaccess файле:

RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]

Бонус: он не будет пытаться перенаправить http-трафик на ваш локальный компьютер для разработки.


-1

Меня устраивает:

<IfModule mod_rewrite.c>
 RewriteEngine On
  RewriteCond %{HTTPS} !on
  RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

и, например, http: // server / foo? email = somebody% 40example.com перенаправляет нормально без каких-либо проблем. Файл .htaccess находится в корневой папке сайта (например, с именем public_html). Вместо RewriteCond% {HTTPS}! On можно использовать RewriteCond% {SERVER_PORT}! ^ 443 $

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.