Перенаправление в NGINX

Перенаправление в NGINX

Где настраивать редирект в Nginx

Если в случае с серверами Apache2 для переадресации следует отредактировать файл .htaccess, в Nginx таковой отсутствует. Тем не менее, редирект можно настроить, отредактировав файлы конфигурации виртуальных доменов.

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

  • в дистрибутивах, основанных на RPM (CentOS, Red Hat) — /etc/nginx/conf.d/.
  • в дистрибутивах, основанных на Debian (Ubuntu, Debian) — /etc/nginx/sites-enabled/.

Как применить настройки редиректа

Чтобы применить редиректы на веб-сервере Nginx, необходимо выполнить последовательно два действия:

  1. Добавить соответствующую команду в виртуальный хост выбранного домена.
  2. Перезагрузить сервер.

Настройка редиректа

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

Способ №1

Первый представляет собой строку :rewrite ^ https://$host$request_uri? <flag>

Здесь переменная $host является хостом из запросов. Если он отсутствует, следует воспользоваться именем заголовка в поле «Host», если и его нет — подойдет имя сервера.

Переменная $request_uri — это первоначальный запрос с аргументами.

При настройке можно выбрать следующие флаги (<flag>):

  • permanent — 301 редирект (или постоянный редирект) на страницу с кодом ответа сервера 301.
  • redirect — 302 редирект (или временный редирект) на страницу с кодом 302.
  • last — завершение обработки и последующий переходом в новый location.
  • break — завершение обработки и работа в текущем location.

Способ №2

return <code> https://$host$request_uri;

Здесь можно использовать любой код редиректа, однако самые распространенные случаи — 301, 302, 404.

По завершении редактирования файлов остается проверить, правильны ли они:nginx -t

Чтобы их применить, необходима перезагрузка Nginx:systemctl restart nginxservice nginx restart

Первая команда используется в новых версиях Linux. Вторая — для устаревших версий и FreeBSD.

Практическое использование редиректов

Редирект с www на без www

Это наиболее распространенное перенаправление, которое позволяет направить весь трафик непосредственно на домен, минуя поддомены. Код редиректа:

# www.domen -> domenserver {server_name www.[domain];return 301 $scheme://[domain]$request_uri;}

Если необходимо получить противоположный эффект (перенаправление на «www» c «без www»):

server {server_name [domain];return 301 $scheme://www.[domain]$request_uri;}

Редирект на другой домен

Чтобы организовать перенаправление на другой сайт — например, после изменения адреса сайта — можно воспользоваться командой:

location / {rewrite ^(.*)$ $scheme://new-domain.com/$1 redirect;}

Второй вариант проще:

location / {return 301 $scheme://$http_host$request_uri;}

Редирект с http на https

Установить перенаправление с http на https (защищенный протокол SSL) можно следующим образом:server { listen 80; server_name domain.ru www.domain,ru; return 301 https://$host$request_uri;}

Здесь при всех обращениях domain.ru по протоколу http сработает перенаправление на 443-порт с использованием 301 редиректа для склейки доменов.

Чтобы установить редирект на http с https, достаточно изменить код ответа сервера:server { listen 443; server_name domain.ru www.domain,ru; return 301 http://$host$request_uri;}

Редирект на другой сервер

При необходимости использовать перенаправление на другой сервер всех запросов: … location / { proxy_pass $scheme://192.168.0.12:8080/; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }

Здесь за прием запросов браузера и ответ на них отвечает веб-сервер Nginx. Их обработка выполняется сервером с IP-адресом 192.168.0.12 (порт 8080). Таким же образом осуществляется и перенаправление на другой Nginx.

Редирект с IP адреса на домен

server { listen 80; server_name 192.168.1.15; return 301 http://site.ru$request_uri; }

Перенаправление домена без www на домен с www

server { … server_name domain.ru; return 301 http://www.$host$request_uri;}

В противном случае (редирект с www на без www) нужно использовать такое сочитание:server { …server_name «~^www\.(.*)$» ;return 301 $scheme://$1$request_uri;}

Перенаправление одного URL

location /old-adres-url.htm {rewrite ^(.*)$ http://new-domain.com/new-adres-url.htm redirect;}

Перенаправление на index.php

Сделать так, чтобы запросы из браузера обрабатывались через index.php можно таким образом:location /public/ { index index.php; try_files $uri$uri/ /public/index.php?$args;}

Если же файл расположен в корневом каталоге, перенаправление на index.php указывается командой:location / { index index.php; try_files $uri$uri/ /index.php?$args;

Перенаправление «после слэша» (/)

Следующий блок позволяет установить перенаправление «после слэша» для домена:location /mail {return 301 https://mail-server.com/mail-panel;}

Это приведет к тому, что после ввода адреса http://domain.com/mail пользователь будет перенаправлен на https://mail-server.com/mail-panel.

Стоит добавить в приведенный пример знак «=», чтобы перенаправление относилось только к этому элементу (почта), а не ко всему, что начинается с «mail»:location = /mail {return 301 https://mail-server.com/mail-panel;}

Перенаправление с изменением типа файла

Еще один вариант будет полезным, когда ссылку на файл HTML нужно автоматически заменить ссылкой на файл PHP:location ~ (.*).html$ {rewrite ^(.*)$ http://my-site.com$1.php redirect;}

Несколько доменов, один каталог и один основной домен

Этот прием пригодится при наличии нескольких доменов. Для примера возьмем следующие домены:

  • new-address.ru
  • new-address.com
  • new-address.org

Все эти домены указывают на один и тот же каталог на сервере. Соответственно, они отображают одну и ту же страницу/контент, хотя и при вводе разных адресов.

Не стоит забывать об исключении ошибки 404 («страница не найдена»), которая может возникнуть, если кто-то воспользуется ссылкой на товар/страницу с одного из альтернативных доменов. Решить эту задачу можно следующим способом:server {server_name new-adress.ru new-adress.com new-adress.org;rewrite ^ http://new-adress.ru$request_uri? permanent;}

Таким образом, все альтернативные адреса, отличные от «.ru», будут направлены на «new-address.ru», который является основным адресом.

Техническое обслуживание сайта

Следующий сценарий подойдет для сайта, который находится на техническом обслуживании. То есть в случае необходимости внесения изменений на сайте. При этом перенаправление будет работать в случае обращения к определенному IP-адресу.

Задача заключается в перенаправлении оставшихся посетителей на страницу, которая будет содержать информацию, подобную «На сайте ведутся технические работы…». Это можно осуществить следующим способом:location / {if (-f $document_root/technical-break.html) {return 503;}[Standart Code/Parameters]}error_page 503 @maintenance;location @maintenance {if ($remote_addr !~ «^123.123.123.123»){rewrite ^(.*)$ /technical-brea.html break;}}

Вместо подстановочных значений «123.123.123.123» в примере следует вписать IP-адрес своего сервера.

Дополнительные настройки

Свой IP-адрес нужно исключить с редиректа, чтобы сохранить полный доступ к сайту:if ($remote_addr !~ «^123.123.123.123»)

Вместо 123.123.123.123 следует указать IP адрес своего сервера.

Благодаря примеру ниже можно обнаружить, существует ли такой файл (technical-break.html) на сервере:if (-f $document_root/technical-break.html)

Если да, перенаправление сработает, в противном случае сайт открывается в обычном режиме.

Работа над новой версией сайта с перенаправлением на старую

  • Задача: начать работу над модернизацией действующего веб-сайта, оставить при этом посетителям доступ к его старой версии.
  • Решение: старую версию сайта можно поместить в каталог «old», а в главной директории работать над созданием новой версии.

Перенаправить пользователей на старую версию:location / {if ($remote_addr !~ «^123.123.123.123»){rewrite ^(.*)$ /old$1 redirect;}[Standart code:try_files $uri $uri/ /old/index.php?$args; ]}

Вместо «123.123.123.123» необходимо подставить IP адрес своего сервера (или адреса).

В случае, если возникает циклическое перенаправление на странице, следует добавить:location /old {[Standart Code]}

Перенаправление в зависимости от IP-адреса посетителя

Приведённый ниже способ предпочтителен с точки зрения SEO-оптимизации, так как при выполнении сценария в ссылках ничего не меняется:set $WWWDIR «old-version»;if ($remote_addr ~ MY_IP) {set $WWWDIR «new-version»;}root /var/www/[domain]/$WWWDIR/;

При посещении сайта, сервер предоставляет владельца или администратору ресурса (MY_IP) файлы из каталога new-version («новая-версия»). Когда страница посещается «сторонним лицом», сервер открывает старую версию сайта.

Перенаправление в зависимости от IP-адреса посетителя и браузера

Ситуация становится немного сложнее, когда нужно нужно организовать подключение с использованием сразу двух условий:

  1. указанного IP;
  2. строго определённого браузера.

К сожалению, Nginx не поддерживает правила объединения, поэтому здесь следует применить небольшой трюк:set $WWWDIR «old-version»;if ($remote_addr ~ MY_IP) {set $test okA;}if ($http_user_agent ~ Firefox) {set $test «${TEST}okB»;}if ($test = okAokB) {set $WWWDIR «public_html»;}root /var/www/[domain]/$WWWDIR/;

Здесь используется дополнительная переменная $TEST. С первым условием (действительным IP-адресом) она получает значение «okA», а со вторым (браузер Firefox) — дополнительное значение «okB».

В результате, значением должно быть «okAokB». И только когда оба условия выполняются одновременно ($ TEST соответствует «okAokB»), открывается доступ в соответствующий (рабочий) каталог (public_html).

Редирект в зависимости от файлов cookie

В то время как на рабочем месте часто используется статический IP-адрес, бывает, что работу над сайтом нужно проводить удалённо, с другого IP-адреса.

Хотя в таких ситуациях может помочь подключение через VPN, это не всегда возможно. Здесь применяется еще одно условие — проверка cookie:server {[…]set $WWWDIR «old-version»;if ($cookie_name-site = «test») {set $WWWDIR «public_html»;}root /var/www/[domain]/$WWWDIR/;[…]}

Если в браузере будет сохранен cookie с контентом «text», то файлы нового сайта будут открываться без редиректа.

Очевидно, понадобится механизм для сохранения соответствующего куки в браузере. Здесь достаточно применить директиву PHP:<?php$cookie_name = «name-site»;$cookie_value = «test»;setcookie( $cookie_name,$cookie_value, time() + 300, ‘/’ ); // 300 = 300 sekond = 5 minutesecho «Generated cookies»;?>

Она сохраняется на сервере (например, в файле cookie.php). Он добавляется в каталог со старой (для создания cookie) и новой страницей (обновления cookie до его истечения). Данный код выполняет следующую инструкцию:

  1.     Осуществляется переход по адресу [domain] /cookie.php.
  2.     Выполняется стандартный переход на сайт.
  3.     Вместо старого сайта открывается новый.

В приведенном выше примере cookie действителен в течение 5 минут (300 секунд), после чего — если он не будет создан снова — вместо новой страницы снова будет отображаться старая страница. Когда новая страница готова, достаточно удалить эти несколько строк.

Nginx и CloudFlare

В случае использования CloudFlare существует высокая вероятность того, что редирект не будет работать правильно для выбранного IP-адреса, то есть сервис не будет его распознавать.

В этом случае в файле конфигурации виртуального хоста следует добавить:# CloudFlare IPset_real_ip_from 173.245.48.0/20;set_real_ip_from 103.21.244.0/22;set_real_ip_from 103.22.200.0/22;set_real_ip_from 103.31.4.0/22;set_real_ip_from 141.101.64.0/18;set_real_ip_from 108.162.192.0/18;set_real_ip_from 190.93.240.0/20;set_real_ip_from 188.114.96.0/20;set_real_ip_from 197.234.240.0/22;set_real_ip_from 198.41.128.0/17;set_real_ip_from 162.158.0.0/15;set_real_ip_from 104.16.0.0/12;set_real_ip_from 2400:cb00::/32;set_real_ip_from 2606:4700::/32;set_real_ip_from 2803:f800::/32;set_real_ip_from 2405:b500::/32;set_real_ip_from 2405:8100::/32;real_ip_header CF-Connecting-IP;real_ip_recursive on;# /CloudFlare IP

Текстовый редактор Nano КОМАНДА LS LINUX