Як перенаправити всі запити HTTP на HTTPS


294

Я намагаюся перенаправити всі небезпечні запити HTTP на своєму сайті (наприклад http://www.example.com) на HTTPS ( https://www.example.com). Я використовую PHP btw. Чи можу я це зробити у .htaccess?


1
Ви можете (і повинні) зробити це через ваш httpd, а не з PHP.
дружина

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"
Жук-сік

2
@Whitecat In 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
Так. Це правильна відповідь, оскільки вона також
спрямовує

Це на верхньому рівні файлу htaccess?
CodyBugstein

1
@CodyBugstein Ось де я завжди розміщую це, і це завжди працює.
Даан ван ден Берг

3
У всіх відповідях відсутнє одне - будь-який код для переадресації повинен бути розміщений прямо на початку.
Вадим Анісімов

35

Як я вже говорив у цьому запитанні , я пропоную вам уникати перенаправлення всіх HTTP-запитів до їх HTTPS-еквівалента наосліп, оскільки це може викликати у вас помилкове враження безпеки. Натомість, ви, ймовірно, повинні перенаправити "корінь" вашого HTTP-сайту до кореня вашого HTTPS-сайту та посилатися звідти лише на HTTPS.

Проблема полягає в тому, що якщо якесь посилання або форма на веб-сайті HTTPS змушує клієнта відправити запит на сайт HTTP, його вміст буде видно перед перенаправленням.

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

Звичайно, помилка в наданні посилань, які мають бути на сайті HTTPS, але в кінцевому підсумку є для HTTP-сайту, може спричинити проблеми, як тільки ви отримаєте щось прослуховування на порту HTTP на тій же IP-адресі, що і ваш HTTPS-сайт. Однак я вважаю, що зберігання двох сайтів як "дзеркала" лише збільшує шанси помилитися, оскільки, можливо, ви можете зробити припущення, що воно автоматично виправить себе, перенаправляючи користувача на HTTPS, тоді як часто це вже пізно. (У цьому питанні були подібні дискусії . )


1
Приймаючи рішення обслуговувати весь сайт як HTTPS, подібне перенаправлення має сенс. Я не хочу, щоб користувач отримував номер 403, оскільки він вказав http для своєї цільової сторінки. Я погоджуюся, якщо хтось Вказує http у посиланні і розгортає його у виробництві, що погано. ЇЇ ВИНАГАЮТЬ під час тестування навіть при переадресації на місці. Мені не подобається аргумент "міг", тому що це "могло" статися без перенаправлення на місці. Симптоми однакові при тестуванні в захищеному браузері, за винятком випадків після підтвердження надсилання в поле, він перенаправляє замість отримання 403.
Дерек Літц,

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

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

чому б не зробити http для https в dns.
Мухаммед Умер

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 AND'd. Натомість вони повинні бути АБО, тобто. включіть ORпрапор на першу умову (і не забудьте уникнути буквальних крапок у регулярному виразі). Але якщо ви реалізуєте HSTS, тоді ви не хочете переспрямовувати на HTTPS та www в одному переадресуванні, спершу слід перенаправитись на HTTPS .
MrWhite

Куди я кладу цей текст?
Аарон Франке

На подібний тип запитань. Чи може хто-небудь допомогти з наведеним нижче питанням? stackoverflow.com/questions/59503217 / ...
appsntech

14

Це підхід до переадресації HTML, який працює, але не найкращий.

 <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 Approch

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файлі. У такому випадку ви можете використовувати RewriteEngine Apache :

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 та функцію заголовка :

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

Схоже, що документація Apache рекомендує проти маршруту Переписати. Що з перенаправленням? Що ще може бути у .htaccessфайлі?
Аарон Франке

Так, перенаправлення є кращим і може використовуватися в .htaccess. Але ви не можете додати умову лише для перенаправлення трафіку http на https. Він також перенаправляє https, а також -> нескінченну петлю переадресації. Я перерахував це у директиві VirtualHost, що використовується для http (порт 80) вище, .htaccess не підтримує цю директиву, і тому Redirect не можна використовувати тут.
maikel

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". Це дозволить уникнути людини в середині нападу.

Відредагуйте файл конфігурації 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]

Якщо модуль перезапису не ввімкнено, і ви перебуваєте на апаш 2.4, ви також можете використовувати Redirectвнутрішню ifдирективу для переадресації httpзапитів наhttps .

Apache 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
Це рішення для тих, хто отримує "Занадто багато помилок переадресації" і не може змінити властивість enableOverride.
Евохром

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) на сервері 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 - трафік між балансиром навантаження та фактичним веб-сервером - це HTTP.

Отже, всі змінні серверного запиту в PHP або Apache показують, що з'єднання - це лише HTTP. І каталоги HTTP і HTTPS на сервері однакові.

RewriteCondition у затвердженій відповіді не працює. Він дає цикл або просто не працює.

Питання: Як змусити це працювати над балансиром навантаження.

(Або налаштовано балансир завантаження неправильно. На що я сподіваюся, тому що тоді я можу перенести проблему на компанію WebHosting :-))


Переадресація повинна була б відбутися замість балансира навантаження. Залежно від типу балансира навантаження, це повинно бути можливим у конфігурації, або це сам екземпляр apache, де працюватиме прийнята відповідь. Просто не робіть цього на окремих вузлах.
marc82ch

-1

Якщо ви використовуєте еластичний балансир завантаження Amazon Web Services, який приймає трафік https та спрямовує його на ваш сервер (и) за допомогою http, тут описаний правильний спосіб перенаправити весь http-трафік на https: https://aws.amazon. com / premiumsupport / центр знань / перенаправлення-http-https-elb

Використовуйте заголовок X-Forwarded-Proto (містить http або https), який завжди входить у запити http від балансира навантаження, як описано тут: https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x- forwarded-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 = хтось% 40example.com перенаправляє звичайно без проблем. Файл .htaccess розташований у кореневій папці веб-сайту (наприклад, з ім'ям public_html). Можна використовувати RewriteCond% {SERVER_PORT}! ^ 443 $ замість RewriteCond% {HTTPS}! On

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.