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

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

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

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

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

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

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

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

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

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

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

      • 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