Сценарии
Общие сведения о Сценариях
Сценарии – это lua-скрипты, являющиеся дополнением к основным параметрам конфигурации Виртуальных Серверов.
С помощью Сценариев (lua-скриптов) можно:
-
выбирать Сервер Балансировки (Content Switching (cs));
-
изменять содержимое запросов/ответов (Rewrite);
-
отвечать на HTTP-запрос (Responder);
-
прерывать нежелательные соединения.
lua-скрипты применяются к:
-
Виртуальному Серверу для:
-
выбора Сервера Балансировки (Content Switching (cs));
-
ответа на HTTP-запрос (Responder);
-
изменения содержимого запросов (Rewrite);
-
прерывания нежелательного соединения;
-
-
Серверу балансировки для:
-
ответа на HTTP-запрос (Responder) (например, при условии получении ответа);
-
изменения содержимого ответов (Rewrite);
-
прерывания нежелательного соединения (например, при условии получении ответа).
-
Условия выполнения того или иного действия определяются:
-
логическими выражениями
if,elseif,else,end; -
любыми данными, полученными из запроса, а также их комбинацией. Например:
-
if client.http_req.host == "abc.ru" then– если имя хоста из запроса эквивалентно «abc.ru», то выполнить какое-либо действие; -
if (client.http_req.host == "abc.ru" and client.remote_p.ip == "10.140.0.200") then– если имя хоста из запроса эквивалентно «abc.ru», и запрос пришел с IP-адреса 10.140.0.200, то выполнить какое-либо действие.
-
Можно использовать возможности языка для работы с полученными данными, поскольку правила с четким соответствием не всегда применимы.
Пример для curl qwe.123.ru/abczxc (см. Пример выражений для работы с данными):
> GET /abczxc HTTP/1.1
> Host: qwe.123.ru
> User-Agent: curl/7.81.0
| Выражение | Результат | Комментарий |
|---|---|---|
|
|
Эквивалентно |
|
|
|
|
|
Содержит значение |
|
|
Вернет строку, значение ДО « .123.ru» |
Использование в Сценариях балансировки
Обработка правил в Сценариях балансировки осуществляется через глобальные переменные:
-
storage– содержит методы для работы с путями к каталогам, которые будут доступны при вызове изlua-скрипта; -
client– содержит методы для работы с клиентом и запросом.
Обработка правил Сценария останавливается после выражения: client.action = "xxx".
|
Описание полей приведено в таблице ниже.
| Поле | Тип поля | Описание |
|---|---|---|
|
Строка |
Возвращает путь к каталогу, к которому можно обращаться по его наименованию ( В текущей версии Пример: выражение |
|
Строка |
Формирует полный путь ( В текущей версии Пример: выражение |
| Поле | Тип поля | Описание | ||
|---|---|---|---|---|
|
Структура |
Псевдоним, то же самое, что |
||
|
Структура |
Содержит поля локальной точки подключения. Доступно только для чтения |
||
|
Строка |
Возвращает локальный IP-адрес подключения (IP-адрес Виртуального Сервера, |
||
|
Строка |
Возвращает локальный порт подключения (порт Виртуального Сервера, |
||
|
Структура |
Псевдоним, то же самое, что |
||
|
Структура |
Содержит поля удаленной точки подключения (клиента). Доступно только для чтения |
||
|
Строка |
Возвращает IP-адрес клиента. Доступно только для чтения |
||
|
Целое |
Возвращает порт клиента. Доступно только для чтения |
||
|
Строка |
Определяет действие, которое необходимо выполнить. Для Сценария балансировки:
Для Сценария модификации ответа:
При использовании аутентификации пользователя:
|
||
|
Строка |
Определяет имя Сервера Балансировки. Пример: При использовании в Сценарии балансировки свойство чтения и записи применяется, если При использовании в Сценарии модификации ответа доступно только чтение, ответ будет содержать имя Сервера Балансировки |
||
|
Строка |
Определяет имя Шлюза. Пример: |
||
|
Строка |
Возвращает статус Сервера Балансировки ( Возвращаемые значения:
|
||
|
Структура или |
Класс для работы с HTTP-запросами. Описание полей приведено в таблице (см. таблицу Описание полей структуры
|
||
|
Структура |
Класс для работы с HTTP-ответами. Существует только для Сценария модификации ответа. Описание полей приведено в таблице (см. таблицу Описание полей структуры |
||
|
Строка |
Возвращает IP-адрес Реального Сервера |
||
|
Строка |
Возвращает порт Реального Сервера |
||
|
Структура |
Класс для генерации HTTP-ответа. Применяется, если |
||
|
Структура |
Класс для работы с AAA. Описание полей приведено в таблице (см. таблицу Описание полей структуры |
||
|
Структура или |
Опциональное поле. Содержит |
||
|
Структура или |
Содержит |
||
|
Структура |
Класс для работы с SSO. Описание полей приведено в таблице (см. таблицу Описание полей структуры |
||
|
Структура |
Класс для чтения информации из сертификата клиента. Содержит данные начального этапа установления TLS-соединения. Описание полей приведено в таблице (см. таблицу Описание полей структуры
|
|
Примеры из таблицы ниже отражены в этом ответе на запрос к узлу
|
| Поле | Тип поля | Описание |
|---|---|---|
Работа с заголовками – |
||
|
Целое |
Возвращает количество заголовков |
|
Строка |
Возвращает пару: ключ и значение. Пример: |
|
Таблица (список строк) |
Удаляет значение заголовка, индекс (
|
|
Целое |
Возвращает количество всех заголовков с именем |
|
Строка или |
Возвращает пару: ключ (имя заголовка с учетом регистра) и значение:
Значения параметров:
|
|
Таблица (список строк) |
Устанавливает значение заголовка (
Значения параметров:
|
|
Таблица (список строк) |
Удаляет заголовок (
Значения параметров:
|
|
Строка |
Добавляет (продвигает) заголовок (
Значения параметров:
|
|
Таблица (список строк) |
Возвращает таблицу строк значений заголовка |
|
Таблица (список строк) |
Удаляет или перезаписывает все вхождения заголовка |
|
Таблица (список строк) |
Устанавливает значение для всех заголовков |
Дополнительные свойства и методы |
||
|
Целое |
Возвращает версию протокола HTTP: целое число, в котором младший десяток соответствует значению после точки, старший десяток – перед точкой. Поддерживаются версии: 1.0, 1.1. Пример: для HTTP/1.0 будет возвращен ответ: |
|
Строка |
Возвращает метод запроса (GET, POST, HEAD, DELETE, PATCH, PUT, OPTIONS, CONNECT, TRACE и др.). Пример: |
|
Строка |
Возвращает путь запроса. Пример: |
|
Строка |
Возвращает запрос. Пример: |
|
Строка |
Возвращает полный путь запроса. Пример: |
|
Строка |
Возвращает значение заголовка |
|
Логический |
Возвращает значение |
|
Строка |
Возвращает тело HTTP-запроса. Поле существует, если |
| Поле | Тип поля | Описание |
|---|---|---|
|
Целое |
Возвращает количество заголовков |
|
Строка |
Возвращает пару: ключ и значение |
|
Таблица (список строк) |
Удаляет значение заголовка, индекс (
|
|
Целое |
Возвращает количество всех заголовков с именем |
|
Строка или |
Возвращает пару: ключ (имя заголовка с учетом регистра) и значение:
Значения параметров:
|
|
Таблица (список строк) |
Устанавливает значение заголовка (
Значения параметров:
|
|
Таблица (список строк) |
Удаляет заголовок (
Значения параметров:
|
|
Строка |
Добавляет (продвигает) заголовок (
Значения параметров:
|
|
Таблица (список строк) |
Возвращает таблицу строк значений заголовка |
|
Таблица (список строк) |
Удаляет или перезаписывает все вхождения заголовка |
|
Таблица (список строк) |
Устанавливает значение для всех заголовков |
|
Целое |
Возвращает или устанавливает код HTTP-ответа. Пример: |
|
Логический |
Возвращает |
|
Строка |
Возвращает тело HTTP ответа. Поле существует, если |
| Поле | Тип поля | Описание |
|---|---|---|
Работа с заголовками |
||
|
Структура |
Класс для работы с заголовками ответа. Методы и свойства аналогичны |
|
Целое |
Возвращает или устанавливает версию протокола HTTP как целое число:
|
|
Целое |
Возвращает или устанавливает код HTTP-ответа. Пример: |
|
Строка |
Возвращает или устанавливает тело HTTP-ответа |
| Поле | Тип поля | Описание |
|---|---|---|
|
Строка |
Задает AAA-Профиль. Название AAA-Профиля выбирается из конфигурации, в случае несовпадения выводится ошибка |
|
Строка |
Возвращает идентификатор пользователя в формате Для того, чтобы поле было непустое, необходимо установить |
|
Целое |
Возвращает количество неудачных попыток аутентификации за указанный в конфигурации период |
|
Строки |
Возвращает, устанавливает или удаляет атрибуты пользователя, которые создаются во время процедуры аутентификации. Значения параметров:
Поддерживается добавление индивидуальных атрибутов, которые будут храниться в течение жизни сессии |
|
||
|
||
|
||
|
| Поле | Тип поля | Описание | ||
|---|---|---|---|---|
Структура |
||||
|
Перечисление |
Содержит тип адреса. Возможные значения:
|
||
|
Перечисление |
Возможные значения:
|
||
|
Строка |
Содержит адрес назначения:
|
||
|
Логический |
Значение |
||
|
Логический |
Значение |
||
|
Логический |
Значение |
||
|
Логический |
Значение |
||
|
Логический |
Значение |
||
|
Строка, структура или |
Содержит адрес источника:
|
||
|
Строка |
Возвращает TLV типа |
||
|
Перечисление |
Содержит тип транспортного протокола. Возможные значения:
|
||
|
Целое |
Версия PROXY-протокола. Возможные значения:
|
||
Структура |
||||
|
Логический |
Указывает на то, что пользователь предоставил сертификат в данном соединении |
||
|
Логический |
Указывает на то, что пользователь предоставил сертификат как минимум один раз в рамках TLS-сессии данного соединения |
||
|
Логический |
Указывает на то, что пользователь предъявил сертификат и он был успешно проверен |
||
|
Строка |
Название алгоритма шифрования |
||
|
Строка |
Значение поля |
||
|
Строка |
Название алгоритма, используемого для генерации ключа сертификата |
||
|
Строка |
Название алгоритма, используемого для подписи сертификата |
||
|
Логический |
Указывает на то, что используется TLS-соединение |
||
|
Строка |
Версия TLS |
||
| Поле | Тип поля | Описание |
|---|---|---|
|
Строка |
Задает SSO-Профиль |
|
Строка |
Устанавливает имя пользователя, если требуется |
|
Строка |
Устанавливает пароль пользователя, если требуется |
|
Структура |
Устанавливает параметры SSO-Профиля. Примеры:
|
| Поле | Тип поля | Описание |
|---|---|---|
|
Строка |
Возвращает строку сертификата, закодированная в формате |
|
Строка |
Возвращает версию протокола TLS из сертификата. Поддерживается только для mTLS |
|
Строка |
Возвращает серийный номер сертификата. Поддерживается только для mTLS |
|
Таблица (список строк) |
Возвращает поля субъекта сертификата. Поддерживается только для mTLS. Значения параметра
|
|
Таблица (список строк) |
Возвращает поля издателя сертификата. Поддерживается только для mTLS. Значения параметра
|
|
Строка |
Возвращает значение поля |
|
Строка |
Возвращает значение поля |
|
Строка |
Возвращает |
Использование в Сценариях ошибок
Обработка правил Сценария ошибок осуществляется через глобальные переменные:
-
storage– аналогично Сценариям балансировки содержит методы для работы с путями к каталогам, которые будут доступны при вызове изlua-скрипта; -
client– аналогично Сценариям балансировки содержит методы для работы с клиентом и запросом. Доступны все поля, кроме:client.bs,client.action,client.aaa,client.sso.
Описание используемых полей приведено в таблице (см. таблицу Описание полей для Сценариев ошибок).
| Поле | Тип поля | Описание |
|---|---|---|
|
Структура |
Возвращает информацию об ошибке в
|
|
Целое |
Код ошибки |
`context.bs ` |
Строка |
Возвращает Сервер Балансировки |
|
Строка |
Возвращает IP-адрес Реального Сервера |
|
Целое |
Возвращает порт Реального Сервера |
|
Строка |
Заголовок, на котором был превышен лимит |
|
Строка |
Возвращает код ошибки в виде строки |
`status_to_string(status_code) ` |
Строка |
Возвращает код HTTP-статуса в виде строки |
Поддерживаемые коды ошибок перечислены в таблице (см. таблицу Описание кодов для Сценариев ошибок).
| Поле | Описание |
|---|---|
|
Превышено ограничение на размер одного заголовка |
|
Превышено ограничение на общий размер заголовков |
|
Превышено ограничение на количество заголовков |
|
Неправильное значение заголовка |
|
Несколько заголовков |
|
Неправильная или неподдерживаемая версия HTTP |
|
Несколько заголовков |
|
|
|
Метод |
|
Другие ошибки разбора HTTP-запроса |
|
Ошибка выполнения Сценария балансировки ( |
|
Сервер Балансировки, который вернул Сценарий ( |
|
Ошибка аутентификации пользователя |
|
Сервер Балансировки, который вернул Сценарий ( |
|
Ошибка подключения к Реальному Серверу |
|
Ошибка при передаче запроса Реальному Серверу |
|
Ошибка при чтении ответа от Реального Сервера |
|
Превышено ограничение на размер одного заголовка |
|
Превышено ограничение на общий размер заголовков |
|
Превышено ограничение на количество заголовков |
|
Неправильное значение заголовка |
|
Несколько заголовков |
|
Другие ошибки разбора HTTP-ответа |
Использование в Сценариях SSL
Обработка правил в Сценариях SSL осуществляется через глобальную переменную:
-
handshake– содержит методы для работы с SSL-Политиками. Доступно только для Сценариев SSL.
Описание полей приведено в таблице ниже.
| Поле | Тип поля | Описание |
|---|---|---|
|
Строка |
Возвращает имя сервера, к которому подключается клиент. Поле доступно только на чтение, может быть пустым |
|
Таблица (список строк) |
Возвращает список протоколов в порядке очередности, которые могут быть выбраны сервером. Поле доступно только на чтение |
|
Таблица (список строк) |
Возвращает список алгоритмов шифрования, поддерживаемых клиентом. Поле доступно только на чтение |
|
Строка |
Возвращает идентификатор Серверного SSL-Профиля, используемого для установки соединения. По умолчанию поле пустое. Если значение остается пустым, то используется Серверный SSL-Профиль по-умолчанию из конфигурации Серевера Балансировки |
|
Строка |
Определяет действие, которое необходимо выполнить:
|
Добавление Сценария
Добавление Сценария выполняется одним из способов:
-
из интерфейса командной строки Termidesk Connect;
-
из веб-интерфейса Termidesk Connect (см. подраздел Веб. Сценарии).
Пример команды с указанием порядка исполнения и имени файла Сценария:
set vs HTTP <имя> luarules 5 script test.lua
|
Файлы должны располагаться:
Порядковый номер определяет очередность выполнения файла Сценария: например, Сценарий с порядковым номером 10 будет исполнен раньше, чем Сценарий с порядковым номером 15. При этом правила в файлах Сценариев также обрабатываются по порядку:
Правила Сценария могут располагаться как в одном файле, так и в нескольких. |
Примеры Сценариев для изменения содержимого запросов
Пример 1. Если имя хоста содержит текст «abc» и запрос пришел из сети 192.0.2.0/24, то добавить заголовок «XFF: <IP-адрес_пользователя_при_подключении>», и перенаправить запрос на Сервер Балансировки «lb1».
Код:
if (client.http_req.host:find("abc") and client.remote_p:is_network("192.0.2.0/24")) then
client.http_req.header:field_set("XFF", client.remote_p.ip)
client.bs = "lb1"
client.action = "bs"
end
Результат:
WEB -- 03<p>Method GET</p><p>URL on server: /</p><p>REQ
Headers: </p>Host: abc.domain.ru
User-Agent: curl/7.81.0
Accept: */*
XFF: 192.0.2.5
Пример 2. Если имя хоста начинается с «abc», то добавить заголовок «XFF: <IP-адрес_пользователя_при_подключении>» и «Remote-port: <порт-источник_на_клиенте>», и перенаправить запрос на Сервер Балансировки «lb1».
Код:
function startswith(text, prefix)
return text:find(prefix, 1, true) == 1
end
if startswith(client.http_req.host, "abc") then
client.http_req.header:field_set("Remote-port", client.remote_p.port)
client.http_req.header:field_set("XFF", client.remote_p.ip)
client.bs = "lb1"
client.action = "bs"
end
Пример 3. Если путь запроса содержит «app», то при наличии заголовка X-Forwarded-For добавить IP-адрес клиента в конец запроса. Если заголовка не было в запросе, то добавить новый. Перенаправить запрос на Сервер Балансировки «lb1».
Код:
if client.http_req.path:find("abc") then
if client.http_req.header:field_count("X-Forwarded-For") > 0 then
xff, xffip = client.http_req.header:field_get("X-Forwarded-For")
client.http_req.header:field_set("X-Forwarded-For", xffip ..", "..client.remote_p.ip)
else
client.http_req.header:field_set("X-Forwarded-For", client.remote_p.ip)
end
client.bs = "lb1"
client.action = "bs"
end
Пример 4. Подменить домен «ru» на домен «local» (например, если запрос идет к app.domain.ru, то в сторону Реального Сервера должен прийти app.domain.local). В начале пути запроса добавить «/external» и перенаправить запрос на Сервер Балансировки «lb1».
Код:
client.http_req.host = client.http_req.host:match("(.*).ru") .. ".local"
client.http_req.path = "/external" .. client.http_req.path
client.bs = "lb1"
client.action = "bs"
Примеры Сценариев для ответа на запрос
Пример 1. Если метод не GET или не HEAD, то сбросить соединение.
Код:
if (client.http_req.method ~= "GET" and client.http_req.method ~= "HEAD") then
client.action = "drop"
end
Пример 2. Перенаправить соединение с HTTP на HTTPS.
Код:
client.respond.status = 302
client.respond.header["Location"] = "https://" .. client.http_req.host .. client.http_req.path
client.respond.header["Connection"] = "close"
client.action = "respond"
Пример 3. Если запрос из сети 192.0.2.0/24, то ответить HTML-страницей и параметрами запроса.
Код:
if client.remote_p:is_network("192.0.2.0/24") then
client.respond.header["Connection"] = "close"
client.respond.header["Content-type"] = 'text/html
client.respond.body = [[<html>
<body>
<meta charset="UTF-8">
<h1>Lets goodbye!</h1>
<p>Доступ запрещен</p>
</body>
</html>]] .. "IP: " .. client.remote_p.ip .. "\n TRY: " .. client.http_req.host .. client.http_req.path .. "\n" .. " Vserver: " .. client.local_p.ip .. ":" .. client.local_p.port
client.action = 'respond'
Примеры Сценариев для выбора Сервера Балансировки
Пример 1. Передача любого запроса на Сервер Балансировки «lb1».
Код:
client.bs = "lb1"
client.action = "bs"
Пример 2. Если имя хоста в запросе точно соответствует «abc.domain.ru», то направить запрос на Сервер Балансировки «lb1». В противном случае вернуть код ответа 403 (по умолчанию вернется ошибка 503).
Код:
if client.http_req.host == "abc.domain.ru" then
client.bs = "lb1"
client.action = "bs"
else
client.respond.status = 403
client.action = "respond"
end
Пример 3. Если имя хоста содержит текст «abc» и запрос пришел из сети 192.0.2.0/24, то вернуть Сервер Балансировки «lb1». В противном случае вернуть код ответа 403 (по умолчанию вернется ошибка 503).
Код:
if (client.http_req.host:find("abc") and client.remote_p:is_network("192.0.2.0/24"))
then
client.bs = "lb1"
client.action = "bs"
else
client.respond.status = 403
client.action = "respond"
end
Пример 4. Если путь содержит:
-
«red», то вернуть Сервер Балансировки «lb1»;
-
«green», то вернуть Сервер Балансировки «lb2».
Если не сработало ни одно из условий выше, то вернуть Сервер Балансировки «lb-default».
Код:
if client.http_req.path:find("red") then
client.bs = "lb1"
client.action = "bs"
elseif client.http_req.path:find("green") then
client.bs = "lb2"
client.action = "bs"
else
client.bs = "lb-default"
client.action = "bs"
end