nginx redirect from subdomain
Примеры редиректов в NGINX
В данной инструкции мы рассмотрим, в большей степени, перенаправления запросов на другие страницы с помощью NGINX. Также мы немного разберем проксирование и перенаправление на другие файлы.
Настройка перенаправлений
Настройки необходимо вносить в файлах конфигураций виртуальных доменов. В Linux на основе RPM (CentOS, Red Hat), как правило, они расположены в директории /etc/nginx/conf.d/. В Linux на основе Deb (Ubuntu, Debian) — в директории /etc/nginx/sites-enabled/. Во FreeBSD все в одном файле — /usr/local/etc/nginx/nginx.conf.
Саму настройку на перенаправление в NGINX можно прописать несколькими способами.
* $host — имя хоста из запроса, если отсутствует — имя в поле «Host» заголовка, если тоже отсутствует — имя сервера; $request_uri — первоначальный запрос с аргументами (все, что идет после доменного имени).
** где флаги могут быть следующие:
* где коды могут использоваться любые, но чаще всего — 301, 302, 404.
Есть различные мнения, какой из методов лучше и безопаснее, поэтому каким воспользоваться — решать по ситуации. В данных примерах используются оба варианта.
После внесения изменений, необходимо проверить их корректность:
И для их применения перезапустить веб-сервер:
systemctl restart nginx
service nginx restart
* в первом примере перезапуск выполняется на новых системах Linux. Второй пример — на устаревших или FreeBSD.
Проверяя редиректы в браузере, следует учесть, что настройки могут кэшироваться. Для обновления кэша используйте комбинацию Ctrl + F5. Если и это не помогает, закрывайте вкладку и открывайте новую.
С HTTP на HTTPS (другой порт)
Пример конфигурации для перенаправления запросов на другой порт — с 80 (http) на 443 (https):
server <
listen 80;
server_name domain.ru www.domain.ru;
return 301 https://$host$request_uri;
>
* в данном примере для всех обращений к сайту domain.ru по 80 порту (http) будет работать редирект на 443 порт (https) с кодом 301 (для склеивания доменов).
Также мы можем добавить условие, чтобы не перенаправлять на https для определенных ссылок, например:
/page.html) <
return 301 https://$host$request_uri;
>
>
* в данном примере запрос на страницу /page.html будет открыт по http.
С одного домена на другой
server <
.
server_name domain1.ru;
return 302 http://domain2.ru$request_uri;
>
C домена без www на домен с www
server <
.
server_name domain.ru;
return 301 http://www.$host$request_uri;
>
С www на без www
Все домены, которые обслуживает nginx:
C index.php на / (корень)
Данная настройка позволит перевести все запросы с /index.php на корневой адрес /:
server <
.
if ($request_uri
Перенаправление запросов для отсутствующих доменов (перенаправление по умолчанию)
Если обращение к веб-серверу идет по IP-адресу или домену, который не прописан в конфигурационном файле, можно перенаправить весь трафик на домен по умолчанию:
server <
listen 80 default_server;
return 302 https://welcome.domain.ru$request_uri;
>
или независимо от протокола:
ssl on;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/cert.key;
>
* $scheme позволяет перевести запрос на тот же протокол (http или https), по которому он был инициирован.
* если nginx должен слушать и обрабатывать запросы по https, необходимо указывать в настройках пути к сертификатам.
С IP-адреса на домен
В данном случае мы переводим все запросы по IP-адресу на конкретный домен:
server <
listen 80;
server_name 192.168.1.15;
return 301 http://site.ru$request_uri;
>
* при отправке http-запроса на сервер 192.168.1.15 по IP-адресу, он будет переведен на домен site.ru.
Редирект домена и всех его поддоменов
server <
.
server_name domain domain.*;
return 301 https://$host$request_uri;
>
На другой файл
Это скорее не перенаправление, а алиас или rewrite. Позволяет по запросу одного из файлов, отдать другой:
server <
.
location = /robots.txt <
rewrite ^/robots.txt$ /robots2.txt;
>
>
* в данном примере по запросу robots.txt, сервер отдаст содержимое robots2.txt.
Часть url на другой сервер
Перенаправить запрос на другой сервер при обращении по url page1:
server <
.
server_name domain1.ru;
location
* в данном примере для всех запросов, начинающихся на /page1/. будет работать перенаправление на другой домен domain2.ru.
Редирект со слешем
1. Убрать слеш в конце url
2. Добавить слеш в конце url
Удаляем расширение
Для перенаправления запроса, где в URL есть полное название файла скрипта (с расширением) используем конфигурацию:
server <
.
if ($request_uri
* в данном случае все запросы, которые заканчиваются на .php или .html, будут перенаправляться на страницы без данных расширений.
Для примера, запрос http://site-example.ru/page.php будет переведен на http://site-example.ru/page.
На другую страницу
Нам может понадобиться перенаправлять запросы с одной страницы сайта на другую. Приведем примеры, как это сделать с помощью return и rewrite.
а) с помощью rewrite:
server <
.
rewrite ^/page1$ /page2 permanent;
>
б) с помощью return:
server <
.
location = /page1 <
return 301 /page2;
>
>
Удалить часть URL
Иногда нужно удалять часть url. Это можно сделать следующими способами:
server <
.
rewrite /deleted-url/(.*) /$1 permanent;
>
server <
.
if ($request_uri
* в данном примере из url мы удалим deleted-url/.
Перенаправить запрос в случае обращения к несуществующим файлам
Перевод запросов, если файла не существует
Данное действие не является редиректом, но близко по смыслу — NGINX проверяет наличие файла скрипта, к которому идет обращение, и если его нет, переводит запрос на другой файл. Как правило, это используется для того, чтобы перевести все обращения на файл index.php.
* в данном примере мы скажем веб-серверу все запросы обрабатывать с помощью файла index.php в корневой директории.
Проксирование
Проксирование, в отличие от редиректа, не передает инструкции браузеру перейти на другой url — NGINX сам выполняет http-запрос по другому адресу и возвращает готовый ответ. Эта возможность может применяться для внутреннего распределения серверных ресурсов.
Хоть это и не совсем редирект, рассмотрим примеры его настройки, так как очень часто нужно не перенаправление, а, как раз, обратное проксирование.
1. На другой сервер
Пример внутреннего перенаправления http-запроса на другой веб-сервер:
* в данном случае, принимать запросы от браузера и отвечать на них будет NGINX, а сама обработка будет выполняться на сервере с IP-адресом 192.168.0.15 на порту 8080.
Использование NGINX в качестве http-прокси:
* в данном примере запросы на site1.ru будут перекинуты на сервер 192.168.1.21, а запросы на site2.ru — 192.168.1.22.
HTTP proxy с авторизацией (если удаленный веб-сервер требует аутентификации):
server <
.
location / <
proxy_pass http://10.10.10.10/page/;
proxy_set_header Authorization «Basic dGVzdDp0ZXN0»;
.
>
>
* где 10.10.10.10/page — страница, на которую будут перекинуты запросы; dGVzdDp0ZXN0 — логин:пароль test:test, закодированные в формате base64.
2. Часть url на другой сервер
Выше мы рассмотрели пример перенаправления запроса по части веб-адреса. По схожему сценарию мы можем делать проксирование:
3. На другой сайт
Мы можем сделать так, что при переходе по одному адресу у нас будет открываться совершенно другой сайт:
* в данном случае мы при обращении к нашему серверу (до доменному имени dmosk.local) будем попадать на сайт https://www.dmosk.ru. Обратите внимание, что в proxy_set_header мы передаем хосту его имя — в противном случае, как правило, другой сервер вернет ошибку. Также мы не указываем proxy_redirect, иначе, nginx будет переводить запросы на реальный сайт (отправлять инструкции браузеру перейти на него), а не тот, что мы используем за http-прокси.
4. На другой сайт по части URL
Если нам нужно настроить проксирование на другой сайт при обращении к определенной странице сайта, настраиваем NGINX так:
* в данном примере, если мы перейдем на страницу www.dmosk.ru/page, то мы попадем на сайт www.site.ru.
5. Редиректы при проксировании
Если при проксировании хост возвращает инструкцию браузеру для выполнения редиректа, обозреватель может сменить адрес сайта. Это особенно не удобно, когда проксирование мы выполняем на другой сайт. Чтобы отловить редиректы и заменить их своими значениями, мы должны воспользоваться опцией proxy_redirect. Рассмотрим ее применение для предыдущего примера, когда мы проксировали запрос на сайт www.dmosk.ru:
proxy_redirect https://www.dmosk.ru/url1 http://dmosk.local/url2;
proxy_redirect https://www.dmosk.ru/ http://dmosk.local/;
>
>
* в конкретном случае мы проксируем запросы http://dmosk.local на сайт www.dmosk.ru, но если он вернет инструкцию для редиректа https://www.dmosk.ru/url1, в браузере он должен быть заменен на http://dmosk.local/url2. А также любое перенаправление для https://www.dmosk.ru/ будет заменено на http://dmosk.local/.
Немного о 301 и 302
В чем принципиальная разница между ответом с кодом 301 и 302? Для обычного посетителя сайта разницы нет. А вот для поискового робота разница огромная.
301-й редирект говорит о склеивании страниц. Это означает для поисковика то, что старая и новая страницы — это одно и то же. Таким образом, результаты ранжирования необходимо сохранить для новой страницы.
302-о перенаправление просто говорит о том, что нужно перейти по другому адресу. Поисковый робот не сохраняет результат выдачи для новой страницы, индексируя его с нуля.
Правильный redirect 301 для SEO в Nginx
Хочу сегодня рассмотреть тему редиректов в Nginx. Я обычно настраиваю их в лоб. То есть нужен какой-то редирект, я его добавляю. На днях меня попросили СЕО специалисты переработать редиректы одного проекта и сделать так, чтобы для клиента был ровно один 301 редирект, который включает в себя сразу все необходимые преобразования url.
Пример двойного редиректа
Для того, чтобы было понятно, о чем идет речь, приведу пример. Допустим, у вас настроен редирект с http на https и добавление к урлу в конце слеш. То есть вы хотите такое преобразование:
Допустим, у вас сначала был настроен редирект на https подобным образом:
А потом вас попросили добавить редирект всех урлов без слеша на тот же урл только со слешем на конце. Вы идете в секцию c listen 443 и добавляете редирект.
В целом все нормально, редиректы работают. Но если перейти по ссылке http://site.ru/catalog, мы получим 2 301-х редиректа.
На выходе у вас 2 редиректа вместо одного, что плохо для СЕО. Надо по возможности все реализовать в одном. В данном случае напрашивается простое и очевидное решение:
Вроде бы все нормально. Теперь редирект будет автоматически добавлять слеш в конец запроса. Но проблемы начнутся со ссылками на медиа файлы. Например, запрос http://site.ru/catalog/img.png будет превращаться в https://site.ru/catalog/img.png/, что нам совершенно не нужно. Чтобы это исправить, надо сделать так.
Теперь все будет нормально, так как location со статикой указан в виде регулярного выражения. В случае попадания запроса в указанное правило, будет выполнен редирект без слеша. Все остальное попадет в следующий префиксный location /. То же самое можно сделать с помощью if и одного location, но c if работать будет медленнее. Там где можно обходиться без if, лучше его не использовать.
Пример с nginx rewrite
Обращаю внимание на то, что сделано. Я использую rewrite без какого-либо флага на конце, чтобы не прекращать обработку директив. В данном случае просто меняется uri и передается дальше. Если запрос приходит со слешом на конце, мы его обрезаем и отправляем в правило редиректа на https. Если слеша нет, то он сразу на редирект уходит. Теперь все в порядке.
Встроенные редиректы WordPress
Очевидно, что выше описана простая ситуация. На нее достаточно обратить внимание и исправить. Но не всегда бывает так просто. Например, вы сами не настраивали редирект урлов без слеша на урлы со слешом, он вам не нужен. Но, к примеру, WordPress реализует подобный редирект своими средствами. В итоге, при запросе http://site.ru/catalog вы получите такую картину с редиректами.
Сначала nginx сделал редирект на https, так как вы это настроили у него в конфигурации, а потом wordpress на страницу со слешом на конце. В итоге у вас два редиректа, а надо один. Причем, два редиректа получились не по вашей воле. Если не обратите на это внимание, так и будете с ними жить. По факту, все типовые редиректы лучше сразу реализовывать в одном месте в веб сервере.
Все стандартные редиректы в nginx
Рассмотрю типовой пример, когда у нас одновременно присутствуют следующие редиректы:
Наша цель будет реализовать все преобразования url в одном месте и выдать клиенту только один 301-й редирект.
Получилось примерно так. Призываю не копировать бездумно конфиг, а проверить то, что я предлагаю. Хотя я сам внимательно проверил, как мог, но все равно не застрахован от ошибки. На мой взгляд здесь рассмотрены все основные моменты с редиректами. На выходе всегда один 301 редирект, какой бы запрос мы не сделали. При этом все реализовано средствами самого веб сервера, а значит, будет работать максимально быстро.
Корректный редирект с одного url на другой
Допустим вы корректно настроили стандартные редиректы в nginx. А потом в какой-то момент у вас поменялась структура сайта, или просто нужно было сделать редиректы для отдельных страниц. К примеру, запрос https://site.ru/main/hello/ перенаправить в https://site.ru/main/. По идее ничего сложного. Добавляем редирект:
Опять два 301-х редиректа. Переделываем на один, не забывая все возможные варианты написания.
Ну и так далее. Думаю, идея ясна. Следует следить за всеми редиректами и стараться всегда оставлять только один.
Заключение
Я прилично заморочился с темой редиректов в nginx. Раньше никогда не обращал на них пристального внимания. Да и у других не видел акцента на этом. В интернете полно готовых вариантов перенаправлений на все случаи жизни, но рассмотрены они в отдельности. А вот так комплексно взглянуть на полный конфиг со всеми нюансами не приходилось.
Материал полностью написан и протестирован мной от начала до конца, поэтому призываю не копировать слепо к себе, а проверить. Я могу где-то ошибаться, что в такой важной теме может быть чревато проблемами с индексацией и работой сайта. Так что внимательно все проверяйте, прежде чем внедрять у себя. Ну а замечания все, как обычно, жду в комментариях.
В завершении рекомендую мою статью про настройку nginx. Я там частично рассматриваю и эту тему. А вообще там рассказаны все основные моменты, на которые стоит обращать внимание при работе с nginx.
How to redirect to a different domain using NGINX?
How can I redirect mydomain.com and any subdomain *.mydomain.com to www.adifferentdomain.com using NGINX?
8 Answers 8
or on any version 0.9.1 or higher:
You can also give it a 301 redirect.
Example rewrite from www.example.com to example.com:
If you would like to redirect requests for «domain1.com» to «domain2.com», you could create a server block that looks like this:
I’m using this code for my sites
You can simply write a if condition inside server <> block:
Temporary redirect
Permanent redirect
In nginx configuration file for specific site:
Not the answer you’re looking for? Browse other questions tagged redirect nginx vhosts or ask your own question.
Linked
Related
Hot Network Questions
Subscribe to RSS
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
site design / logo © 2021 Stack Exchange Inc; user contributions licensed under cc by-sa. rev 2021.9.17.40233
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.
Примеры настройки перенаправлений на NGINX
Где настраивать редирект в Nginx
Эти файлы с параметрами, которые идентичны, вне зависимости от используемого дистрибутива Linux. Тем не менее, их расположение может отличаться:
Как применить настройки редиректа
Чтобы применить редиректы на веб-сервере Nginx, необходимо выполнить последовательно два действия:
Настройка редиректа
Ниже разберем два основных способа настройки редиректов для выбранных веб-страниц. Так как общепринятого мнения, какой из них является оптимальным, в практике не сложилось, в последующих примерах будут использоваться оба.
Способ №1
Первый представляет собой строку:
При настройке можно выбрать следующие флаги ( ):
Способ №2
По завершении редактирования файлов остается проверить, правильны ли они:
Чтобы их применить, необходима перезагрузка Nginx:
Первая команда используется в новых версиях Linux. Вторая — для устаревших версий и FreeBSD.
Практическое использование редиректов
Редирект с www на без www
Это наиболее распространенное перенаправление, которое позволяет направить весь трафик непосредственно на домен, минуя поддомены. Код редиректа:
Если необходимо получить противоположный эффект (перенаправление на «www» c «без www»):
Редирект на другой домен
Чтобы организовать перенаправление на другой сайт — например, после изменения адреса сайта — можно воспользоваться командой:
Второй вариант проще:
Редирект с http на https
Установить перенаправление с http на https (защищенный протокол SSL ) можно следующим образом:
Здесь при всех обращениях domain.ru по протоколу http сработает перенаправление на 443-порт с использованием 301 редиректа для склейки доменов.
Редирект на другой сервер
При необходимости использовать перенаправление на другой сервер всех запросов:
Здесь за прием запросов браузера и ответ на них отвечает веб-сервер Nginx. Их обработка выполняется сервером с IP-адресом 192.168.0.12 (порт 8080 ). Таким же образом осуществляется и перенаправление на другой Nginx.
Редирект с IP адреса на домен
Перенаправление домена без www на домен с www
В противном случае (редирект с www на без www) нужно использовать такое сочитание:
Перенаправление одного URL
Перенаправление на index.php
Сделать так, чтобы запросы из браузера обрабатывались через index.php можно таким образом:
Если же файл расположен в корневом каталоге, перенаправление на index.php указывается командой:
Перенаправление «после слэша» (/)
Следующий блок позволяет установить перенаправление «после слэша» для домена:
Это приведет к тому, что после ввода адреса http://domain.com/mail пользователь будет перенаправлен на https://mail-server.com/mail-panel.
Стоит добавить в приведенный пример знак « = », чтобы перенаправление относилось только к этому элементу (почта), а не ко всему, что начинается с «mail»:
Перенаправление с изменением типа файла
Еще один вариант будет полезным, когда ссылку на файл HTML нужно автоматически заменить ссылкой на файл PHP:
Несколько доменов, один каталог и один основной домен
Этот прием пригодится при наличии нескольких доменов. Для примера возьмем следующие домены:
Все эти домены указывают на один и тот же каталог на сервере. Соответственно, они отображают одну и ту же страницу/контент, хотя и при вводе разных адресов.
Не стоит забывать об исключении ошибки 404 («страница не найдена»), которая может возникнуть, если кто-то воспользуется ссылкой на товар/страницу с одного из альтернативных доменов. Решить эту задачу можно следующим способом:
Таким образом, все альтернативные адреса, отличные от «.ru», будут направлены на «new-address.ru», который является основным адресом.
Техническое обслуживание сайта
Следующий сценарий подойдет для сайта, который находится на техническом обслуживании. То есть в случае необходимости внесения изменений на сайте. При этом перенаправление будет работать в случае обращения к определенному IP-адресу.
Задача заключается в перенаправлении оставшихся посетителей на страницу, которая будет содержать информацию, подобную «На сайте ведутся технические работы…». Это можно осуществить следующим способом:
Вместо подстановочных значений «123.123.123.123» в примере следует вписать IP-адрес своего сервера.
Дополнительные настройки
Свой IP-адрес нужно исключить с редиректа, чтобы сохранить полный доступ к сайту:
Вместо 123.123.123.123 следует указать IP адрес своего сервера.
Благодаря примеру ниже можно обнаружить, существует ли такой файл (technical-break.html) на сервере:
Если да, перенаправление сработает, в противном случае сайт открывается в обычном режиме.
Работа над новой версией сайта с перенаправлением на старую
Перенаправить пользователей на старую версию:
Вместо «123.123.123.123» необходимо подставить IP адрес своего сервера (или адреса).
В случае, если возникает циклическое перенаправление на странице, следует добавить:
Перенаправление в зависимости от IP-адреса посетителя
Приведённый ниже способ предпочтителен с точки зрения SEO-оптимизации, так как при выполнении сценария в ссылках ничего не меняется:
При посещении сайта, сервер предоставляет владельца или администратору ресурса ( MY_IP ) файлы из каталога new-version («новая-версия»). Когда страница посещается «сторонним лицом», сервер открывает старую версию сайта.
Перенаправление в зависимости от IP-адреса посетителя и браузера
Ситуация становится немного сложнее, когда нужно нужно организовать подключение с использованием сразу двух условий:
К сожалению, Nginx не поддерживает правила объединения, поэтому здесь следует применить небольшой трюк:
Редирект в зависимости от файлов cookie
В то время как на рабочем месте часто используется статический IP-адрес, бывает, что работу над сайтом нужно проводить удалённо, с другого IP-адреса.
Хотя в таких ситуациях может помочь подключение через VPN, это не всегда возможно. Здесь применяется еще одно условие — проверка cookie:
Если в браузере будет сохранен cookie с контентом «text», то файлы нового сайта будут открываться без редиректа.
Очевидно, понадобится механизм для сохранения соответствующего куки в браузере. Здесь достаточно применить директиву PHP:
Она сохраняется на сервере (например, в файле cookie.php). Он добавляется в каталог со старой (для создания cookie) и новой страницей (обновления cookie до его истечения). Данный код выполняет следующую инструкцию:
В приведенном выше примере cookie действителен в течение 5 минут (300 секунд), после чего — если он не будет создан снова — вместо новой страницы снова будет отображаться старая страница. Когда новая страница готова, достаточно удалить эти несколько строк.
Nginx и CloudFlare
В случае использования CloudFlare существует высокая вероятность того, что редирект не будет работать правильно для выбранного IP-адреса, то есть сервис не будет его распознавать.
В этом случае в файле конфигурации виртуального хоста следует добавить:
Адреса в примере взяты из текущего списка адресов, используемых CloudFlare, размещенного на официальной странице https://www.cloudflare.com/ips/. Это список актуален на момент публикации, но может со временем меняться
Начни экономить на хостинге сейчас — 14 дней бесплатно!