Processing Connections in Lua

In this section

General Information

Requirements for Connection Processing Script

Examples

Tables in Use:

InterceptContext,

TcpEndpoint

Available Auxiliary Modules:

drweb,

drweb.lookup

General Information

The Dr.Web Firewall for Linux component supports interaction with the Lua interpreter (version 5.3.4 is supplied with Dr.Web Mail Security Suite). Lua scripts can be used by Dr.Web Firewall for Linux for scanning a connection in advance prior to analyzing it using SpIDer Gate.

The connection will be analyzed using a script, if a path to this script is specified in Dr.Web Firewall for Linux settings (the InterceptHook parameter). Otherwise, connection processing is performed by using default settings and processing rules specified in the component settings (RuleSet* parameters).

For more examples of connection processing scripts, follow the link:
https://github.com/DoctorWebLtd/drweb-lua-examples/tree/master/firewall.

Requirements for Connection Processing Script

The script must contain a global function being an entry point in the connection scanning module (Dr.Web Firewall for Linux calls this function for processing newly received connections). The function must match the following calling conventions:

function nameintercept_hook;

the only argument—Lua InterceptContext table (provides access from the function to information about the connection being processed; see the table description below);

the only return value—string value from the table below:

Value

Verdict description

pass

Skip the connection without using SpIDer Gate to scan it

check

Scan the connection using SpIDer Gate

reject

Reject the connection (the client that initiated the connection will receive a TCP package with an RST flag)

drop

Disconnect (the client that initiated the connection will receive no acknowledgement)

Examples
 

1.A simple script returning the pass verdict to Dr.Web Firewall for Linux, which indicates that the connections are not to be scanned:

-- Connection scanning function written by the user
function intercept_hook(ctx)
  return "pass" -- do not scan the connection
end

2.The script instructs Dr.Web Firewall for Linux to scan all connections being established with the exception of:

outgoing local connections from applications running with the privileges of the user from the drweb group;

connections from privileged ports (regardless of the owner of a connection and its direction);

outgoing connections from IP addresses of the local subnet.

function intercept_hook(ctx)
  -- Do not scan connections initiated from the local
  -- host (divert == "output") by an application on behalf of the group
  -- "drweb" (group == "drweb")
  if ctx.divert == "output" and ctx.group == "drweb" then
    return "pass"
  end

  -- Do not scan connections initiated from
  -- privileged ports (the range is from 0 to 1024)
  if ctx.src.port >= 0 and ctx.src.port <= 1024 then
    return "pass"
  end

  -- Do not scan connections from local subnet addresses
  -- (the IP address range of 127.0.0.1/8)
  if ctx.src.ip.belongs("127.0.0.0/8") then
    return "pass"
  end

  -- Connection is scanned by default
  return "check"
end

Tables in Use

InterceptContext Table

The table is used to pass data on the connection being processed to the intercept_hook function. One of the following actions can be performed on the basis of this data:

skip the connection,

disconnect,

pass the connection to SpIDer Gate for scanning.

The Dr.Web Firewall for Linux component fills this table with data. Some data in the table is already available by the time the intercept_hook function is called, the remaining (so called “lazy”) data will be calculated directly upon quering the corresponding field of this table.

Field

Description

Data type

src

Address and port of the client that initiated the connection

Example:

if ctx.src.port >= 0 and ctx.src.port <= 1024 then
  return "pass"
end

TcpEndpoint table

dst

Address and port of the server, the connection to which was initiated by the client

Example:

if ctx.dst.ip.belongs("10.20.30.41/8") then
  return "reject"
end

TcpEndpoint table

divert

Type of an intercepted connection:

output—outgoing connection;

input—incoming connection;

forward—transit connection.

Example:

if ctx.divert == "forward" then
  return "check"
end

String

iface_in

Name of the interface from which the connection was initiated.

If the name of the interface was not identified, the field has the nil value.

String

iface_out

Name of the interface to which packets were sent after initiating the connection.

If the name of the interface was not identified, the field has the nil value.

String

uid

Identifier of the user on behalf of whom the outgoing connection was initiated.

If the connection type (divert) is not output or UID cannot be identified, the field has the nil value.

Integer

gid

Identifier of the group on behalf of which the outgoing connection was initiated.

If the connection type (divert) is not output or GID cannot be identified, the field has the nil value.

Integer

user

User on behalf of whom the outgoing connection was initiated.

If the connection type (divert) is not output or the user name cannot be identified, the field has the nil value.

String

group

Group on behalf of which the outgoing connection was initiated.

If the connection type (divert) is not output or the group name cannot be identified, the field has the nil value.

String

pid

Identifier of the process (PID) on behalf of which the outgoing connection was initiated.

If the connection type (divert) is not output or the PID cannot be identified, the field has the nil value.

Integer

exe_path

Executable path of the application that initiated the outgoing connection.

If the divert field (see above) has the input or forward value or the executable path cannot be identified, the field has the nil value.

String

Overridden metamethods: None

TcpEndpoint Table

The table describes a client or server connection point address.

Field

Description

Data type

ip

IP address

IpAddress Table

port

Port number

Integer

Overridden metamethods:

__tostring is a function that transforms TcpEndpoint into a string, for example, "127.0.0.1:443" (IPv4) or "[::1]:80" (IPv6);

__concat is a function that joins TcpEndpoint to a string

Available Auxiliary Modules

The following custom modules listed in the table can be imported into Lua program space for interaction with Dr.Web Mail Security Suite.

Name of the module

Function

Module that provides functions for writing messages from a Lua program to the log of the Dr.Web Mail Security Suite component that started this program, as well as means to run Lua procedures asynchronously

Module that provides tools to query data from external sources using the Dr.Web LookupD module

Contents of the drweb module

1.Functions

The module provides a set of functions.

Storing messages from the Lua program in the Dr.Web Mail Security Suite component log:

log(<level>, <message>) writes the <message> string to the Dr.Web Mail Security Suite log at the <level> level (the required level is defined using one of the following values (a string): debug, info, notice, warning, error);

debug(<message>) writes the <message> string to the Dr.Web Mail Security Suite log at the debug level;

info(<message>) writes the <message> string to the Dr.Web Mail Security Suite log at the info level;

notice(<message>) writes the <message> string to the Dr.Web Mail Security Suite log at the notice level;

warning(<message>) writes the <message> string to the Dr.Web Mail Security Suite log at the warning level;

error(<message>) writes the <message> string to the Dr.Web Mail Security Suite log at the error level.

Managing synchronization of Lua procedures:

sleep(<sec.>) pauses execution of a Lua procedure instance for a specified number of seconds;

async(<Lua function>[, <argument list>]) starts the specified function asynchronously and passes the specified argument list to it. The async function call completes immediately, and the return value (the Future table) allows you to obtain the result of the <Lua function>.

Storing the information about an IP address in the form of the IpAddress table:

ip(<address>) indicates an IP address (IPv4 or IPv6) if the form of the IpAddress table.

Retrieving external data from a text file:

load_set(<file path>) generates a table with its values assigned to true from the contents of a specified text file; strings read from the file are used as keys. Empty strings and strings consisting only of white spaces are ignored.

load_array(<path to file>) generates a string array from the contents of a specified text file. Empty strings and strings consisting only of white spaces are ignored.

2.Tables

The Future table describes a pending result of performing a function using the async function.

Field

Description

Data type

wait

Function that returns a result of the function started using the async function. If the function has not completed its execution yet, it waits for the completion and returns its result. If the function is completed before wait is called, the result is returned immediately. If the started function fails, the wait call generates the same error.

Function

Overridden metamethods: None

The IpAddress table describes an IP address.

Field

Description

Data type

belongs

Function checks an IP address stored in the IpAddress table for belonging to specified subnets (IP address ranges).

Accepts a single argument—an array of strings such as <IP address> or <IP address>/<mask>, where <IP address> is a host address or a network address (for example, 127.0.0.1), and <mask> is a subnet mask (can be specified as an IP address, for example, 255.0.0.0, or as an integer, for example, 8).

Returns a Boolean value:

true indicates that the address matches at least one of the specified IP addresses or belongs to at least one of the specified subnets (a range of IP addresses);

false—if the address does not match any one of the specified IP addresses or does not belong to any of the specified subnets

Function

Overridden metamethods:

__tostring is a function that transforms IpAddress into a string, for example, 127.0.0.1 (IPv4) or ::1 (IPv6);

__concat is a function that joins IpAddress to a string;

__eq is a function that checks whether two IpAddress are equal;

__band is a function that allows applying a mask, for example: dw.ip('192.168.1.2') & dw.ip('255.255.254.0')

3.Examples

Log messages generated by a procedure started asynchronously:

local dw = require "drweb"

-- This function returns a string received as an argument
-- after a delay of two seconds
function out_msg(message)
 dw.sleep(2)
 return message
end

-- "Main" function
function intercept(ctx)
 -- Output a string at the notice level to the log of Dr.Web Mail Security Suite
 dw.notice("Intercept function started.")

 -- Run two instances of the out_msg function asynchronously
 local f1 = dw.async(out_msg, "Hello,")
 local f2 = dw.async(out_msg, " world!")

 -- Wait for the completion of the instances of the function
 -- out_msg and log their results
 -- Dr.Web Mail Security Suite at the debug level
 dw.log("debug", f1.wait() .. f2.wait())
end

Create a scheduled procedure:

local dw = require "drweb"

-- Store the Future table as a futurе global variable to
-- prevent its removal by the garbage collector
future = dw.async(function()
   while true do
     -- Log the following message every day
     dw.sleep(60 * 60 * 24)
     dw.notice("A brand new day began")
   end
end)

Transform a string to an IP address:

local dw = require "drweb"

local ipv4 = dw.ip("127.0.0.1")
local ipv6 = dw.ip("::1")
local mapped = dw.ip("::ffff:127.0.0.1")

 

Contents of the drweb.lookup module

1.Functions

The module provides the following functions:

lookup(<query>, <parameters>) queries data from an external storage available via the Dr.Web LookupD module. The <query> argument must correspond to a section in Dr.Web LookupD settings (the <type>@<tag>string). The <parameters> argument is optional and describes substitutions to be applied to generate the query. The following automatically resolvable tokens can be used:

$u, $U (replaced with user)—user name sent by the client component;

$d, $D (replaced with domain)—domain name sent by the client component.

Arguments are set as a table whose keys and values must be strings. The function returns an array of strings that are query results.

check(<checked string>, <query>, <parameters>) returns true if <checked string> is found in an external repository accessible via the Dr.Web LookupD module. The <query> and <parameters> arguments are equivalent to the arguments of the lookup function (see above). The <checked string> argument must be a string or a table with a __tostring metamethod (i.e. that can be transformed into a string).

2.Examples

Log a list of users retrieved from the LookupD.LDAP.users data source:

local dw = require "drweb"
local dwl = require "drweb.lookup"

-- "Main" function
function intercept(ctx)
 -- Store the string in the Dr.Web Mail Security Suite log at the notice level
 dw.notice("Intercept function started.")

 -- Store in the Dr.Web Mail Security Suite log the results of quering
 -- the 'ldap@users' data source
 for _, s in ipairs(dwl.lookup("ldap@users", {user="username"})) do
   dw.notice("Result of request to 'ldap@users': " .. s)
 end

end