In this section
•General Information
•Requirements for the Connection Processing Script
•Used Tables:
▪MessageContext,
▪ICAP,
▪User,
▪HeaderField,
▪Request,
▪ContentType,
▪Url,
▪RawUrl,
▪UrlCategoryFilter,
▪Response,
▪Body,
▪Virus,
▪ThreatFilter
•Available Service Modules:
▪drweb,
▪drweb.lookup,
▪drweb.regex,
▪drweb.config
General Information
The Dr.Web ICAPD component supports interaction via the Lua program interpreter (version 5.3.4 supplied with Dr.Web Gateway Security Suite is used). Scripts written in Lua can be used by the component for the analysis and processing of the HTTP protocol messages.
The analysis of an HTTP message (request or response) received for scanning from a proxy server via the ICAP protocol is performed by means of the Lua script specified in the Dr.Web ICAPD settings as the value of the MessageHook parameter (either script code or a path to the script file can be provided).
Requirements for the Connection Processing Script
The script must contain a global function which is an entry point to the message scanning module (Dr.Web ICAPD will call this function for processing a newly received message). The processing function must match the following call conventions:
1.Function name is message_hook.
2.The only argument is the MessageContext table (provides access from the function to the information about the processed email message).
3.The single return value is a string. The return value determines a verdict for the scanned message, i.e. to skip it or to block it. Allowed values:
•pass—the HTTP message will be passed to the recipient (the HTTP request—to the server, the HTTP response—to the client).
•block—the HTTP message will not be passed to the recipient, the client will receive an HTTP response with a blocking webpage.
A situation when the function returns a different value or an error occurs when executing the function is treated as a scanning error; the response to the client depends in this case on the value of the BlockUnchecked parameter.
Below is an example of a correct definition of the function, which will always return the pass verdict to Dr.Web ICAPD for all HTTP messages received for scanning (the ctx argument is hereinafter an instance of the MessageContext table):
function message_hook(ctx)
return "pass"
end
|
The script from the next example will block access to all resources except Doctor Web documentation website for all users except the members of the Web Admins group in Active Directory:
local dwl = require "drweb.lookup"
function message_hook(ctx)
-- Do not block access to resources at the documentation website
-- of Doctor Web
if ctx.request.url.in_list{"download.geo.drweb.com"} then
return "pass"
end
-- Allow access to users from the WebAdmins group
-- in the Active Directory section
if dwl.check("WebAdmins", "AD@WinRoot", ctx.icap.user) then
return "pass"
end
-- Block access (to all resources) for everyone else
return "block"
end
|
Tables in Use
MessageContext Table
It is used as an input argument of the message_hook function. It provides access to the information about the processed HTTP message (its type, headers, body, information about the sender and the recipients, if available).
Field
|
Description
|
Data type
|
direction
|
HTTP message type:
•request—an HTTP request.
•response—an HTTP response. |
String
|
icap
|
Information about ICAP request headers.
|
ICAP Table
|
request
|
Information about HTTP request headers.
|
Request Table
|
response
|
Information about HTTP request headers.
|
Response Table
|
body
|
Information about the HTTP message body.
|
Body Table
|
Overridden metamethods: None
|
ICAP Table
The table is used as the icap field of the MessageContext table. It contains the information about an ICAP request from an HTTP proxy server.
Field
|
Description
|
Data type
|
user
|
Information about the user obtained from the X-Client-Username header of the ICAP request.
|
User Table
|
src
|
IP address of a client who sent the request (the address is contained in the X-Client-IP header of the ICAP request from the proxy server), or nil, if the address is unknown.
|
IpAddress Table
|
field
|
Array of ICAP request headers.
|
Array of HeaderField tables
|
search
|
Function for searching a header by a regular expression. It accepts one mandatory argument—patterns—search patterns, i.e. one (string) or several (array of strings) regular expressions in the Perl syntax (PCRE). The search is performed in all available headers.

|
When using quoted strings, the slash character must be escaped.
|
Returns a Boolean value:
•true—if the field.name .. ": " .. field.value.decoded string matches at least one of the specified regular expressions for at least one of the headers;
•false—if no matches have been found. |
Function
|
value
|
Function that accepts one mandatory argument—the header name (string). It returns the value of the first header with the specified name or nil, if there is no header with this name.
|
Function
|
Overridden metamethods: None
|
User Table
The table contains the name and the domain of the user; both fields are optional.
Field
|
Description
|
Data type
|
user
|
User name
|
String
|
domain
|
User domain
|
String
|
Overridden metamethods:
•__tostring—function that returns the User content as a string (in the UTF-8 encoding);
•__concat—function that concatenates the User string value and another string. |
HeaderField Table
The table describes HTTP or ICAP messages.
Field
|
Description
|
Data type
|
name
|
Header name
|
String
|
value
|
Header value
|
String
|
Overridden metamethods: None
|
Request Table
The table describes the headers of an HTTP request.
Field
|
Description
|
Data type
|
method
|
HTTP protocol method used in the request (for example, POST) or nil, if the ICAP request does not contain the HTTP request header.
|
String
|
url
|
URL of the resource at which the HTTP request is sent.
|
Url Table
|
content_type
|
Information from the Content-Type header of the HTTP request.
|
ContentType Table
|
field
|
Array of HTTP request headers.
|
Array of HeaderField tables
|
search
|
Function for searching a header by a regular expression. It accepts one mandatory argument—patterns—search patterns, i.e. one (string) or several (array of strings) regular expressions in the Perl syntax (PCRE). The search is performed in all available headers.

|
When using quoted strings, the slash character must be escaped.
|
Returns a Boolean value:
•true—if the field.name .. ": " .. field.value.decoded string matches at least one of the specified regular expressions for at least one of the headers;
•false—if no matches have been found. |
Function
|
value
|
Function that accepts one mandatory argument—the header name (string). It returns the value of the first header with the specified name or nil, if there is no header with this name.
|
Function
|
Overridden metamethods: None
|
ContentType Table
The table describes a value obtained from the Content-Type header.
Field
|
Description
|
Data type
|
type
|
MIME type of the message part
|
String
|
subtype
|
Subtype of the message part
|
String
|
param
|
Header parameters in the form of a table array with the following fields:
•name is the name of a parameter (string);
•value is the value of a parameter (string). |
Table array
|
match
|
Function that accepts one mandatory argument—media_types, which is an array of strings describing MIME types. Each string in the list must be formatted as follows: "type/subtype", "type/*" or "*/*".
Returns a Boolean value:
•true—if the MIME type of the body matches any of the specified strings (case-insensitively), or the passed array contains the "*/*" string;
•false—if no matches have been found. |
Function
|
Overridden metamethods:
•__tostring—function that returns the decoded header value;
•__concat—function that concatenates the decrypted value of the header and a string. |
Url Table
The table describes a URL address.
Field
|
Description
|
Data type
|
scheme
|
Scheme (protocol) prefix, for example, http. If absent, the value is nil.
|
String
|
host
|
Host name or IP address, for example, example.com. If absent, the value is nil.
|
String
|
port
|
Port number, for example, 80. If absent, the value is nil.
|
Number
|
path
|
Path to a resource, for example, index.html. If absent, the value is nil.
|
String
|
query
|
Decoded request parameters. If absent, the value is nil.
|
String
|
legal_url
|
If the URL belongs to the owners_notice category, the field contains a URL of the owner’s website; otherwise, it is nil.
|
String
|
in_list
|
Function that accepts one mandatory argument—hosts, i.e. the host list (an array of strings). It returns a Boolean value:
•true—if host is a subdomain of one of the specified domains or matches one of them;
•false—if no matches have been found. |
Function
|
categories
|
Function that accepts one optional argument—filter, i.e. the UrlCategoryFilter table (no argument is equivalent of using an empty table). It returns an iterator function using which you can iterate over all categories that meet the conditions specified by filter and to which URL relates.
|
Function
|
in_categories
|
Function that accepts one mandatory argument—categories, i.e. the URL category list (an array of strings). It returns a Boolean value:
•true—if the URL belongs to at least one of the specified categories;
•false—if the URL does not belong to any of the categories.
If the categories array is empty, false is always returned. See the possible category values in the description of the category field in the UrlCategoryFilter table.
|
Function
|
raw
|
Raw undecoded URL.
|
RawUrl Table
|
Overridden metamethods:
•__tostring—function that returns the Url content as a string (in the UTF-8 encoding);
•__concat—function that concatenates the Url string value and another string. |
RawUrl Table
The table contains undecoded information about the URL.
Field
|
Description
|
Data type
|
scheme
|
Scheme (protocol) prefix, for example, http. If absent, the value is nil.
|
String
|
host
|
Host name or IP address, for example, example.com. If absent, the value is nil.
|
String
|
port
|
Port number, for example, 80. If absent, the value is nil.
|
Number
|
path
|
Path to a resource, for example, index.html. If absent, the value is nil.
|
String
|
query
|
Decoded request parameters. If absent, the value is nil.
|
String
|
Overridden metamethods:
•__tostring—function that returns the RawUrl content as a string (in the UTF-8 encoding);
•__concat—function that concatenates the RawUrl string value and another string. |
UrlCategoryFilter Table
The table describes a filter for URL categories. All table fields are optional.
Field
|
Description
|
Data type
|
category
|
List of categories that the URL must match (case-insensitive):
•infection_source—infection source;
•not_recommended—source that is not recommended for visiting;
•adult_content—adult content;
•violence—violence;
•weapons—weapons;
•gambling—gambling;
•drugs—drugs;
•obscene_language—obscene language;
•chats—chats;
•terrorism—terrorism;
•free_email—free email;
•social_networks—social networks;
•owners_notice—websites added due to a notice from a copyright owner;
•online_games—online games;
•anonymizers—anonymizers;
•cryptocurrency_mining_pools—cryptocurrency mining pools;
•jobs—job search websites;
•black_list—black list. |
String or table of strings
|
category_not
|
List of categories that the URL must not match (case-insensitive).
|
String or table of strings
|
Overridden metamethods: None
|
If the filter field is not specified (i.e., the value is nil), any threat matches the filter. If several filter fields are specified, the condition is combined by a conjunction (logical AND). If the filter field is a table (list), the object being filtered must match at least one of the table (list) items.
Response Table
The table describes the headers of an HTTP response.
Field
|
Description
|
Data type
|
status
|
HTTP response code or nil, if the ICAP request does not contain the HTTP response header.
|
Number
|
reason
|
Comment to the response code or nil if absent.
|
String
|
content_type
|
Contains information obtained from the Content-Type header of the HTTP response.
|
ContentType Table
|
field
|
Array of HTTP response headers
|
Array of HeaderField tables
|
search
|
Function for searching a header by a regular expression. It accepts one mandatory argument—patterns—search patterns, i.e. one (string) or several (array of strings) regular expressions in the Perl syntax (PCRE). The search is performed in all available headers.

|
When using quoted strings, the slash character must be escaped.
|
Returns a Boolean value:
•true—if the field.name .. ": " .. field.value.decoded string matches at least one of the specified regular expressions for at least one of the headers;
•false—if no matches have been found. |
Function
|
value
|
Function that accepts one mandatory argument—the header name (string). It returns the value of the first header with the specified name or nil, if there is no header with this name.
|
Function
|
Overridden metamethods: None
|
Body Table
A table describing the HTTP message body.
Field
|
Description
|
Data type
|
has_threat
|
Function that accepts one optional argument—filter, i.e. the ThreatFilter table (the absence of an argument is equivalent to using an empty table). It returns a Boolean value:
•true—if the HTTP message body contains a threat that meets the specified filter condition;
•false—if no matches have been found. |
Function
|
threats
|
Function that accepts one optional argument—filter, i.e. the ThreatFilter table (the absence of the argument is equivalent to using an empty table). It returns an iterator function using which you can iterate over all threats detected in the HTTP message body. The threats are described using the Virus table.
|
Function
|
content_type
|
Contains information on the MIME type of the body obtained from the Content-Type header of the HTTP request or response (depending on the type of the message being analyzed).
|
ContentType Table
|
scan_error
|
Body scanning error, if occurred, nil otherwise. Allowed values:
•path_not_absolute—the specified path is not absolute;
•file_not_found—the file has not been found;
•file_not_regular—the file is not regular;
•file_not_block_device—not a block device;
•name_too_long—the name is too long;
•no_access—access is denied;
•read_error—a reading error has occurred;
•write_error—a writing error has occurred;
•file_too_large—the file is too large;
•file_busy—the file is being used;
•unpacking_error—an unpacking error has occurred;
•password_protected—the archive is password-protected;
•arch_crc_error—an archive CRC error;
•arch_invalid_header—an invalid archive header;
•arch_no_memory—not enough memory to unpack the archive;
•arch_incomplete—the archive is incomplete;
•can_not_be_cured—the file cannot be cured;
•packer_level_limit—the packed object nesting level limit has been exceeded;
•archive_level_limit—the archive nesting level limit has been exceeded;
•mail_level_limit—the mail file nesting level limit has been exceeded;
•container_level_limit—the container nesting level limit has been exceeded;
•compression_limit—the compression rate limit has been exceeded;
•report_size_limit—the report size limit has been exceeded;
•scan_timeout—the scanning timeout limit has been exceeded;
•engine_crash—a scanning engine failure;
•engine_hangup—a scanning engine hangup;
•engine_error—a scanning engine error;
•no_license—no active license has been found;
•multiscan_too_late—a multiscanning error has occurred;
•curing_limit_reached—the limit of curing attempts has been exceeded;
•non_supported_disk—a disk type is not supported;
•unexpected_error—an unexpected error. |
String
|
Overridden metamethods: None
|
Virus Table
Table that describes a threat.
Field
|
Description
|
Data type
|
name
|
Threat name (according to the Doctor Web classification)
|
String
|
type
|
Threat type (according to the Doctor Web classification). Allowed values:
•known_virus—a known threat (i.e., a threat that is covered by virus databases);
•virus_modification—a modification of the known threat;
•unknown_virus—an unknown threat, a suspicious object;
•adware—adware;
•dialer—a dialer program;
•joke—a joke program;
•riskware—a potentially dangerous program;
•hacktool—a hacktool. |
String
|
Overridden metamethods: None
|
ThreatFilter Table
The table describes the filter for threats.
Field
|
Description
|
Data type
|
category
|
List of categories that the threat must match (case-insensitive). See the list of categories in description of the type field of the Virus table.
|
String or table of strings
|
category_not
|
List of categories that the threat cannot match (case-insensitive).
|
String or table of strings
|
Overridden metamethods: None
|
If the filter field is not specified (i.e., the value is nil), any threat matches the filter. If several filter fields are specified, the condition is combined by a conjunction (logical AND). If the filter field is a table (list), the object being filtered must match at least one of the table (list) items.
Usage Examples
1.Log the list of all threats found in the HTTP message:
local dw = require "drweb"
function message_hook(ctx)
for virus in ctx.body.threats() do
dw.notice("threat found: " .. virus.name)
end
return "pass"
end
|
2.Writing to the log the threat names that match the category filter, and the names of the message parts where the threats have been detected:
local dw = require "drweb"
function message_hook(ctx)
for v in ctx.body.threats({category = "known_virus"}) do
dw.notice("found known virus: " .. v.name)
end
return "pass"
end
|
Available Service Modules
The following custom modules listed in the table can be imported into Lua program space for interaction with Dr.Web Gateway Security Suite.
Name of the module
|
Function
|
drweb
|
Module that provides functions for writing messages from the Lua program to the log of the Dr.Web Gateway Security Suite component which has started the Lua program, as well as the means to run Lua procedures asynchronously
|
drweb.lookup
|
Module that provides tools to query data from external sources using the Dr.Web LookupD module
|
drweb.regex
|
Module that provides an interface to match strings with regular expressions
|
drweb.config
|
Module that provides a table with the Dr.Web ICAPD configuration parameter values
|
Contents of the drweb module
1.Functions
The module provides a set of functions.
•Storing messages from the Lua program in the Dr.Web Gateway Security Suite component log:
▫log(<level>, <message>) writes the <message> string to the Dr.Web Gateway 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 Gateway Security Suite log at the debug level;
▫info(<message>) writes the <message> string to the Dr.Web Gateway Security Suite log at the info level;
▫notice(<message>) writes the <message> string to the Dr.Web Gateway Security Suite log at the notice level;
▫warning(<message>) writes the <message> string to the Dr.Web Gateway Security Suite log at the warning level;
▫error(<message>) writes the <message> string to the Dr.Web Gateway 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 Gateway 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 Gateway 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 Gateway Security Suite log at the notice level
dw.notice("Intercept function started.")
-- Store in the Dr.Web Gateway 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
|
Contents of the drweb.regex Module
1. Function
The module provides the following functions:
•search(<template>, <text>[, <flags>]) returns true if the <text> string contains a substring that matches the <template> regular expression. The optional <flags> parameter (integer) is a set of flags affecting the function behavior and connected with the logical OR.
•match(<template>, <text>[, <flags>])—the same as search except that the <template> regular expression must match the entire <text> string, not only its substring.
2. Available flags
•ignore_case ignores text case.
3. Examples
local rx = require "drweb.regex"
rx.search("te.?t", "some TexT") -- false
rx.search("te.?t", "some TexT", rx.ignore_case) -- true
rx.match("some.+", "some TexT") -- true
|
Contents of the drweb.config Module
1. Functions
The module does not provide any functions.
2. Available tables
The module provides a table with the following fields:
Field
|
Description
|
Data type
|
whitelist
|
Value of the Whitelist configuration parameter.
|
String array
|
blacklist
|
Value of the Blacklist configuration parameter.
|
String array
|
adlist
|
Value of the Adlist configuration parameter.
|
String array
|
block_url_categories
|
List of blocked URL categories (based on the Block* parameter values set to Yes).
|
String array
|
block_threats
|
List of blocked threat categories (based in Block* parameter values, set to Yes).
|
String array
|
block_unchecked
|
Value of the BlockUnchecked configuration parameter.
|
Logical
|
Overridden metamethods: None
|
3. Example
local cfg = require "drweb.config"
function message_hook(ctx)
-- Block messages containing threats
-- from the list of threats to be blocked
if ctx.body.has_threat{category = cfg.block_threats} then
return "block"
end
-- Allow access to all other resources
return "pass"
end
|
|