Добавление сценария обработки трафика

Для добавления нового сценария в систему 5А выполните следующие шаги:

  1. Откройте раздел Главная → Кластеры балансировки.

  2. Перейдите в кластер, в котором находится сервис, для которого будет добавлен новый сценарий обработки трафика.

  3. Откройте раздел Сценарии.

  4. Нажмите Добавить сценарий.

  5. Заполните форму Новый сценарий. Все поля, отмеченные , являются обязательными для заполнения.

    Пример заполнения формы "Новый сценарий"

    Пример заполнения формы "Новый сценарий"

    • Название — название для добавляемого сценария, которое будет использоваться в системе 5A.

    • Протокол — сетевой протокол, на котором будет обработка трафика с помощью данного сценария. Доступные варианты:

      • http,
      • https,
      • tcp,
      • udp.
    • Описание — краткое описание назначения и особенностей работы сценария.

    • Место помещения — параметр определяет, на каком этапе обработки трафика будет применяться выбранный сценарий — до или после взаимодействия с бэкенд-сервером. Доступные варианты зависят от выбранного протокола и позволяют точно контролировать, где именно происходят модификации данных.

      Протоколы HTTP/HTTPS:

      • Изменение данных на пути к серверу — сценарий применяется к HTTP-запросу, исходящему от клиента к бэкенду. Позволяет модифицировать заголовки запроса, URI, метод, тело перед отправкой на сервер.
      • Изменение заголовков ответа от сервера — сценарий применяется к HTTP-ответу, возвращаемому бэкендом клиенту. Позволяет изменять, удалять или добавлять HTTP-заголовки.
      • Изменение тела ответа от сервера — сценарий применяется к телу HTTP-ответа перед отправкой клиенту. Поддерживает поиск и замену текстовых шаблонов и манипуляции с контентом.

      Протокол TCP:

      • Изменение TCP данных — сценарий применяется к данным TCP-потока между клиентом и сервером.
    • Код сценария на Lua — программный код на языке Lua, который реализует логику работы правил сценария.

      ℹ️

      Дополнительная информация о синтаксисе и функциях Lua, применяемых для обработки трафика на Nginx, доступна в официальной документации:

      Ниже в этом разделе приведены примеры сценариев.

  6. Нажмите Сохранить для добавления сценария в систему 5А.

Примеры сценариев обработки трафика

Пример №1 — редирект по условию

Сценарий выполняет редирект на указанный адрес, если пользователь использует Яндекс-браузер.

local user_agent = ngx.var.http_user_agent;
 
if user_agent and user_agent:find("YaBrowser") then
    ngx.redirect("https://yandex.ru", 302);
else
    ngx.say("Welcome to 5A RouteWay!");
end

Пример №2 — редирект с заменой протокола

Сценарий выполняет редирект с заменой протокола HTTP на HTTPS.

local https_port = 8443 -- порт с конфигурацией HTTPS
return ngx.redirect("https://" .. ngx.var.host .. ":" .. https_port .. ngx.var.request_uri, 301)

Пример №3 — редирект с заменой части адреса

Сценарий выполняет редирект с заменой части адреса для всех запросов. Например, требуется заменить фрагмент "/api/v1/*" на новый "/api/v2/*":

local new_uri, gsub_err = ngx.re.gsub(
  ngx.var.request_uri, -- исходный URI
  [[v1]], -- регулярное выражение для поиска заменяемой части
  "v2", -- новое значение
  "jo" -- опции компиляции регулярного выражения
)
 
if new_uri ~= ngx.var.request_uri then
  return ngx.redirect(new_uri)
end

Пример №4 — кастомизация страницы ответа

Сценарий выполняет блокировку GET-запроса и возвращает код ответа 405 с HTML-страницей с описанием блокировки. В теле страницы используется случайный эмодзи в качестве демонстрации использования переменных.

-- file: handler.lua
if ngx.req.get_method() == "GET" then
    math.randomseed(ngx.now() * 1000 + ngx.worker.pid())
    local emojis = {"😡", "❌","⛔️"}
    local emoji = emojis[math.random(#emojis)]
 
    ngx.status = 405
    ngx.header["Content-Type"] = "text/html; charset=utf-8"
    ngx.say([[
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Ошибка 405</title>
<style>
  body {margin:0;display:flex;justify-content:center;align-items:center;
        height:100vh;background:linear-gradient(teal,navy);color:#fff;
        font-family:sans-serif;text-align:center;}
  h1 {font-size:4em;margin:0;}
  p {font-size:1.2em;margin:0.5em 0;}
  .emoji {font-size:5em;margin-bottom:0.3em;}
</style>
</head>
<body>
  <div>
    <div class="emoji">]] .. emoji .. [[</div>
    <h1>405</h1>
    <p>Метод GET запрещён</p>
  </div>
</body>
</html>
    ]])
    return ngx.exit(405)
end

Пример №5 — изменение payload запроса

Сценарий выполняет изменение payload-запроса путем добавления в JSON-тело запроса поля "balancer" со значением "5A".

local cjson = require "cjson"
 
local function handler()
    ngx.req.read_body()
    local data = ngx.req.get_body_data()
    if not data then
        return ngx.say("no body")  -- сообщение для отладки
    end
 
    local obj = cjson.decode(data)  -- если JSON некорректный, то тут будет ошибка
    obj["balancer"] = "5A"
    ngx.req.set_body_data(cjson.encode(obj))
end
 
local ok, err = xpcall(handler, debug.traceback)
if not ok then
    ngx.status = 500
    ngx.header["Content-Type"] = "text/plain"
    ngx.say("Lua error:\n", err)
    ngx.exit(500)
end