Table of Contents

4. Mail Server Security

4.1. Authentication and Encryption

4.1.1. Kerberos Authentication within Active Directory

4.2. SPF and DomainKeys

4.2.1. AXIGEN Signing Module Usage and Configuration

4.3. Mail Filtering

4.3.1. Message Acceptance Rules

4.3.2. Routing Rules

4.3.3. Antivirus / Antispam Filters

4.3.4. Message Rules

4.3.4.1. SIEVE Overview and Implementation in AXIGEN

4.3.5. The AXIGEN Filtering Module

4.3.5.1. Filtering Module Implementation in AXIGEN

4.3.5.2. Configuring the AXIGEN Filtering Module

4.3.5.3. AXIGEN Filtering Module Commands

4.3.6. Activating and Prioritising Filters and Rules

4.3.7. Language Specifications for Policy Configuration

4.3.7.1. SMTP Functionalities (I)

4.3.7.2. SMTP Functionalities (II)

4.3.7.3. SMTP Functionalities (III)

4.3.7. Language Specifications for Policy Configuration

The AXIGEN SMTP Policy system is defined in a single file per installed AXIGEN Mail Server and has events for the SMTP Incoming, Outgoing and Processing stages of a mail life cycle.  The Policy system contains Message Acceptance Policies and Processing and Relay Policies. The file is known by the server by the means of smtpFiltersFile parameter.

Important!

Starting with version 5, changing the existent rules/methods or adding new rule/methods by directly editing the smtpFilter file is NOT recommended for normal usage. This could render unavailable in the corresponding context of SMTP filter/rules in WebAdmin and it is not advisable unless you need heavy tweaking and know what you are doing.

Instead of directly editing smtpFilters, for normal usage, the administrator should use the following context from the WebAdmin module: 'Security & Filtering' -> 'Acceptance & Routing'.

If the specific WebAdmin context is invalidated by manual modifications of the smtpFilters file, then a warning will be displayed, and the user will be presented with the opportunity of overwriting the contents of the file.

Since manual modification of smtpFilters file is not recommended anymore, a wizard that will help you build your required rules is available in WebAdmin.

ATTENTION!
If rules already exist in the smtpFilters file, using the wizard from WebAdmin will overwrite all of them, please first back-up your smtpFilters file.

Basic structure

The language is structured in blocks of two types: events and methods. The events are predefined blocks that will be executed at specific moments by the server. The methods are custom defined blocks that will be called from the language. Thus the basic structure of a language file is:

event event1 {
event event2 {
.
.
}


Comments inside the script file are allowed using the syntax: #comment until the end of line.

SMTP Events

The events defined for the SMTP filters and their contexts are as follows:

Event
Context
onConnect SMTP Incoming
onEhlo SMTP Incoming
onMailFrom SMTP Incoming
onRcptTo SMTP Incoming
onHeadersReceived SMTP Incoming
onBodyChunk SMTP Incoming
onDataReceived SMTP Incoming
onRelay SMTP Outgoing
onDeliveryFailure Processing
onTemporaryDeliveryFailure Processing

Thus, the structure of the script file is:

#Sample AXIGEN SMTP Filter
#the event called when a connection is made to SMTP
event onConnect {
.
code
.
}

#the event called when smtp receives EHLO
event onEhlo {
.
call(Ionel);
.
}

method Ionel {
.
code
}


Methods

Beside the custom methods, a number of predefined methods are also available. They are called in the same way and have a predefined behavior. The currently available predefined methods are:
  • checkSPF
  • checkReverseDNS
  • addHeader
  • addIfNotExistsHeader
  • removeFirstHeader
  • removeHeader
  • modifyHeader
  • modifyIfExistsHeader
  • addRcpt
  • discardRcpt
A more comprehensive example of a script defined until now, can be:

event onHelo {
call(heloEvent);
}

method heloEvent {
.
call(checkSpf);
call(addHeader);
}


Contexts

This language defines a scripting language to be used especially for SMTP filtering. The SMPT process has three different contexts: Incoming, Outgoing and Processing. Thus the behavior of the same filter differs depending on the context to which it is applied. For example the SMTPIn events are triggered only within the SMTP Incoming context. The same applies to context dependent variables which will be detailed below.

Variables

After methods and events, the next as level of importance are the variables. They act as input and output to functions and also act as actions to be taken by the SMTP engine. All variables are considered to be string or numbers and can be of three types:
  • read-only variables (input variables);
  • read-write variables (input/output variables);
  • action variables - these variables can be either read-only or read-write but they are in this category because they can cause the SMTP engine to take an action or are involved in an action.

Variable behavior is context-dependent. If a variable is an input variable for the SMTP Incoming context it will be set only in that context and will be "" in the SMTP Outgoing context. Furthermore, a variable will be set only after that variable's value is known. For example, the MailFromDomain variable will be "" in the onConnect and onEhlo events and will be set only in onMailFrom event.


Some variables are set/read by the engine but there are methods for reading/writing them from the code. The reading of a variable implies the comparing of the variable's value with another value or variable. This is done using test functions that form the test block of a conditional block.

To set a variable, the function set is used:

set(SPFResult, "some value");

When a predefined method is called, it usually sets one or more variables as its output and usually requires setting one or more variable as its input. Apart from the predefined variables, custom variables also exist and they can be used later in the code. To define a variable you just set its value:

set(aVariable, "aValue").

The previous function defines a variable named aVariable and sets its value to "aValue".

A custom defined variable has lifetime that lasts until the end of a block. To preserve a variable across blocks and across contexts, the export function is used:

export(aVariable)

The lifetime of a filter with its contexts is per email message so the export function can be used to preserve the value of a variable specific to one email message through different stages of SMTP. For example, at the SMTP Outgoing context, the value of MailFromDomain is not set but can be, if in one of the SMTP Incoming events, an export(MailFromDomain) was made.

Within the SMTP Filter Language, the concept of variable expanding means that, within a string, a variable name may appear and at runtime the name will be replaced by the variable's value. In order for a variable to be expanded, its name must appear between "%" characters. An example of variable expanding is:

event onConnect {
set(aVariable, "Hello.");
set(SMTPGreeting, "%aVariable% This is my AXIGEN server");
}


When you connect on the SMTP port, the greeting will be: "Hello. This is my AXIGEN server"

This expanding mechanism also works for comparing two variables:

event onConnect {
set(aVariable, "value");
set(bVariable, "value");
if (is(aVariable,"%bVariable%) {
set(SMTPAction,"reject");
}
}


Structures

Condition blocks
There are only block, sub-block, if and switch structures. The block structures were defined above. The ‘if’ structure has the following form:

if (conditions) {
}
else {
}

The sub-blocks mentioned above are part of the ‘if’ and ‘switch’ structure and as in the case of blocks, start with a "{" and end with a "}".

The switch structure has the following form:

switch (variable) {
case <value>: {
}
case <value>: {
}
default: {
}
}

Both the ‘if’ and the ‘switch’ structures can imbricate a maximum of 16 levels of imbrication. The case statements are exclusive, that means that if a case is matched, after the execution of the block, the switch structure is exited.

Conditions

The conditions are Boolean functions that are used in the ‘if’ and ‘switch’ tests. They split into 2 types: single conditions and logical groups.

The single conditions are as follows:

  • is(variable,value) - matches for equality;
  • isCase(variable,value) - matches for equality and if strings, the match is case insensitive;
  • match(variable,regexp) - regular expression match
  • lessThen(variable,value) - number comparison
  • greaterThen(variable,value) - number comparison
  • greaterOrEqual(variable, value) - number comparison
  • lessOrEqual(variable, value) - number comparison
  • iprange(variable, range) - matches if the variable's value is in range. If the variable is not an ipAddress, the function returns false. Emample of how to define IP ranges:
    • 192.168.1.1-192.168.1.10 (range)
    • 192.168.1.1/24 (cidr)
    • 192.168.1.1/255.255.255.0 (netmask)

The logical groups are:
  • not(condition) - negation of a condition
  • allof(condition,condition,...) - similar to an AND between conditions
  • anyof(condition,condition,...) - similar to an OR between conditions
The logical groups allow a maximum of 16 levels of imbrication.

Functions

The functions can be looked at as keywords from other languages. They are the building blocks of the language and their behavior is hard-coded. The functions available are:
  • all the Boolean functions described above;
  • call (method) - this executes a predefined of custom defined method. If the method is custom defined, it must be defined in the same script file as the call;
  • export (variable) - this function exports a variable name and value to be used in another context. If the variable is custom defined it must be defined in the same script file;
  • set (variable, value) - this sets the value of a RW variable;
  • return - this function ends the current event or method execution.

See subsections of current page for more details:

SMTP Functionalities (I)
SMTP Functionalities (II)
SMTP Functionalities (III)