Using Stream scripting
Stream Scripting in FortiADC allows you to perform actions that are not supported by the current built-in feature set for Layer 7 TCP and UDP virtual servers. Stream scripts enable you to use predefined script commands and variables to manipulate the TCP/UDP request and response. You can import Stream scripts from the FortiADC GUI. To get started, FortiADC provides system predefined scripts that can be cloned for customization.
FortiADC HTTP scripts are based on Lua 5.3.
FortiADC does not support all Lua functions. For the full list of supported functions, see the Script Reference Guide. Please note that Scripting is an as is feature and does not come with any functionality or performance guarantees. |
This section includes the following:
Configuring Stream Scripting
From the FortiADC GUI, you can type or paste the script content into the configuration page. Alternatively, you can clone a system predefined script to customize. For details, see . From the HTTP Script page, you also have the option to import, export, and delete scripts.
Before you begin:
- You must have Read-Write permission for Server Load Balance settings.
After you have created a script configuration object, you can specify it in the virtual server configuration.
To create a Stream script configuration object:
- Go to Server Load Balance > Scripting.
- Click the Stream tab.
- Click Create New to display the configuration editor.
- Enter a unique name for the Stream script configuration. Valid characters are
A
-Z
,a
-z
,0
-9
,_
, and-
. No spaces. After you initially save the configuration, you cannot edit the name. - In the text box, type or paste your Stream script.
If you want to include this script as part of a multi-script configurations that allows you to execute multiple scripts in a certain order, ensure to set its priority. For more information, see Multi-script support for Stream Scripting. - Click Save.
Once the Stream script configuration is saved, you can specify it in the virtual server.
To import a Stream script:
- Go to Server Load Balance > Scripting.
- Click the Stream tab.
-
Click Import to display the file import options.
-
Click Choose File and browse for the script file. Supported file types are .tar, .tar.gz, and .zip.
-
Click Save.
Once the file is successfully imported, it will be listed in the Scripting > Stream page.
To export a Stream script:
- Go to Server Load Balance > Scripting.
- Click the Stream tab.
-
From the Stream page, select a Stream script configuration.
In the example below, the IP_COMMANDS script is selected. -
Click Export initiate the file download.
The selected script configuration will be exported as a .tar file.
To delete a Stream script:
- Go to Server Load Balance > Scripting.
- Click the Stream tab.
-
From the Stream page, select a user-defined Stream script configuration. System predefined scripts cannot be deleted.
In the example below, the test_stream script configuration is selected. -
Click Delete from the top navigation, or click (delete icon) of the configuration.
Multiple script configurations can be deleted using the Delete button on the top navigation.
Predefined Stream scripts
FortiADC provides system predefined scripts for Stream Scripting.
The following table lists the FortiADC predefined scripts available for users to apply and customize.
Predefined script | Usage |
---|---|
IP_COMMANDS | Used to get various types of IP addresses and port numbers between the client and server side. |
SNAT_COMMANDS | Allows you to overwrite client source address to a specific IP for certain clients. |
ISO8583 | Implements ISO8583 load balancing based on message content. |
RADIUS | Implements RADIUS load balancing based on message content. |
Multi-script support for Stream Scripting
Linking multiple scripts to the same virtual server
FortiADC supports the use of a single script file containing multiple scripts and applies them to a single virtual server in one execution. Different scripts can contain the same event. You can specify the priority for each event in each script file to control the sequence in which multiple scripts are executed or let the system to execute the individual scripts in the order they are presented in the multi-script file.
Currently, up to 16 individual scripts can be added to create a large multi-script file.
In practice, instead of creating a single large and complex script containing all necessary logic, it's often more advantageous to decompose it into smaller functional components represented by individual scripts. This approach offers several benefits. Firstly, executing multiple scripts concurrently is more efficient than running them sequentially. Additionally, breaking down a massive script into smaller units enhances flexibility, particularly when applying scripts to various virtual servers. Some servers may require only specific scripts, while others may utilize all available ones. With smaller, modular scripts, you have the flexibility to select and combine only the necessary components to construct a comprehensive multi-script file, each with its designated priority, and apply them collectively to a virtual server.
Apply multiple scripts shows how to link multiple scripts to a single virtual server from the GUI.
Setting script priority
Priority in a multi-script is optional, but is highly recommended. When executing a big multiple-script file, care must be taken to avoid conflicting commands among the scripts. You can set the priority for each script using the script editor on FortiADC's GUI. Valid values range from 1 to 1,000, with 500 being the default. The smaller the value, the higher the priority. Below is an example script with a set priority:
when STREAM_CLIENT_INIT priority 100 { local header = TCP:peek(20) }
To display the priority information in the GUI, you can define one and only one event in each script file, as shown below:
Script 1:
when STREAM_REQUEST_DATA priority 500 { local header = TCP:receive(20) }
Script 2:
when STREAM_REQUEST_DATA priority 500 { local header = TCP:receive(20) local len = string.byte(string.sub(header, 3, 3)) if (len < 2) then TCP:reject() end }
Script 3:
when STREAM_REQUEST_DATA priority 400 { TCP:set_src_key(get_key()) }
Script 4:
when STREAM_RESPONSE_DATA priority 600 { TCP:set_dst_key(get_key()) }
Individual script files are loaded separately into the Lua stack. A numeric value (starting from 1) is appended to each event (e.g., for STREAM_REQUEST_DATA event, there are functions STREAM_REQUEST_DATA1
, STREAM_REQUEST_DATA2,
and so on so forth).
To support multiple scripts, FortiADC:
- Supports multiple calls of redirect/routing/close function, making them re-entrant so that the final one prevails. For that purpose, the system checks the behavior of multiple calls across
redirect(), close(), and routing()
. Ifredirect()
comes first, followed byclose(),
thenclose()
prevails. Ifclose()
comes first, followed byredirect()
, thenredirect()
prevails. If you want toclose()
, you must disable the event afterclose()
. - Allows enabling or disabling events. There are times when you may want to disable the processing of the remaining scripts while a multi-script file is being executed, or want to disable processing the response completely. The mechanism serves that purpose.
Compiling principles
- All individual scripts should be pre-compiled when they are linked to a virtual server, where they can be combined into one big multi-script.
- For the same event, combine the commands in different scripts according to their priorities and orders.
- For commands of different priorities, FortiADC processes the high-priority commands first, and then the low-priority ones; for commands of the same priority, it processes them in the order they appear in the combined script.
- And if you are using multiple scripts with overlapping events for bidirectional traffic, you must ensure that the response traffic traverses the overlapping events in the expected order. By default, the scripts applied to the same virtual server will run in the order in which they are applied, regardless of the direction of traffic flow.
- For a specified event, you must make sure to avoid the conflict commands in different scripts. For example, if you have multiple scripts applied to the same virtual server and the scripts contain both request and response logic, the default execution order is like this:
but NOT like this:
As shown above, FortiADC cannot control the order in which events in the scripts are executed. The only way to enforce the execution order for response traffic is to use the event priority command, as we have discussed above. When setting the priorities, pay special attention to both request and response flows.
Special notes
When using the multi-script feature, keep the following in mind:
- The multi-script feature is supported on all FortiADC hardware platforms.
- Currently, the feature can be applied to Layer 7 virtual servers on TCP or UDP protocols only.
- Scripts are VDOM-specific, and cannot be shared among different VDOMs.
- Session tables set up using scripts must be synced through high-availability (HA) configuration.
- Each multi-script configuration can contain up to 256 individual scripts, each being no more than 32 kilobytes.