Nginx location

Как я вижу, тебя интересует настройка nginx, и в этой статье я постараюсь тебе помочь кое в чём разобраться. А именно — с nginx директивой location, её назначением и синтаксисом.

Location очень широко используется при конфигурировании nginx-серверов. Поэтому, если ты сам администрируешь свой сервер, чтобы избежать проблем при работе сайта, тебе сначала необходимо понять, как же эта штука работает.

Итак, директива location служит для установки конфигурации в зависимости от URI-запроса.

Синтаксис location в общем виде следующий:

Syntax:   location [=|~|~*|^~] uri { ... }
          location @name { ... }
Context: server, location

Как видите, операторы соответствия расположены в квадратных скобках, что значит, что они опциональны, их может и не быть в некоторых расположениях.

Перед тем, как перейти к более детальному изучению, нужно заметить, что location определяется в контексте server (или в location в случае вложенной директивы), и в одном настраиваемом виртуальном хосте могут использоваться разные конфигурации в зависимости от обрабатываемого сервером URI.

Префикс «@» («собака») определяет именованные расположения. Такие location’ы не используются для обработки обычных запросов. Вместо этого они используются для перенаправления запросов (пример №6). Они не могут быть вложенными и содержать в себе вложенные.

Для задания расположения, к которому будет применяться тот или иной фрагмент конфигурации, можно пользоваться как строками, так и регулярными выражениями. Что из этого выбрать — зависит от поставленной задачи.

Логика работы

Логика работы nginx при определением нужного расположения такова: сначала он ищет соответствия URI со строковыми location’ами. Если он нашёл подходящий строковый литерал с оператором соответствия «=», поиск завершается. Иначе, запомнив удовлетворяющий (если такой нашелся) максимальной длины, сравнивает с местоположениями, заданными через регулярные выражения в порядке их следования в конфигурационном файле. Если одно из регулярных выражений удовлетворило запрашиваемому ресурсу, поиск больше не продолжается. Если же ни одна регулярка не подошла, выбирается сохранённая на первом шаге строка максимальной длины.

Nginx location с регулярными выражениями

Если при указании расположения необходимо использование регулярных выражений, всегда нужно использовать один из следующих префиксов:

"~" (тильда) - для регистрозависимого соотношения URI (case sensitive matching)
"~*" (тильда звёздочка) - для регистроНЕзависимого соотношения URI (case insensitive matching)

Если необходимо помимо ресурсов в заданных регулярными выражениями расположениях обслуживать и другие, можно завести для всех остальных location /, который и будет указывать конфигурацию по умолчанию для всех запросов, которые не попали ни в один location.

На заметку: Nginx умеет декодировать URI налету. Например, для URI «/my/nginx/%20%20%20/logo.png» для определения location можно использовать «/my/nginx/   /logo.png».

Nginx location со строковыми литералами

Префикс «=» предназначен для строгого соответствия между запрошенным URI и значением location. Если они полностью совпадают, поиск сразу же прекращается.

На заметку: Если в проекте выяснилось, что на адрес «/» переходят очень часто, то для увеличения производительности будет лучше сделать строковый литерал. Например, вместо расположения location / для URI «/» использовать location = /. Это ускорит обработку, т.к. nginx на строгом совпадении с «/» завершит поиск и не будет пытаться вести поиск в других location’ах.

Выделение переменной

При соотношении URI с расположением через регулярные выражения можно выделять некоторые фрагменты строки в переменную. Как это сделать можно посмотреть в примере №7).

Примеры использования location

# Пример конфигурации №1. Для корневого URI «/»

location = / {
    # Расположение только для URI /
    # При совпадении дальнейший поиск не осуществляется
}

# Пример конфигурации №2. Базовый location

location / {
    # Совпадает с URI всех запросов, т.к. они все начинаются с "/"
    # Но! Если будут найдены соответствия в расположениях
    # с регулярными выражениями или с другим более длинным
    # строковым литералом (например, "/data/"), 
    # то конфигурация для "/" не будет применена.
}

# Пример конфигурации №3. Для URI вида «/data/.*»

location /data/ {
    # Это расположение соответствует всем URI, начинающихся с "/data/"
    # и продолжает поиск по оставшимся location'ам.
    # В этом примере регулярные выражения и другие строковые литералы
    # также будут проверены, и "location /data/" будет использован,
    # если более конкретизирующие расположения не удовлетворят искомому ресурсу.
}

# Пример конфигурации №4. Для URI вида «/img/.*»

location ^~ /img/ {
    # Соответствует любому URI, начинающемуся с "/img/".
    # Если соответствие установлено - останавливает дальнейший поиск,
    # не проверяя регулярные выражения, т.к. используется
    # префикс ^~ "крышечка/циркумфлекс тильда".
}

# Пример конфигурации №5. Для графических форматов

location ~* \.(png|ico|gif|jpg|jpeg)$ {
    # Данное расположение соответствует всем запрашиваемым URI,
    # оканчивающихся ".png", ".ico", ".gif", ".jpg" или ".jpeg".
    # При этом надо заметить, что запросы внутри расположения "/img/"
    # будут обработаны в location из примера №4
    # Т.е., если расположения из примеров №4 и №5 разместить в таком же
    # порядке в реальном конфиге, то до этого расположения ресурсов 
    # дойдут только те картинки, которые лежат вне расположения "/img/"
}

# Пример конфигурации №6. Именованный location

location / {
    error_page 404 = @fallback;
}

location @fallback {
    # Если при внутреннем перенаправлении не нужно менять URI,
    # то можно передать обработку ошибки в именованный location
}

# Пример конфигурации №7. Выделение переменной

location ~ ^/a/(?<myvar>[a-zA-Z]+) {
   # Тут можно использовать переменную $myvar,
   # которая представляет из себя строку из латиницы
   if ($myvar = "sth") { ... }
}

Примеры реальных nginx location’ов

Anti-hotlinking

Директива location для Anti-hotlinking (борьбы с использованием ресурсов с вашего сервера на сторонних ресурсах. Такой способ использования ваших сетевых ресурсов называется hotlinking). Такое поведение хитрых разработчиков может заметно увеличить нагрузку на ваш сервер. Конфигурация:

location ~ \.(gif|png|jpe?g)$ {
    valid_referers none blocked mywebsite.com *.mywebsite.com;
    if ($invalid_referer) {
       return 403;
    }
}

Запрет на скрипты внутри директорий

Следующий пример — запрет на скрипты в разрешённых для записи директориях:

location ~* /(images|cache|media|logs|tmp)/.*\.(php|pl|py|jsp|asp|sh|cgi)$ {
    error_page 403 /403.htm;
    return 403;
}

Включение autoindex

В следующем примере location используется для включения autoindex в nginx (Разрешение на вывод листинга каталога):

location /list_dir {
    autoindex on;
    autoindex_exact_size off;
    autoindex_localtime on;
}

Заключение

Как видишь, при помощи location в nginx можно очень точечно или наоборот фрагментированно настраивать ресурс.

Если эта статья тебя так увлекла, что захотелось изучить эту тему более детально, обратись к официальной документации по location в nginx. Также можешь почитать инструкцию по созданию виртуальных хостов в nginx.

Спасибо, что дочитал статью до конца! Надеюсь, что она тебе понравилась! Не забудь задать вопросы в комментариях и поделиться ссылкой с друзьями! :)

  • Сергей Кравченя

    А можно ссылку на оригинал статьи?

    • Писал давно. Насколько я помню, тут я брал примеры конфигураций из разных статей и доки. Единого оригинала как такового нет.