Custom Persistence with DataScript
Description
Avi Vantage includes a number of common methods of persisting clients to the same server for a duration of time. For some applications, it may be valuable to have more customization to the behavior of the persistence, or to support a wider array of application types. See Overview of Server Persistence for other methods.
Persistence is based on the ability to uniquely identify a user, and to stick or persist them to a destination server for a period of time.
The primary DataScript function for creating custom persistence are the table commands, which enable storing data locally on an Avi Service Engine for a configurable length of time. The stored data is also replicated to other relevant Service Engines for high availability and scale.
DataScript
avi.vs.table_insert( [table_name,] key, value [, lifetime] ) | Store custom data in a time-based table |
avi.vs.table_lookup( [table_name,] key [, lifetime_exten] ) | Lookup data in a table |
avi.vs.table_remove( [table_name,] key ) | Remove data from a table |
avi.vs.table_refresh( [table_name,] key [, lifetime_exten] ) | Update the expire time for a table entry |
JSessionID Example
The following example persists based upon an HTTP cookie sent from a server with a unique JSessionID. Subsequent client requests include that cookie, which is used to persist requests to the same server.
HTTP Response event: Add persist for 20 minutes, or update timer if entry already exists
if avi.http.get_cookie("JSESSIONID") then
avi.vs.table_insert(avi.http.get_cookie("JSESSIONID"), avi.pool.server_ip(), 1200)
end
HTTP Request event: Rename the pool before applying to a virtual service
if avi.http.get_cookie("JSESSIONID") then
avi.pool.select("poolname", avi.vs.table_lookup(avi.http.get_cookie("JSESSIONID")))
end
SSL Session ID Persistence
SSL/TLS session resumption is a mechanism to reduce the full SSL handshake between the client and server when a new connection is established. The server puts a non-zero session ID in the Server Hello, when the SSL handshake is complete. The client persists and reuses the session ID throughout the session-timeout to reduce the full SSL handshake.
Persistence is the ability to identify a session with the session ID provided by the server and to stick or persist them to a destination server for some time.
NSX Advanced Load Balancer provides a way to persist session ID mapped to the server and port information using VS_DATASCRIPT_EVT_L4_REQUEST
and VS_DATASCRIPT_EVT_L4_RESPONSE
events.
Note: SSL/TLS session resumption using session ID is not supported for the TLS1.3 version.
Persistence Table
The primary DataScript function for creating session ID persistence is the table commands which enable storing data locally on an NSX Advanced Load Balancer SE for a configurable length of time. The stored data is replicated to other relevant SEs for high availability and scale.
DataScripts Examples
DataScript uses the existing Default-TLS DataScript template to extract session ID from the SSL handshake. The following are the two DataScripts required for L4 persistence:
VS_DATASCRIPT_EVT_L4_REQUEST
DataScript: The session ID is extracted from Client Hello. If the session ID is found, then mapped server information is found using table commands. Otherwise, it is considered as a new session.function string.tohex(str) return (str:gsub('.', function (c) return string.format('%02X', string.byte(c)) end)) end local avi_tls = require "Default-TLS" local buffered = avi.l4.collect(10) local payload = avi.l4.read() local len = avi_tls.get_req_buffer_size(payload) if ( buffered < len ) then avi.l4.collect(100) end if ( avi_tls.sanity_check(payload) ) then local h = avi_tls.parse_record(payload) local ses = avi_tls.get_session_id(h) if ses ~= nil then persisted_info = avi.vs.table_lookup(string.tohex(ses)) if persisted_info ~= nil then sip, sport = persisted_info:match("([^,]+),([^,]+)") if(avi.pool.get_server_status("tls-pp-pool", sip, sport) ~= 1) then avi.vs.table_remove(string.tohex(ses)) else avi.pool.select("tls-pp-pool", sip, tonumber(sport)) end end avi.l4.ds_done() end end avi_tls = nil
VS_DATASCRIPT_EVT_L4_RESPONSE
DataScript: The session ID is extracted from Server Hello. If the session ID is found, then the session ID and server information are inserted into the persistent table using table commands.function string.tohex(str) return (str:gsub('.', function (c) return string.format('%02X', string.byte(c)) end)) end local avi_tls = require "Default-TLS" local buffered2 = avi.l4.collect(10) local payload2 = avi.l4.read() local len = avi_tls.get_req_buffer_size(payload2) if ( buffered2 < len ) then avi.l4.collect(100) end if ( avi_tls.sanity_check(payload2) ) then local h = avi_tls.parse_record(payload2) local ses_server = avi_tls.get_session_id(h) if ses_server ~= nil then sip, sport = avi.pool.get_server_info() avi.vs.table_insert(string.tohex(ses_server), sip..","..sport) avi.l4.ds_done() end end avi_tls = nil
Document Revision History
Date | Change Summary |
---|---|
January 30, 2023 | Added SSL Session ID Persistence section for version 22.1.3 |