Apache переписывает все поддомены, кроме одного, на не-www https

Apache переписывает все поддомены, кроме одного, на не-www https

Я пытаюсь сократить количество цепочек перенаправлений 301 на моем сервере, поэтому я хотел бы объединить перенаправление с поддомена на не-www (за исключением случаев, когда поддомен — dev) с перенаправлением с HTTP на HTTPS (используя %{HTTP:X-Forwarded-Proto}), поскольку экземпляр находится за балансировщиком нагрузки.

Вот что у меня есть на данный момент .htaccess:

# move http to https 
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=301]

# Remove leading www 
RewriteCond %{HTTP_HOST} ^www.example.net [NC]
RewriteRule ^(.*)$ https://example.net/$1 [R=301,L]

В моей текущей реализации есть три проблемы:

  1. Запрос http://www.example.netбудет иметь два перенаправления.

  2. Как и большинство примеров перенаправления с www на без www на этом сайте, перенаправление не выполняется, ww.или wwww.в моей аналитике есть много неправильно введенных поддоменов, которые не были перенаправлены.

  3. Я хотел бы исключить dev.поддомен из перенаправления, а http://dev.example.netтакже его httpsродственный домен, поскольку я использую его dev.для разработки и подготовки к выпуску.

Как мне это объединить?

решение1

1) Запрос http://www.example.netбудет иметь два перенаправления.

Это можно решить, просто поменяв местами два правила. Затем www.example.netпроисходит перенаправление на HTTPS в первом перенаправлении, поэтому перенаправление с HTTP на HTTPS не должно срабатывать.

(Однако это предполагает, что вы не собираетесь внедрятьHSTS- в этом случае вам нужно будет сохранить их как два перенаправления, так как перенаправление на HTTPS на том же имени хостапервыйявляется обязательным требованием.)

2) Как и большинство примеров перенаправления с www на без www на этом сайте, перенаправление не выполняется, ww.или wwww.моя аналитика обнаружила много неправильно введенных поддоменов, которые не были перенаправлены.

Обычно запросы к ww.или wwww.поддоменам просто не разрешаются, так что это обычно не проблема. Чтобы это работало, вам нужно настроитьподстановочный знакподдомен в DNS и настроил сервер на прием таких запросов.

Но это можно объяснить, изменив регулярное выражение (фрагмент) с ^www\.на ^w{2,4}\..

3) Я хотел бы исключить dev.поддомен из перенаправления, а http://dev.example.netтакже его httpsродственный домен, поскольку я использую его dev.для разработки и подготовки релиза.

Это применимо только к правилу HTTP-HTTPS, поэтому здесь можно применить дополнительное условие, чтобы исключить имена хостов, начинающиеся с dev..

Объединив вышеизложенные пункты, попробуйте сделать следующее:

# Remove leading ww, www or wwww (and redirect to HTTPS)
RewriteCond %{HTTP_HOST} ^w{2,4}\.example\.net [NC]
RewriteRule (.*) https://example.net/$1 [R=301,L]

# Move http to https (except dev subdomain)
RewriteCond %{HTTP:Host} !^dev\. [NC]
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP:Host}%{REQUEST_URI} [R=301,L]

Я сохранил ваше использование HTTP:Hostтого же (для доступа к Hostзаголовку HTTP-запроса) на случай, если это является требованием балансировщика нагрузки? В противном случае здесь более распространено использование HTTP_HOSTпеременной сервера.

Префикс !наCondPattern(т.е. !^dev\.) отрицает регулярное выражение, поэтому условие выполняется, когда Hostвыполняетсянетначните с dev.. (Я полагаю, www.dev.это не вещь?)

(.*)то же самое, ^(.*)$поскольку регулярное выражение по умолчанию является жадным.

Вам нужно будет очистить кэш браузера перед тестированием. Рекомендуется сначала протестировать с 302 (временными) перенаправлениями, чтобы избежать проблем с кэшированием.

решение2

# Remove leading www, always using https regardless of the current URL scheme
RewriteCond %{HTTP_HOST} ^w{2,4}.example.net(?::|$) [NC,NV]
RewriteRule .* https://example.net%{REQUEST_URI} [L,R=301]

# move http to https, except for dev.example.net
RewriteCond %{HTTP:X-Forwarded-Proto} =http [NC,NV]
RewriteCond %{HTTP_HOST} !^dev.example.net(?::|$) [NC,NV]
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
  1. Добавлен флаг NC( ) к условию, так как его значение, по-видимому, не имеет значения регистра , т.е. Вы можете удалить его.nocaseX-Forwarded-ProtoHTTP = Http = hTTp = http
  2. Добавлен флаг NV( ) к условию, чтобы скрыть его из заголовка ответа. Опять же, вы можете удалить это, особенно если это не так (обратный прокси-сервер автоматически фильтрует его для вас в любом случае перед отправкой клиенту) или необходимо для правильного поведения кэширования (в противном случае кэш не различает и содержимое).novaryX-Forwarded-ProtoVaryhttphttps
  3. Добавлен флаг NV( novary) в Hostзаголовок условия, чтобы скрыть его из Varyзаголовка ответа. Вы также можете удалить это, если у вас сломанный сервер кэширования.
  4. Сделал RewriteRuleпорядок флагов единообразным ( L,R=301и R=301,Lпо сути одинаковым).
  5. Запрещено www.example.net.but.not.actually.yours.comраспознавать, но все еще разрешено, например www.example.net:443.
  6. Последовательно используйте %{REQUEST_URI}в качестве замены.
  7. Также распознавайте wwи wwww.

Связанный контент