
У меня есть одно приложение с сервером на нескольких доменах (каждый из которых настраивает внешний вид приложения).
Кроме того, существует общий домен, имеющий несколько поддоменов для отображения тех же данных, что и выше.
Так что - www.apples.com
выглядит так же, какapples.efruit.co.uk
и - www.bananas.co.uk
выглядит так же, какbananas.efruit.co.uk
и т. д.
Теперь у меня есть wildcard ssl для домена efruit.co.uk, поэтому я хочу использовать файл htaccess, чтобы заставить все запросы efruit.co.uk использовать https (если это еще не сделано).
Все остальные домены не будут иметь SSL, поэтому им придется использовать http, чтобы избежать предупреждений браузера (опять же из файла htaccess).
Я также хотел бы использовать файл htaccess, чтобы если кто-то вводит www.apples.efruit.co.uk, он переписывался как apples.efruit.co.uk (по https, как указано выше). Однако, www. подойдет, если это не домен efruit.co.uk.
Наконец, у меня есть стандартное и хорошо документированное правило перезаписи для codeigniter, позволяющее сделать URL-адрес более привлекательным.
Вот что у меня есть на данный момент.
Options +FollowSymlinks
RewriteEngine On
RewriteCond %{REQUEST_URI} !(health_check\.php)$
RewriteCond %{HTTP_HOST} ^(.*)\.efruit\.co\.uk
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
RewriteCond %{HTTP_HOST} !^(.*)\.efruit\.co\.uk
RewriteCond %{HTTP:X-Forwarded-Proto} =https
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R,L]
RewriteCond %{HTTP_HOST} ^www\.([^\.]*)\.efruit\.co\.uk$
RewriteRule (.*) https://%1.efruit.co.uk$1 [R,L]
# block hidden directories
RewriteRule "(^|/)\." - [F]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ./index.php/$1 [L,QSA]
Единственное, что, похоже, работает, — это принудительное обслуживание доменов efruit.co.uk по протоколу https.
решение1
Похоже, вы находитесь за SSL-прокси(?), отсюда и использование X-Forwarded-Proto
заголовка запроса вместо HTTPS
переменной сервера.
RewriteCond %{REQUEST_URI} !(health_check\.php)$ RewriteCond %{HTTP_HOST} ^(.*)\.efruit\.co\.uk RewriteCond %{HTTP:X-Forwarded-Proto} =http RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
Хотя вы утверждаете, что этот бит "работает" ("заставляет efruit.co.uk
домены обслуживаться по https"), это не перенаправит основной пустой домен и также сохранит поддомен www, если он присутствует в запросе - вам следует сначала удалить его, чтобы избежать вторичного перенаправления. Поэтому требуется изменить порядок этих директив.
Вам также не нужна группа захвата (т. е. заключенный в скобки подшаблон), если только вы не собираетесь использовать его в качестве обратной ссылки — чего, судя по всему, вы не собираетесь делать.
Все остальные домены не будут иметь SSL, поэтому им придется использовать http, чтобы избежать предупреждений браузера (опять же из файла htaccess).
Вы не можете выполнить перенаправление с HTTPS на HTTP, .htaccess
чтобы избежать предупреждения браузера на этих других доменах - что, похоже, вы и предлагаете. Поскольку недействительный сертификат SSLпредупреждение браузераимеет местодо .htaccess
выполняется. SSL-рукопожатие происходит в самом начале запроса.
RewriteCond %{HTTP_HOST} !^(.*)\.efruit\.co\.uk RewriteCond %{HTTP:X-Forwarded-Proto} =https RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R,L]
Таким образом, приведенное выше действие фактически не будет выполнено из браузера, если пользователь не примет предупреждение SSL-сертификата (чего делать не следует).
RewriteCond %{HTTP_HOST} ^www\.([^\.]*)\.efruit\.co\.uk$ RewriteRule (.*) https://%1.efruit.co.uk$1 [R,L]
В .htaccess
результате это приведет к недействительному перенаправлению, для чего угодно, кроме корня документа, потому что $1
обратная ссылка не имеет префикса слеша. Даже для корня документа вы действительно должны включить завершающий слеш взамена(хотя браузер неявно исправит это). Также интересно, почему вы использовали REQUEST_URI
переменную сервера в первых двух правилах, но здесь использовали обратную ссылку?
Попробуйте вместо этого сделать что-то вроде следующего:
# Prevent any fruther processing when requesting "health_check.php"
# CHECK: Absence of start of string anchor?
RewriteRule health_check\.php$ - [L]
# Remove www sub-subdomain (and redirect to HTTPS)
RewriteCond %{HTTP_HOST} ^www\.([^.]+)\.efruit\.co\.uk [NC]
RewriteRule .* https://%1.efruit.co.uk%{REQUEST_URI} [R,L]
# HTTP to HTTPS redirect for the "efruit.co.uk" domain (and subdomains)
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteCond %{HTTP_HOST} ^([^.]+\.)?efruit\.co\.uk [NC]
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
# HTTPS to HTTP redirect for none "efruit.co.uk" domains
# Note that the user will still have to click through any browser security warnings
RewriteCond %{HTTP_HOST} !(^|\.)efruit\.co\.uk
RewriteCond %{HTTP:X-Forwarded-Proto} =https
RewriteRule .* http://%{HTTP_HOST}%{REQUEST_URI} [R,L]
Другие примечания:
- Нет необходимости экранировать точку обратным слешем при использовании внутри класса символов.
- Я удалил
$
привязку конца строки при проверке хоста, чтобы отследить FQDN, включающие конечную точку. - Вероятно, вы захотите изменить эти постоянные (301) перенаправления, как только убедитесь, что они работают нормально, например, изменить
R
наR=301
.