13 Mail Filtering and Access Control

This information discusses how to filter mail based on its source (sender, IP address and so on) or header strings. Two mail filtering mechanisms are used, controlling access to the MTA by using mapping tables and Sieve server-side rules (SSR).

Limiting access to the MTA by using the mapping tables enables messages to be filtered based on From: and To: addresses, IP address, port numbers, and source or destination channels. Mapping tables permit SMTP relaying to be enabled or disabled. Sieve is a mail filtering script that enables messages to be filtered based on strings found in headers.

If envelope-level controls are desired, use mapping tables to filter mail. If header-based controls are desired, use Sieve server-side rules.

Topics:

"PART 1. MAPPING TABLES." Enables the administrator to control access to MTA services by configuring certain mapping tables. The administrator can control who can or cannot send mail, receive mail through Oracle Communications Messaging Server.

"PART 2. MAILBOX FILTERS." Enables users and administrators to filter messages and specify actions on those filtered messages based on a string found in the message header. Uses the Sieve filter language and can filter at the channel, MTA or user level.

Controlling Access with Mapping Tables

You can control access to your mail services by configuring certain mapping tables. These mapping tables allow you to control who can or cannot send mail, receive mail, or both. Table 13-1, "Access Control Mapping Tables" lists the mapping tables described in this section. The application information string supplied to the FROM_ACCESS, MAIL_ACCESS, and ORIG_MAIL_ACCESS mappings includes the system name claimed in the HELO/EHLO SMTP command. This name appears at the end of the string and is separated from the rest of the string (normally "SMTP*") by a slash. The claimed system name can be useful in blocking some worms and viruses.

Access Control Mapping Tables - Operation

Access control mapping tables follow the same general format and operations as all mappings tables. (See the Messaging Server Reference for more details about the format and operation, and patterns, templates, and metacharacters which apply to all mapping tables.) They consist of a mapping table name, followed by a blank line, followed by one or more mapping entries. Mapping entries consist of a search pattern on the left side and a template on the right side. The search pattern filters specific messages and the template specifies actions to take on the message. For example:

SEND_ACCESS

 *|Elvis1@example.org|*|*      $Y
 *|Nelson7@example.org|*|*     $Y
 *|AkiraK@example.org|*|*      $Y
 *|*@example.org|*|*           $NMail$ Blocked

In this example all email from the domain example.org except those of Elvis1, Nelson, AkiraK are blocked.

The search pattern for access control mapping entries consist of a number of search criteria separated by vertical bars (|). The order of the search criteria depends on the access mapping table and is described in subsequent sections. But as an example, the SEND_ACCESS mapping table has the following search form:

src-channel|from-address|dst-channel|to-address

where src-channel is the channel queueing the message; from-address is the address of the message's originator; dst-channel is the channel to which the message will be queued; and to-address is the address to which the message is addressed. Use of an asterisk in any of these four fields causes that field to match any channel or address, as appropriate.

The from-address is a positional content string placeholder. In some circumstances, you can modify the default type of information, for example, by using the use_auth_return MTA option. An option might affect only substrings in certain mappings and might be subject to precedence rules of options affecting the same mapping table substring. For more information, see "Controlling the Envelope From: Address in Mappings Strings and Mailing List Named Options and LDAP Attributes."

Note:

Whenever a mappings table is modified, you must recompile the configuration. See "Compiling the MTA Configuration."

Table 13-1 describes the different mapping tables.

Table 13-1 Access Control Mapping Tables

Mapping Table Description

SEND_ACCESS (See SEND_ACCESS and ORIG_SEND_ACCESS Mapping Tables)

Used to block incoming connections based on envelope From address, envelope To address, source and destination channels. The To address is checked after rewriting, alias expansion, and so on, have been performed.

ORIG_SEND_ACCESS (See SEND_ACCESS and ORIG_SEND_ACCESS Mapping Tables)

Used to block incoming connections based on envelope From address, envelope To address, source and destination channels. The original To address after rewriting but before alias expansion is used, but the function of alias expansion has already been performed.

MAIL_ACCESS (See MAIL_ACCESS and ORIG_MAIL_ACCESS Mapping Tables)

Used to block incoming connections based on combined information found in SEND_ACCESS and PORT_ACCESS tables: that is, the channel and address information found in SEND_ACCESS combined with the IP address and port number information found in PORT_ACCESS.

ORIG_MAIL_ACCESS (See MAIL_ACCESS and ORIG_MAIL_ACCESS Mapping Tables)

Used to block incoming connections based on combined information found in ORIG_SEND_ACCESS and PORT_ACCESS tables: that is, the channel and address information found in ORIG_SEND_ACCESS combined with the IP address and port number information found in PORT_ACCESS.

FROM_ACCESS Mapping Table

Used to filter mail based on envelope From addresses. Use this table if the To address is irrelevant.

PORT_ACCESS Mapping Table

Used to block incoming connections based on IP address and TCP port.

IP_ACCESS Mapping Table.

Used to control outgoing connections based on IP address information.


The MAIL_ACCESS and ORIG_MAIL_ACCESS mappings are the most general, having available not only the address and channel information available to SEND_ACCESS and ORIG_SEND_ACCESS, but also any information that would be available via the PORT_ACCESS mapping table, including IP address and port number information.

Access Control Mapping Table Flags

This section consists of the following subsections:

See the Messaging Server Reference for more details about the format and operation, and patterns, templates, and metacharacters which apply to all mapping tables.

Input vs Output Flags

Mapping table templates can test input flags and can set output flags. Input and output flags should be thought of as being stored in separate namespaces. For example, the $A input flag may have nothing to do with a $A output flag. "$A" is a short hand way of saying "the A flag" (as opposed to the string "A"). There are input flags set by the MTA when it does a probe - so there is the probe string, plus any probe input flags. Then there is the output string plus output flags that were set on the right hand side of the mapping entry.

So $A could be set by the MTA as an input flag, then testable (on the right hand side of an entry) via $:A or $;A. Then the right hand side of an entry may set its own output flags (that is, $A) which as output means something entirely different - and which do not count as input flags for testing purposes (regardless of whether the mapping "iterates" - say with $C). That is, the flag tests such as $:flag-char are always on the original (set by the MTA, or via -flags input setting in imsimta test -mapping) input flags, not on any flags that may have been set in the right-hand-side of the mapping.

For example, try using imsimta test -mapping, especially with its -flags switch to set some input flags. Try using some arbitrary, private mapping table. Use a few $:flag or$;flag tests on your right hand side. Also notice that the output lists (separately):

Output string: ...
Output flags: [...]

where the output flags (the stuff inside the []'s) correspond to the output flags set. That is, with a mapping:

X-FLAGS

   *              $C$:AA$ set$Y
   *              $;AA$ not$ set$Y

try something like:

# imsimta test -mapping -flags=A -table=x-flags

and note how it yields

Output string: A set
Output flags: [0, 'Y' (89)]

meaning that it output the string "A set", matched on the 0th iteration (as opposed to iterative or recursive mappings where you'll see the number go up) and output the Y flag (or $Y if you want to write it that way) but the A flag that was an input flag is not an output flag. 'Y' is character position 89 in ASCII - the character position is shown for extra clarity.

In contrast,

# imsimta test -mapping -flags=B -table=x-flags

yields

Output string: A not set
Output flags: [0, 'Y' (89)]

Output Flag Argument Order

Flags with arguments must have those arguments arranged in the reading order shown in the table. For example:

ORIG_SEND_ACCESS

  tcp_local|*|tcp_local|*     $N$D30|Relaying$ not$ allowed

In this case, the proper order is the delay period followed by the rejection string. Note that the flags themselves can be in any order. So the following entries have identical results:

30|Relaying$ not$ allowed$D$N
$N30|Relaying$ not$ allowed$D
30|$N$DRelaying$ not$ allowed

For the details of the flags and metacharacters supported in each table, see:

Send Access and Mail Access Mapping Tables

The following flags and metacharacters apply to the SEND_ACCESS, ORIG_SEND_ACCESS, MAIL_ACCESS, and ORIG_MAIL_ACCESS mapping tables. The FROM_ACCESS and PORT_ACCESS mapping tables have different sets of flags - see the "FROM_ACCESS Mapping Table" and "PORT_ACCESS Mapping Table" sections.

Input flags are set by the process that calls the mapping table and tested for by using the $: and $; metacharacters in the template. The $: will succeed if the flag is set or fail if it is not set. The $; will succeed if the flag is not set or fail if it is set. Table 13-2 shows the $:x form to test if the flag is set. The $;x form can also be used to test if condition is not true. Table 13-2 describes the send and mail access input flags.

Table 13-2 Send and Mail Access Input Flags

Flag Description

$:|

Match only if external material (that is, an envelope address) in the probe contained a vertical bar.

$:A

Match only if SASL (SMTP AUTH) has been used.

$:D

Match only if DELAY delivery receipts have been requested (that is, NOTIFY=DELAY).

$:E

Match only if ESMTP has been used.

$:F

Match only if FAILURE delivery receipts have been requested (that is, NOTIFY=FAILURE).

$:L

Match only if LMTP has been used.

$:P

Match only if POP-before-SMTP was used.

$:S

Match only if SUCCESS delivery receipts have been requested (that is, NOTIFY=SUCCESS).

$:T

Match only if TLS has been used.

$:V

Match only if recipient address expanded via an alias.


Output flags are set by the template in the mapping table entry and consumed upon return to the calling program. Table 13-3 describes the send and mail access output flags.

Table 13-3 Send and Mail Access Output Flags

Flag Description

$.

Establishes a string which will be processed as the mapping entry result in the event of a temporary LDAP lookup failure. By default a temporary failure string remains set only for the duration of the current rule. "$.." can be used to return to the default state where no temporary failure string is set and temporary LDAP failures cause mapping entry or rewrite rule failure. Note that all errors other than failure to match an entry in the directory are considered to be temporary errors; in general it isn't possible to distinguish between errors caused by incorrect LDAP URLs and errors caused by directory server configuration problems.

$*

If used with $N, force disconnect of the SMTP session.

$B

Redirect the message to the bitbucket; the effect is per-recipient in the Send/Mail Access mapping tables, vs entire message in the "FROM_ACCESS Mapping Table."

$H

Hold the message as a .HELD file; the effect is per-recipient in the Send/Mail Access mapping tables, vs entire message in the "FROM_ACCESS Mapping Table."

$J

Used with $M (see below) to cause generation of envelope "journal" format rather than the default DSN encapsulated format for the "capture" message copy (added in 7u3p16)

$O

Forces single-copy-per-recipient message copy "split up." For more information see the discussion on addresses per message copy in the Messaging Server Reference.

$P

Force to enqueue to the reprocess channel. (For instance, this might be useful as part of $. text. handling when attempting an LDAP lookup that encountered an LDAP directory temporary problem; that is, in case of an LDAP lookup problem, defer to the reprocess channel.)

$V

Force Sieve filter discard behavior for all recipients of this message copy.

$v

Force Sieve filter discard behavior for solely this recipient.

$Y

Allow access.

$Z

Force Sieve filter jettison behavior (non-overridable discard) for all recipients of this message copy.

$z

Force Sieve filter jettison behavior (non-overridable discard) for solely this recipient.


Table 13-4 describes send and mail access flags with arguments. For more information see "Output Flag Argument Order." Note: Do NOT alphabetize this list.

Table 13-4 Send and Mail Access Flags with Arguments

Flag Description

$Uinteger

Enable channel (slave) debugging; if the optional n argument is specified, it also sets the specified value for enqueue debugging (see MM_DEBUG option). See the discussion on debugging channel master and slave programs in the Messaging Server Reference.

$Iuser|identifier

Check specified user for specified groupid (UNIX) and if not in the group, reject access (effectively sets the $N output flag).

$<string

+++ Send string to UNIX syslog (user.notice facility and severity) if probe matches. (see SNDOPR_PRIORITY option)

$>string

+++ Send string to UNIX syslog (user.notice facility and severity) if access is rejected. (see SNDOPR_PRIORITY option)

$Ddelay

Delay response for an interval of delay hundredths of seconds; a positive value causes the delay to be imposed on each command in the transaction; a negative value causes the delay to be imposed only on the address handover (SMTP MAIL FROM: command for the FROM_ACCESS table; SMTP RCPT TO: command for the other tables).

$Ttag

Prefix subsequent *ACCESS mapping table probes with tag _tag

$Aheader

Add the header line header to the message.

$Gconversion_tag

If used in ORIG_SEND_ACCESS, SEND_ACCESS, ORIG_MAIL_ACCESS, and MAIL_ACCESS, it reads a value from the mapping result and treats it as a set of conversion tags to be applied to the current recipient. If used with FROM_ACCESS, conversion tags are applied to all recipients. $G is positioned after $A (header address) in the sequence of arguments read from the mappings. See "Mail Conversion Tags."

$Maddress

Capture a copy of the message, sending the captured copy to address. By default, this captured copy is DSN encapsulated---but see the no-argument, non-FROM_ACCESS $J output flag above.

$,spamadjust_arg

Set a spam level value x (between -10000.0 and 10000.0). If the message already had a spam level, this is a spamadjust effect (adds or subtracts the specified amount x from the prior spam level). Note that such a spam level/spamadjust effect applies to all recipients (even for the recipient-specific mapping tables such as SEND_ACCESS) in order for tests to see if one of the recipients is a "honeypot" address. Allows you to perform a sieve spamadjust operation from the access mapping tables. Argument takes the same form as a spamadjust argument. Note also that some of these mappings are applied on a per-recipient basis. Any spamadjust operation that is done applies to all recipients.

$+Ename|value

Set the environment variable name to value.

$Xerror-code

Lets you specify the extended SMTP error-code (the digit.digit.digit part), and if the first digit is a 4 rather than a 5, then you'll get a 452 SMTP temporary error, rather than the usual 550 SMTP permanent error. For example:

ORIG_SEND_ACCESS

<...probe...> $N$X4.5.9|Temporary$ problem$ with$ address;$ try$ later$

$Nstring

$Fstring

Reject access with the optional error text string.$F and $N are synonyms.

$Surl

Apply the Sieve filter obtained from resolving url.

$+Rn|string

Opt in to spam filtering. Only applied if neither $N nor $F is set. n is which spam/virus filter package; string is the optin string to pass to that spam filter.


{+} To use multiple flags with arguments, separate the arguments with the vertical bar character, |, placing the arguments in the order listed in this table. For more information see "Output Flag Argument Order."

+++ It is a good idea to use the $D flag when dealing with problem senders, to prevent a denial of service attack. In particular, it is a good idea to use $D in any $> entry or < entry rejecting access.

SEND_ACCESS and ORIG_SEND_ACCESS Mapping Tables

You can use the SEND_ACCESS and ORIG_SEND_ACCESS mapping tables to control who can or cannot send mail, receive mail, or both. The access checks have available a message's envelope From: address and envelope To: addresses, and knowledge of what channel the message came in, and what channel it would attempt to go out.

If a SEND_ACCESS or ORIG_SEND_ACCESS mapping table exists, then for each recipient of every message passing through the MTA, the MTA will scan the table with a string of the following form (note the use of the vertical bar character, |):

src-channel|from-address|dst-channel|to-address

The src-channel is the channel queueing the message; from-address is the address of the message's originator; dst-channel is the channel to which the message will be queued; and to-address is the address to which the message is addressed. Use of an asterisk in any of these four fields causes that field to match any channel or address, as appropriate.

The addresses here are envelope addresses; that is, envelope From: address and envelope To: address. In the case of SEND_ACCESS, the envelope To: address is checked after rewriting, alias expansion, etc., have been performed; in the case of ORIG_SEND_ACCESS the originally specified envelope To: address is checked after rewriting, but before alias expansion. Note however that the function of alias expansion has already been performed at this point, the ORIG_* variant simply uses a copy of the address from before expansion.

If the search string matches a pattern (that is, the left-hand side of an entry in the table), then the resulting output of the mapping is checked. If the output contains the flags $Y or $y, then the enqueue for that particular To: address is permitted. If the output contains any of the flags $N, $n, $F, or $f, then the enqueue to that particular address is rejected. In the case of a rejection, optional rejection text may be supplied in the mapping output. This string will be included in the rejection error the MTA issues. If no string is output (other than the $N, $n, $F, or $f flag), then default rejection text will be used. For descriptions of additional flags, see "Access Control Mapping Table Flags."

See "Send Access and Mail Access Mapping Tables" for the complete list of flags which apply to the SEND_ACCESS and ORIG_SEND_ACCESS mapping tables.

Setting the MTA option ACCESS_ORCPT to 1 adds an additional vertical bar delimited field to the probe value passed to the SEND_ACCESS, ORIG_SEND_ACCESS, MAIL_ACCESS, and ORIG_MAIL_ACCESS mapping tables that contains the original recipient (ORCPT) address. If the message doesn't have an ORCPT address, the original unmodified RCPT TO: address is used instead. The default is 0, and the probe value is at the end:

src-channel|from-address|dst-channel|to-address|ORCPT_address

In the following example, mail sent from UNIX user agents such as mail, Pine, and so on, originates from the local, l, channel and messages to the Internet go out a TCP/IP channel of some sort. Suppose that local users, with the exception of the postmaster, are not allowed to send mail to the Internet but can receive mail from there. Then the SEND_ACCESS mapping table shown in the example below is one possible way to enforce this restriction. In the mapping table, the local host name is assumed to be example.org. In the channel name "tcp_*," a wild card is used so as to match any possible TCP/IP channel name (for example, tcp_local).

Example - SEND_ACCESS Mapping Table

SEND_ACCESS

   *|postmaster@example.org|*|*    $Y
   *|*|*|postmaster@example.org    $Y
   l|*@example.org|tcp_*|*         $NInternet$ postings$ are$ not$ permitted

In the rejection message, dollar signs are used to quote spaces in the message. Without those dollar signs, the rejection would be ended prematurely and only read "Internet" instead of "Internet postings are not permitted." Note that this example ignores other possible sources of "local" postings such as from PC-based mail systems or from POP or IMAP clients.

Note:

The client attempting to send the message determines whether the MTA rejection error text is actually presented to the user who attempted to send the message. If SEND_ACCESS is used to reject an incoming SMTP message, the MTA merely issues an SMTP rejection code including the optional rejection text; it is up to the sending SMTP client to use that information to construct a bounce message to send back to the original sender.

MAIL_ACCESS and ORIG_MAIL_ACCESS Mapping Tables

The MAIL_ACCESS mapping table is a superset of the SEND_ACCESS and PORT_ACCESS mapping tables. It combines both the channel and address information of SEND_ACCESS with the IP address and port number information of PORT_ACCESS. Similarly, the ORIG_MAIL_ACCESS mapping table is a superset of the ORIG_SEND_ACCESS and PORT_ACCESS mapping tables. The format for the probe string for MAIL_ACCESS is:

port-access-probe-info|app-info|submit-type|send_access-probe-info

Similarly, the format for the probe string for ORIG_MAIL_ACCESS is:

port-access-probe-info|app-info|submit-type|orig_send_access-probe-info

Here port-access-probe-info consists of all the information usually included in a PORT_ACCESS mapping table probe in the case of incoming SMTP messages; otherwise, it is blank. app-info includes the system name claimed in the HELO/EHLO SMTP command. This name appears at the end of the string and is separated from the rest of the string (normally "SMTP*") by a slash. The claimed system name can be useful in blocking some worms and viruses. submit-type may be one of MAIL, SEND, SAML, or SOML, corresponding to how the message was submitted into Messaging Server. Normally the value is MAIL, meaning it was submitted as a message; SEND, SAML, or SOML can occur in the case of broadcast requests (or combined broadcast/message requests) submitted to the SMTP server. And for the MAIL_ACCESS mapping, send-access-probe-info consists of all the information usually included in a SEND_ACCESS mapping table probe. Similarly for the ORIG_MAIL_ACCESS mapping, orig-send-access-probe-info consists of all the information usually included in an ORIG_SEND_ACCESS mapping table probe.

See "Send Access and Mail Access Mapping Tables" for the list of flags which apply to the MAIL_ACCESS and ORIG_MAIL_ACCESS mapping tables.

See the Messaging Server Reference for more details about the format and operation, and patterns, templates, and metacharacters which apply to all mapping tables.

Setting the MTA option ACCESS_ORCPT to 1 adds an additional vertical bar delimited field to the probe value passed to the SEND_ACCESS, ORIG_SEND_ACCESS, MAIL_ACCESS, and ORIG_MAIL_ACCESS mapping tables that contains the original recipient (ORCPT) address. If the message doesn't have an ORCPT address, the original unmodified RCPT TO: address is used instead. The default is 0, and the probe value is at the end. Example:

port-access-probe-info|app-info|submit-type|send_access-probe-info|ORCPT_address

Having the incoming TCP/IP connection information available in the same mapping table as the channel and address information makes it more convenient to impose certain sorts of controls, such as enforcing what envelope From: addresses are allowed to appear in messages from particular IP addresses. This can be desirable to limit cases of email forgery, or to encourage users to configure their POP and IMAP clients' From: address appropriately. For example, a site that wishes to allow the envelope From: address vip@example.com to appear only on messages coming from the IP address 1.2.3.1 and 1.2.3.2, and to ensure that the envelope From: addresses on messages from any systems in the 1.2.0.0 subnet are from example.com, might use a MAIL_ACCESS mapping table as shown in the following example.

Example - MAIL_ACCESS Mapping Table

MAIL_ACCESS

! Entries for vip's two systems
!
  TCP|*|25|1.2.3.1|*|SMTP*|MAIL|tcp_*|vip@example.com|*|*  $Y
  TCP|*|25|1.2.3.2|*|SMTP*|MAIL|tcp_*|vip@example.com|*|*  $Y
!
! Disallow attempts to use vip's From: address from other
! systems
!
  TCP|*|25|*|*|SMTP*|MAIL|tcp_*|vip@example.com|*|*  \
      $N500$ Not$ authorized$ to$ use$ this$ From:$ address
!
! Allow sending from within our subnet with example.com From:
! addresses
!
  TCP|*|25|1.2.*.*|*|SMTP*|MAIL|tcp_*|*@example.com|*|*  $Y
!
! Allow notifications through
!
  TCP|*|25|1.2.*.*|*|SMTP*|MAIL|tcp_*||*|*  $Y
!
! Block sending from within our subnet with non-example.com
! addresses
!
  TCP|*|25|1.2.*.*|*|SMTP*|MAIL|tcp_*|*|*|*  \
     $NOnly$ example.com$ From:$ addresses$ authorized

FROM_ACCESS Mapping Table

The following flags and metacharacters apply to the FROM_ACCESS mapping table. The SEND_ACCESS, ORIG_SEND_ACCESS, MAIL_ACCESS, and ORIG_MAIL_ACCESS mapping tables have a similar set of flags but there are significant differences. See "Send Access and Mail Access Mapping Tables" for more information. The "PORT_ACCESS Mapping Table" has a different set of flags.

See the Messaging Server Reference for more details about the format and operation, and patterns, templates, and metacharacters which apply to all mapping tables.

Input flags are set by the process that calls the mapping table and tested for by using the $: and $; metacharacters in the template. The $: will succeed if the flag is set or fail if it is not set. The $; will succeed if the flag is not set or fail if it is set. Table 13-5 shows the $:x form to test if the flag is set. The $;x form can also be used to test if condition is not true.

Table 13-5 FROM_ACCESS Input Flags

Flag Description

$:|

Match only if external material (that is, an envelope address) in the probe contained a vertical bar.

$:A

Match only if SASL (SMTP AUTH) has been used.

$:E

Match only if ESMTP has been used.

$:L

Match only if LMTP has been used.

$:P

Match only if POP-before-SMTP was used.

$:T

Match only if TLS has been used.


Output flags are set by the template in the mapping table entry and consumed upon return to the calling program. Table 13-6 shows the FROM_ACCESS output flags.

Table 13-6 FROM_ACCESS Output Flags

Flag Description

$.

Establishes a string which will be processed as the mapping entry result in the event of a temporary LDAP lookup failure. By default a temporary failure string remains set only for the duration of the current rule. "$.." can be used to return to the default state where no temporary failure string is set and temporary LDAP failures cause mapping entry or rewrite rule failure. Note that all errors other than failure to match an entry in the directory are considered to be temporary errors; in general it isn't possible to distinguish between errors caused by incorrect LDAP URLs and errors caused by directory server configuration problems.

$/

Set the "fast disconnect" flag for sessions that have not yet succeeded in starting a transaction; for such sessions, any subsequent disconnect is done with SO_LINGER enabled and a timeout of 0, which may clear slots quicker on intermediate firewalls and proxies.

$!

Disable (Sieve requested) vacation messages regarding this message.

$*

If used with $N, force disconnect of the SMTP session.

$B

Redirect the message to the bitbucket; effects the entire message (all recipients) when used in FROM_ACCESS, vs. per-recipient in Table 13-3, "Send and Mail Access Output Flags".

$H

Hold the message as a .HELD file; effects the entire message (all recipients) when used in FROM_ACCESS, vs. per-recipient in Table 13-3, "Send and Mail Access Output Flags".

$O

Forces single-copy-per-recipient message copy "split up," as if the single channel option were set on the relevant destination channel(s). For more information see the discussion on addresses per message copy in the Messaging Server Reference.

$P

Force to enqueue to the reprocess channel. (For instance, this might be useful as part of $. text. handling when attempting an LDAP lookup that encountered an LDAP directory temporary problem; that is, in case of an LDAP lookup problem, defer to the reprocess channel.)

$V

Force Sieve filter discard behavior for all recipients of this message copy.

$Y

Allow access.

$Z

Force Sieve filter jettison behavior (non-overridable discard) for all recipients of this message copy.

$z

Force Sieve filter jettison - synonymous with $Z. Also see per-recipient behavior in Table 13-3, "Send and Mail Access Output Flags".


Table 13-7 describes FROM_ACCESS flags with arguments. For more information see "Output Flag Argument Order." Note: Do NOT alphabetize this list.

Table 13-7 FROM_ACCES Flags with Arguments

Flag Description

$Uinteger

Enable channel (slave) debugging; if the optional n argument is specified, it also sets the specified value for enqueue debugging (see MM_DEBUG option). See the discussion on debugging channel master and slave programs in the Messaging Server Reference for more information.

$~channel-name

Change source channel to _channel-name_. This may be of especial interest for the case of incoming notification messages (incoming messages with empty envelope From); note that when this feature is used and it actually changes the source channel, then the FROM_ACCESS check process is restarted; also, $~ can only be applied once.

$Jaddress

Replace original envelope From: address with specified address.

$Kaddress

Replace the MTA's internal sender address with specified address for subsequent checking.

Note: to also add a Sender: header, the source channel must include the authrewrite channel option.

$Iuser|identifier

Check specified user for specified groupid (UNIX) and if not in the group, reject access (effectively sets the $N output flag).

$<string

+++ Send string to UNIX syslog (user.notice facility and severity) if probe matches. (see SNDOPR_PRIORITY option).

$>string

+++ Send string to UNIX syslog (user.notice facility and severity) if access is rejected. (see SNDOPR_PRIORITY option).

$Ddelay

Delay response for an interval of delay hundredths of seconds; a positive value causes the delay to be imposed on each command in the transaction; a negative value causes the delay to be imposed only on the address handover (SMTP MAIL FROM: command for the FROM_ACCESS table; SMTP RCPT TO: command for the other tables).

$Ttag

Prefix subsequent *_ACCESS mapping table probes with tag tag

$Aheader

Add the header line header to the message.

$Gconversion_tag

If used in ORIG_SEND_ACCESS, SEND_ACCESS, ORIG_MAIL_ACCESS, and MAIL_ACCESS, it reads a value from the mapping result and treats it as a set of conversion tags to be applied to the current recipient. If used with FROM_ACCESS, conversion tags are applied to all recipients. $G is positioned after $A (header address) in the sequence of arguments read from the mappings. See "Mail Conversion Tags."

$Maddress

Capture a copy of the message, sending the captured copy to address. By default, this captured copy is DSN encapsulated---but see the no-argument, non-FROM_ACCESS $J flag above.

$Sx,y,z

Set a blocklimit, and optionally recipientlimit, and optionally recipientcutoff for the transaction. These values override any global MTA option or source-based such limits that may already be effect (but destination-based limits will still be applied, later). See the discussion on message size limits in the Messaging Server Reference.

$,spamadjust_arg

Set a spam level value x (between -10000.0 and 10000.0). If the message already had a spam level, this is a spamadjust effect (adds or subtracts the specified amount x from the prior spam level). Note that such a spam level/spamadjust effect applies to all recipients (even for the recipient-specific mapping tables such as SEND_ACCESS) in order for tests to see if one of the recipients is a "honeypot" address. Allows you to perform a sieve spamadjust operation from the access mapping tables. Argument takes the same form as a spamadjust argument. Note also that some of these mappings are applied on a per-recipient basis. Any spamadjust operation that is done applies to all recipients.

$(postmaster-address

Set an override postmaster address.

$)postmaster-address

Set an override postmaster address if none was previously set.

$+Ename|value

Set the environment variable name to value.

$+Rn|string

Opt in to spam filtering. n specifies which spam/virus filter package; string is the optin string to pass to that spam filter.

$Xerror-code

Lets you specify the extended SMTP error-code (the digit.digit.digit part), and if the first digit is a 4 rather than a 5, then you'll get a 452 SMTP temporary error, rather than the usual 550 SMTP permanent error. For example:

ORIG_SEND_ACCESS

<...probe...> $N$X4.5.9|Temporary$ problem$ with$ address;$ try$ later$

$Nstring

$Fstring

Reject access with the optional error text string.

$F and $N are synonyms.


{+} To use multiple flags with arguments, separate the arguments with the vertical bar character, |, placing the arguments in the order listed in this table. For more information see "Output Flag Argument Order."

+++ It is a good idea to use the $D flag when dealing with problem senders, to prevent a denial of service attack. In particular, it is a good idea to use $D in any $> entry or < entry rejecting access.

FROM_ACCESS Description

The FROM_ACCESS mapping table may be used to control who can send mail, or to override purported From: addresses with authenticated addresses, or both.

The input probe string to the FROM_ACCESS mapping table is similar to that for a MAIL_ACCESS mapping table, minus the destination channel and address, and with the addition of authenticated sender information, if available. Thus, if a FROM_ACCESS mapping table exists, then for each attempted message submission, Messaging Server will search the table with a string of the form (note the use of the vertical bar character, |):

port-access-probe-info|app-info|submit-type|src-channel|from-address|auth-from

Here port-access-probe-info consists of all the information usually included in a PORT_ACCESS mapping table probe in the case of incoming SMTP messages; otherwise, it is blank. app-info includes the system name claimed in the HELO/EHLO SMTP command. This name appears at the end of the string and is separated from the rest of the string (normally "SMTP*") by a slash. The claimed system name can be useful in blocking some worms and viruses. submit-type may be one of MAIL, SEND, SAML, or SOML, corresponding to how the message was submitted into the MTA. Normally the value is MAIL, meaning it was submitted as a message; SEND, SAML, or SOML can occur in the case of broadcast requests (or combined broadcast/message requests) submitted to the SMTP server. src-channel is the channel originating the message (that is, queuing the message); from-address is the address of the message's purported originator; and auth-from is the authenticated originator address, if such information is available, or blank if no authenticated information is available.

If the probe string matches a pattern (that is, the left-hand side of an entry in the table), the resulting output of the mapping is checked. If the output contains the flags $Y or $y, then the enqueue for that particular To: address is permitted. If the output contains any of the flags $N, $n, $F, or $f, then the enqueue to that particular address is rejected. In the case of a rejection, optional rejection text may be supplied in the mapping output. This string will be included in the rejection error Messaging Server issues. If no string is output (other than the $N, $n, $F, or $f flag), then default rejection text will be used. For descriptions of additional flags, see "Access Control Mapping Table Flags."

Besides determining whether to allow a message to be submitted based on the originator, FROM_ACCESS can also be used to alter the envelope From: address via the $J flag, or to modify the effect of the authrewrite channel option (adding a Sender: header address on an accepted message) via the $K flag. For instance, this mapping table can be used to cause the original envelope From: address to simply be replaced by the authenticated address.

Example - FROM_ACCESS Mapping Table

FROM_ACCESS

  *|SMTP*|*|tcp_auth|*|       $Y
  *|SMTP*|*|tcp_auth|*|*      $Y$J$4

When using the FROM_ACCESS mapping table to modify the effect on having authrewrite set to a nonzero value on some source channel, it is not necessary to use FROM_ACCESS if the authenticated address is going to be used verbatim.

For example, with authrewrite 2 set on the tcp_local channel, the following FROM_ACCESS mapping table would not be necessary because authrewrite alone is sufficient to get this effect (adding the authenticated address verbatim):

FROM_ACCESS

   *|SMTP*|*|tcp_auth|*|     $Y
   *|SMTP*|*|tcp_auth|*|*    $Y$K$4

However, the real purpose of FROM_ACCESS is to permit more complex and subtle alterations, as shown in the example below. The authrewrite channel option alone is appropriate if you want to add a Sender: header line (showing the SMTP AUTH authenticated submitter address) to incoming messages. However, suppose you want to force the addition of such a Sender: header line to incoming messages only if the SMTP AUTH authenticated submitter address differs from the envelope From: address (that is, not bother to add a Sender: header line if the addresses match), and suppose further that you wish the SMTP AUTH and envelope From: addresses will not be considered to differ merely because the envelope From: includes optional subaddress information.

FROM_ACCESS

! If no authenticated address is available, do nothing
  *|SMTP*|*|tcp_auth|*| $Y
! If authenticated address matches envelope From:, do nothing
  *|SMTP*|*|tcp_auth|*|$3* $Y
! If authenticated address matches envelope From: sans
! subaddress, do nothing
  *|SMTP*|*|tcp_auth|*+*@*|$3*@$5* $Y
! Fall though to...
! ...authenticated address present, but didn?t match, so force
! Sender: header
  *|SMTP*|*|tcp_auth|*|* $Y$K$4

The $( metacharacter in a FROM_ACCESS specifies that an address should be read from the result string and used to replace the current overriding postmaster address. $) has the same effect with the added constraint that the overriding postmaster address must not be set prior to invoking the mapping. This allows for specific postmaster addresses to be used with addresses in nonlocal domains - domain postmaster addresses by definition only work with locally defined domains. The override address is (currently) the last string read from the FROM_ACCESS result prior to reading any $N/$F failure result.

PORT_ACCESS Mapping Table

The Dispatcher is able to selectively accept or reject incoming connections based on IP address and port number. As the Dispatcher accepts incoming connections, it searches the PORT_ACCESS table using probes of the form:

TCP|server-address|server-port|client-address|client-port

The Dispatcher tries to match against all PORT_ACCESS mapping entries. If the result of the mapping contains $N or $F, the connection will be immediately closed. Any other result of the mapping indicates that the connection is to be accepted. $N or $F may optionally be followed by a rejection message. If present, the message will be sent back down the connection just prior to closure. Note that a CRLF terminator will be appended to the string before it is sent back down the connection.

The tcp_smtp_server and tcp_lmtp_server processes also probe the PORT_ACCESS table. Checks that should not be duplicated in both the dispatcher and SMTP or LMTP server processes should be qualified using $: or $; and the A or S flags. See "PORT_ACCESS Input Flags" for more information.

Note:

The MMP does not make use of mapping tables. If you wish to reject SMTP connections from certain IP addresses and you are using the MMP, you must use the TCPAccess option. See "To Configure Mail Access with MMP."

To control SMTP connections using mapping tables, use the INTERNAL_IP mapping table (see "Allowing SMTP Relaying for External Sites.")

The flag $< followed by an optional string causes Messaging Server to send the string to syslog (UNIX) or to the event log (NT) if the mapping probe matches. The flag $> followed by an optional string causes Messaging Server to send the string as to syslog (UNIX) or to the event log (NT) if access is rejected. If bit 1 of the LOG_CONNECTION MTA option is set and the $N flag is set so that the connection is rejected, then also specifying the $T flag will cause a "T" entry to be written to the connection log. If bit 4 of the LOG_CONNECTION MTA option is set, then site-supplied text may be provided in the PORT_ACCESS entry to include in the "C" connection log entries. To specify such text, include two vertical bar characters in the right-hand side of the entry, followed by the desired text.

PORT_ACCESS is evaluated unconditionally as soon as the SMTP server thread starts, before the banner is sent.

The following flags and metacharacters apply to the PORT_ACCESS mapping table. The "Send Access and Mail Access Mapping Tables" and "FROM_ACCESS Mapping Table" have different sets of flags.

See the Messaging Server Reference for more details about the format and operation, and patterns, templates, and metacharacters which apply to all mapping tables.

Input flags are set by the process that calls the mapping table and tested for by using the $: and $; metacharacters in the template. The $: will succeed if the flag is set or fail if it is not set. The $; will succeed if the flag is not set or fail if it is set. Table 13-8 shows the $:x form to test if the flag is set. The $;x form can also be used to test if condition is not true.

The PORT_ACCESS table is consulted by both the dispatcher and the tcp_smtp_server or tcp_lmtp_server processes. Mapping table entries that perform callouts to external functions that may incur some overhead should be done in one or the other, but not both.

Table 13-8 PORT_ACCESS Input Flags

Flag Description

$:A

Match only when the probe is performed by the Dispatcher.

$:S

Match only when the probe is performed by an SMTP server or LMTP server.


See "To Use DNS Lookups Including RBL Checking for SMTP Relay Blocking" for examples of using $:A, $;A, $:S, and $;S.

Output flags are set by the template in the mapping table entry and consumed upon return to the calling program. The Valid column in the tables below indicates whether the flag is used by dispatcher (D), tcp_smtp_server (S), or tcp_lmtp_server (L). The Table 13-8, "PORT_ACCESS Input Flags" should be used to ensure that rules are only applied in the appropriate context. Table 13-9 shows the PORT_ACCESS output flags.

Table 13-9 PORT_ACCESS Output Flags

Flag Valid Description

$U

S

Enable channel (slave) debugging. If MM_DEBUG or OS_DEBUG are set, enable those as well. See the discussion on debugging channel master and slave programs in the Messaging Server Reference for more information.

$V

S

Enable the MTA's private SMTP extensions XADR, XCIR, XGEN, and XSTA, overriding any SMTP server DISABLE_* channel options.

$/

DS

Set the "fast disconnect" flag for sessions that have not yet succeeded in starting a transaction; for such sessions, any subsequent disconnect is done with SO_LINGER enabled and a timeout of 0, which may clear slots quicker on intermediate firewalls and proxies.

$Y

DSL

Allow access.

$T

D

If bit 1 (value 2) of the LOG_CONNECTION MTA option is set and the $N flag is set so that the connection is rejected, then $T outputs the entire right hand side text in a "T" (or "X" ++) record. The T log entry will include the entire mapping result string ($N and its string). In contrast, bit 4 of LOG_CONNECTION is a different effect: it will cause material after two vertical bars to be included in normal "C" (connection close) records.


Table 13-10 describes PORT_ACCESS flags with arguments. For more information see "Output Flag Argument Order." Note: Do NOT alphabetize this list.

Table 13-10 PORT_ACCESS Flags with Arguments

Flag Valid Description

$<string

DSL

Send string to syslog if probe matches.

$>string

DSL

Send string to syslog if access is rejected.

$N string

$F string

DSL

Reject access with the optional error text string.

$F is a synonym for $N

SASL Ruleset

S

Not used, but you must enter an empty value (double bar with no space, "||") if you want to use any of the following flags.

SASL Realm

S

Not used, but you must enter an empty value (double bar with no space, "||") if you want to use any of the following flags.

Application Info

SL

If the LOG_CONNECTION MTA option is set to bit 4 (value 16), PORT_ACCESS is allowed to add text to application information string. This is where the string can be specified. If it is not used, you must enter an empty value (double bar with no space, "||") if you want to use any of the flags below.

$D delay

S

Specifies the number of centiseconds to delay before purging and sending the banner. A value of 0 disabled both the delay and purge. This value has the same semantics as the BANNER_PURGE_DELAY value. Note that any PORT_ACCESS mapping setting overrides the BANNER_PURGE_DELAY SMTP channel option. For details on using this anti-spam feature see the Messaging Server Reference.

$S channel

S

Set channel as the source channel for this SMTP session.

Certificate Nickname

S

Comma-separated list of Server Certificates to send to client for TLS.


{+} To use multiple flags with arguments, separate the arguments with the vertical bar character, |, placing the arguments in the order listed in this table. For more information see "Output Flag Argument Order."

++ The T record discussed in the $T flag above occurs when the PORT_ACCESS table entry is being evaluated by the dispatcher process. If it is evaluated by the tcp_smpt_server it will produce an X record instead.

PORT_ACCESS Table Examples

For example, the following mapping will only accept SMTP connections (to port 25, the normal SMTP port) from a single network, except for a particular host singled out for rejection without explanatory text:

PORT_ACCESS

  TCP|*|25|192.123.10.70|*  $N500
  TCP|*|25|192.123.10.*|*   $Y
  TCP|*|25|*|*              $N500$ Bzzzt$ thank$ you$ for$ playing.

You need to restart the Dispatcher after making any changes to the PORT_ACCESS mapping table so that the Dispatcher will see the changes. (If you are using a compiled MTA configuration, you will first need to recompile your configuration using the imsimta cnbuild command to get the change incorporated into the compiled configuration.)

The PORT_ACCESS mapping table is specifically intended for performing IP-based rejections. For more general control at the email address level, the SEND_ACCESS or MAIL_ACCESS mapping table, might be more appropriate.

Table 13-9, "PORT_ACCESS Output Flags" lists the order in which arguments are consumed from the template for certain flags and other arguments that can be returned from the PORT_ACCESS table.

PORT_ACCESS

  *|*|*|*|*  $C$|INTERNAL_IP;$3|$Y$E
  *  $YEXTERNAL

In this default configuration, it appears as if the $Y is being given a mysterious "EXTERNAL" argument. But $Y does not take any arguments. That "EXTERNAL" is actually the value for the "SASL Ruleset" argument. If other argument-consuming flags were specified, you would use "|" to separate the arguments.

SASL Ruleset

If you set a ruleset, then msconfig options of the form authoption-name apply.

Note that the PORT_ACCESS mapping supplied by the initial configuration does set the ruleset to "EXTERNAL" for incoming connections that don't match in INTERNAL_IP - that way you can, in theory, configure different SASL options for the "internal" connections (in the "DEFAULT" ruleset) vs. the "external" connections (in the "EXTERNAL" ruleset).

SASL Realm

Realm is used in place of base.defaultdomain if the userid supplied for authentication is unqualified.

Application Info

If the LOG_CONNECTION MTA option is set to bit 4 (value 16), PORT_ACCESS is allowed to add text to application information string. This is where the string can be specified. If the option is enabled but you do not want to specify any additional app info in a rule, you must enter an empty value (double bar with no space, "||") if you want to use any of the later flags/arguments.

Certificate Nickname

PORT_ACCESS

  *|*|*|*|*  $C$|INTERNAL_IP;$3|$Y$E
  TCP|1.2.3.4|*|*|* $;A$Y||xyzzy
  *  $YEXTERNAL

In this example, if the server has multiple IP addresses, for connections from clients to the server's IP address 1.2.3.4, the tcp_smtp_server process will use the Certificate with the nickname xyzzy for TLS instead of the default certificate. The "||" supplies null values for "SASL Ruleset" and "SASL Realm." If the LOG_CONNECTION MTA option is set to bit 4 (value 16), an additional "|" would be needed, for example:

PORT_ACCESS

  *|*|*|*|*  $C$|INTERNAL_IP;$3|$Y$E
  TCP|1.2.3.4|*|*|* $;A$Y|||xyzzy
  *  $YEXTERNAL

IP_ACCESS Mapping Table

The IP_ACCESS Mapping Table can be used to do a last moment check on the IP address to which the MTA is about to connect. The connection attempt can then be aborted or redirected. This can be useful under certain special circumstances, for example, security concerns about a destination IP address to which should never be connected, or where it is wished to avoid connecting to known-to-be-bogus destination IP addresses (for example, 127.0.0.1), or where you wish to attempt to fail over to another destination IP address similar to a lastresort channel option effect (see the discussion on specifying a last resort host for delivery in the Messaging Server Reference.

This access mapping is consulted during SMTP client operations just prior to attempting to open connections to a remote server. The mapping probe has the following format:

source-channel|address-current|address-count|ip-current|hostname

source-channel is the channel from which the message is being dequeued. address-count is the total number of IP addresses for the remote server. address-current is the index of the current IP address being tried. ip-current is the current IP address. hostname is the symbolic name of the remote server. Table 13-11 shows the IP_ACCESS flags.

See the Messaging Server Reference for more details about the format and operation, and patterns, templates, and metacharacters which apply to all mapping tables.

Table 13-11 IP_ACCESS Mapping Table Flags

Flag Description

$N

Immediately reject the message with an "invalid host/domain error." Any supplied text will be logged as the reason for rejection but will not be included in the DSN.

$I

Skip the current IP without attempting to connect.

$A

Replace the current IP address with the mapping result.


When Access Controls Are Applied

Messaging Server checks access control mappings as early as possible. Exactly when this happens depends upon the email protocol in use - when the information that must be checked becomes available.

For the SMTP protocol, a FROM_ACCESS rejection occurs in response to the MAIL FROM: command, before the sending side can send the recipient information or the message data. A SEND_ACCESS or MAIL_ACCESS rejection occurs in response to the RCPT TO: command, before the sending side gets to send the message data. If an SMTP message is rejected, Messaging Server never accepts or sees the message data, thus minimizing the overhead of performing such rejections.

If multiple access control mapping tables exist, Messaging Server checks them all. That is, a FROM_ACCESS, a SEND_ACCESS, an ORIG_SEND_ACCESS, a MAIL_ACCESS, and ORIG_MAIL_ACCESS mapping tables may all be in effect.

PORT_ACCESS is called from dispatcher as soon as it accepts the incoming TCP connection. It is also called from tcp_smtp_server when any of the maysaslserver or mustsaslserver channel options are present on the source channel. (See the discussion on SMTP authentication and SASL in the Messaging Server Reference.)

FROM_ACCESS is used by the tcp_smtp_server when processing the MAIL FROM SMTP command.

SEND_ACCESS and ORIG_SEND_ACCESS tables are used by the tcp_smtp_server when processing the RCPT TO SMTP command.

MAIL_ACCESS and ORIG_MAIL_ACCESS tables are used by the tcp_smtp_server when processing the RCPT TO SMTP command.

To Test Access Control Mappings

The imsimta test -rewrite utility - particularly with the -from, -source_channel, -sender and -destination_channel options - can be useful in testing access control mappings. See "imsimta test" for details. The example below shows a sample SEND_ACCESS mapping table and the resulting probe.

MAPPING TABLE:

ORIG_SEND_ACCESS

  tcp_local|friendly@example.com|*|User@example.org     $Y
  tcp_local|unwelcome@example.edu|*|User@example.org  $NGo$ away!

PROBE:

$ imsimta test -rewrite -from="friendly@example.com" -source=tcp_local User@example.org
...
Submitted address list:
  ims-ms
    user@ims-ms-daemon (orig User@example.org, inter User@example.org, host ims-ms-daemon)
*NOTIFY-FAILURES* *NOTIFY-DELAYS*

Submitted notifications list:

$ imsimta test -rewrite -from="unwelcome@example.edu" -source=tcp_local User@example.org
...
Submitted address list:
Address list error -- 5.7.1 Go away!: User@example.org

Submitted notifications list:

To Limit Specified IP Address Connections to the MTA

To limit how often a particular IP address can connect to the MTA, see "Using and Configuring MeterMaid for Access Control." Limiting connections by particular IP addresses can be useful for preventing excessive connections used in denial-of-service attacks. In the past, this function was performed using the shared library, conn_throttle.so in the Port Access mapping table. No new enhancements are planned for conn_throttle.so and MeterMaid is its more effective replacement.

conn_throttle.so is a shared library used in a PORT_ACCESS mapping table to limit MTA connections made too frequently from particular IP addresses. All configuration options are specified as options to the connection throttle shared library as follows:

$[MessagingServer_home/lib/conn_throttle.so,throttle,IP-address,max-rate]

IP-address is the dotted-decimal address of the remote system. max-rate is the connections per minute that shall be the enforced maximum rate for this IP-address.

The routine name throttle_p may be used instead of throttle for a penalizing version of the routine. throttle_p will deny connections in the future if they've connected too many times in the past. If the maximum rate is 100, and 250 connections have been attempted in the past minute, not only will the remote site be blocked after the first 100 connections in that minute, but they'll also be blocked during the second minute. In other words, after each minute, max-rate is deducted from the total number of connections attempted and the remote system is blocked as long as the total number of connections is greater than the maximum rate.

If the IP-address specified has not exceeded the maximum connections per minute rate, the shared library callout will fail.

If the rate has been exceeded, the callout will succeed, but will return nothing. This is done in a $C/$E combination as in the example:

PORT_ACCESS

  TCP|*|25|*|* \
$C$[_MessagingServer_home_/lib/conn_throttle.so,throttle,$1,10] \
$N421$ Connection$ not$ accepted$ at$ this$ time$E

Where,

$C continues the mapping process starting with the next table entry; uses the output string of this entry as the new input string for the mapping process.

$[MessagingServer_home/lib/conn_throttle.so,throttle,$1,10] is the library call with throttle as the library routine, $1 as the server IP Address, and 10 the connections per minute threshold.

$N421$ Connection$ not$ accepted$ at$ this$ time rejects access and returns the 421 SMTP code (transient negative completion) along with the message "Connection not accepted at this time".

$E ends the mapping process now. It uses the output string from this entry as the final result of the mapping process.

To Add SMTP Relaying

Messaging Server is, by default, configured to block attempted SMTP relays. That is, it rejects attempted message submissions to external addresses from unauthenticated external sources (external systems are any other system than the host on which the server itself resides). This default configuration is quite aggressive in blocking SMTP relaying in that it considers all other systems to be external systems.

IMAP and POP clients that attempt to submit messages via the Messaging Server system's SMTP server destined for external addresses, and who do not authenticate using SMTP AUTH (SASL), will find their submission attempts rejected. Thus, you will likely want to modify your configuration so that it recognizes your own internal systems and subnets from which relaying should always be accepted.

Which systems and subnets are recognized as internal is normally controlled by the INTERNAL_IP mapping table, which is located in the MessagingServer_home/config/mappings directory.

For instance, on a Messaging Server whose IP address is 123.45.67.89, the default INTERNAL_IP mapping table would appear as follows:

INTERNAL_IP

   $(123.45.67.89/32)   $Y
   127.0.0.1            $Y
   *   $N

Here the initial entry, using the $(IP-pattern/signicant-prefix-bits) syntax, is specifying that any IP address that matches all 32 bits of 123.45.67.89 should match and be considered internal. The second entry recognizes the loopback IP address 127.0.0.1 as internal. The final entry specifies that all other IP addresses should not be considered internal. All entries must be preceded by at least one space.

You add additional entries by specifying additional IP addresses or subnets before the final $N entry. These entries must specify an IP address or subnet (using the $(.../...) syntax to specify a subnet) on the left side and $Y on the right side. Or you may modify the existing $(.../...) entry to accept a more general subnet.

For instance, if this same sample site has a class-C network, that is, it owns all of the 123.45.67.0 subnet, then the site would want to modify the initial entry by changing the number of bits used in matching the address. In the mapping table below, we change from 32 bits to 24 bits. This allows all clients on the class-C network to relay mail through this SMTP relay server.

INTERNAL_IP

   $(123.45.67.89/24)   $Y
   127.0.0.1   $Y
   *   $N

Or if the site owns only those IP addresses in the range 123.45.67.80-123.45.67.99, then the site would want to use:

INTERNAL_IP

! Match IP addresses in the range 123.45.67.80-123.45.67.95
   $(123.45.67.80/28) $Y
! Match IP addresses in the range 123.45.67.96-123.45.67.99
   $(123.45.67.96/30) $Y
   127.0.0.1 $Y
   * $N

Note that the imsimta test -match utility can be useful for checking whether an IP address matches a particular $(.../...) test condition. The imsimta test -mapping utility can be more generally useful in checking that your INTERNAL_IP mapping table returns the desired results for various IP address inputs.

After modifying your INTERNAL_IP mapping table, be sure to issue the imsimta restart command (if you are not running with a compiled configuration) or an imsimta cnbuild followed by an imsimta restart smtp (if you are running with a compiled configuration) so that the changes take effect.

Further information on the mapping file and general mapping table format, as well as information on imsimta command-line utilities, can be found in the Messaging Server Reference.

Allowing SMTP Relaying for External Sites

All internal IP addresses should be added to the INTERNAL_IP mapping table as discussed above. If you have friendly or companion systems/sites from which you wish to allow SMTP relaying, the simplest approach is to include them along with your true internal IP addresses in your INTERNAL_IP mapping table.

If you don't wish to consider these as true internal systems/sites, (for instance, if for logging or other control purposes you wish to distinguish between true internal systems versus the friendly non-internal systems with relay privileges), there are other ways to configure the system.

One approach is to set up a special channel for receiving messages from such friendly systems. Do this by creating a tcp_friendly channel akin to your existing tcp_internal channel with official host name tcp_friendly-daemon, and a FRIENDLY_IP mapping table akin to your INTERNAL_IP mapping table that lists the friendly system IP addresses. Then right after the current rewrite rule:

! Do mapping lookup for internal IP addresses
[]    $E$R${INTERNAL_IP,$L}$U%[$L]@tcp_intranet-daemon

add a new rewrite rule:

! Do mapping lookup for "friendly", non-internal IP addresses
[]     $E$R${FRIENDLY_IP,$L}$U%[$L]@tcp_friendly-daemon

An alternate approach is to add to your ORIG_SEND_ACCESS mapping table above the final $N entry, new entries of the form:

tcp_local|*@example.com|tcp_local|*     $Y

where example.com is the name of a friendly domain, and to add an ORIG_MAIL_ACCESS mapping table of the form:

ORIG_MAIL_ACCESS

   TCP|*|25|$(match-example.com-IP-addresses)|*|SMTP*|MAIL|   \
tcp_local|*@example.com|tcp_local|*      $Y
   TCP|*|*|*|*|SMTP*|MAIL|tcp_local|*|tcp_local|* $N

where the $(...) IP address syntax is the same syntax described in the previous section. The ORIG_SEND_ACCESS check will succeed as long as the address is ok, so we can go ahead and also do the ORIG_MAIL_ACCESS check which is more stringent and will only succeed if the IP address also corresponds to an example.com IP address.

Configuring SMTP Relay Blocking

You can use access control mappings to prevent people from relaying SMTP mail through your Messaging Server system. For example, you can prevent people from using your mail system to relay junk mail to hundreds or thousands of Internet mailboxes.

By default, Messaging Server prevents all SMTP relaying activity, including relaying by local POP and IMAP users.

Blocking unauthorized relaying while allowing it for legitimate local users requires configuring Messaging Server to know how to distinguish between the two classes of users. For example, local users using POP or IMAP depend upon Messaging Server to act as an SMTP relay.

To prevent SMTP relay, you must be able to:

To enable SMTP relay by internal hosts and clients, you must add your "internal" IP addresses or subnets to the INTERNAL_IP mapping table.

Differentiate Between Internal and External Mail

To block mail relaying activities, the MTA must first be able to differentiate between internal mail originated at your site and external mail originated out on the Internet and passing through your system back out to the Internet. The former class of mail you want to permit; the latter class you want to block. This differentiation is achieved using the switchchannel option on your inbound SMTP channel, usually the tcp_local channel, and is set by default.

The switchchannel channel option works by causing the SMTP server to look at the actual IP address associated with the incoming SMTP connection. Messaging Server uses that IP address, in conjunction with your rewrite rules, to differentiate between an SMTP connection originated within your domain and a connection from outside of your domain. This information can then be used to segregate the message traffic between internal and external traffic.

The MTA configuration described below is setup by default so that the server can differentiate between your internal and external message traffic.

  • In the configuration file, immediately before the local channel, is a defaults channel with the noswitchchannel option:

    defaults notices 1 2 4 7 noswitchchannel immnonurgent maxjobs 7 defaulthost example.com example.com
    
  • The incoming TCP/IP channel specifies the switchchannel and remotehost options; for example:

    tcp_local smtp single_sys mx switchchannel remotehost
    tcp-daemon
    
  • After the incoming TCP/IP channel definition, is a similar channel with a different name which specifies the allowswitchchannel option; for example:

    tcp_intranet smtp single_sys mx allowswitchchannel
    tcp_intranet-daemon
    

    With the above configuration settings, SMTP mail generated within your domain will come in via the tcp_intranet channel. All other SMTP mail will come in via the tcp_local channel. Mail is distinguished between internal and external based upon which channel it comes in on.

How does this work? The key is the switchchannel option. The option is applied to the tcp_local channel. When a message comes in your SMTP server, that option causes the server to look at the source IP address associated with the incoming connection. The server attempts a reverse-pointing envelope rewrite of the literal IP address of the incoming connection, looking for an associated channel. If the source IP address matches an IP address or subnet in your INTERNAL_IP mapping table, the rewrite rule which calls out to that mapping table causes the address to rewrite to the tcp_intranet channel.

Since the tcp_intranet channel is marked with the allowswitchchannel option, the message is switched to the tcp_intranet channel and comes in on that channel. If the message comes in from a system whose IP address is not in the INTERNAL_IP mapping table, the reverse-pointing envelope rewrite will either rewrite to the tcp_local or, perhaps to some other channel. However, it will not rewrite to the tcp_intranet channel and since all other channels are marked noswitchchannel by default, the message will not switch to another channel and will remain with the tcp_local channel.

Note:

Any mapping table or conversion file entries which use the string "tcp_local" may need to be changed to either "tcp_*" or "tcp_intranet" depending upon the usage.

Differentiate Authenticated Users' Mail

Your site might have "local" client users who are not part of your physical network. When these users submit mail, the message submissions come in from an external IP address, for instance, arbitrary Internet Service Providers. If your users use mail clients that can perform SASL authentication, then their authenticated connections can be distinguished from arbitrary other external connections. The authenticated submissions you can then permit, while denying non-authenticated relay submission attempts. Differentiating between authenticated and non-authenticated connections is achieved using the saslswitchchannel option on your inbound SMTP channel, usually the tcp_local channel.

The saslswitchchannel option takes an argument specifying the channel to switch to; if an SMTP sender succeeds in authenticating, then their submitted messages are considered to come in the specified switched to channel.

To Add Distinguishing Authenticated Submissions

  1. In your configuration file, add a new TCP/IP channel definition with a distinct name; for example:

    tcp_auth smtp mustsaslserver noswitchchannel
    tcp_auth-daemon
    

    This channel should not allow regular channel switching (that is, it should have noswitchchannel on it either explicitly or implied by a prior defaults line). This channel should have mustsaslserver on it.

  2. Modify your tcp_local channel by adding maysaslserver and saslswitchchannel tcp_auth, as shown in the following example:

    tcp_local smtp mx single_sys maysaslserver saslswitchchannel tcp_auth switchchannel
    tcp-daemon
    

    With this configuration, SMTP mail sent by users who can authenticate with a local password will now come in the tcp_auth channel. Unauthenticated SMTP mail sent from internal hosts will still come in tcp_internal. All other SMTP mail will come in tcp_local.

Prevent Mail Relay

Now to the point of this example: preventing unauthorized people from relaying SMTP mail through your system. First, keep in mind that you want to allow local users to relay SMTP mail. For instance, POP and IMAP users rely upon using Messaging Server to send their mail. Note that local users may either be physically local, in which case their messages come in from an internal IP address, or may be physically remote but able to authenticate themselves as local users.

You want to prevent random people out on the Internet from using your server as a relay. With the configuration described in the following sections, you can differentiate between these classes of users and block the correct class. Specifically, you want to block mail from coming in your tcp_local channel and going back out that same channel. To that end, an ORIG_SEND_ACCESS mapping table is used.

An ORIG_SEND_ACCESS mapping table may be used to block traffic based upon the source and destination channel. In this case, traffic from and back to the tcp_local channel is to be blocked. This is realized with the following ORIG_SEND_ACCESS mapping table:

ORIG_SEND_ACCESS

  tcp_local|*|tcp_local|*  $N$D30|Relaying$ not$ allowed

In this example, the entry states that messages cannot come in the tcp_local channel and go right back out it. That is, this entry disallows external mail from coming in your SMTP server and being relayed right back out to the Internet.

An ORIG_SEND_ACCESS mapping table is used rather than a SEND_ACCESS mapping table so that the blocking will not apply to addresses that originally match the ims-ms channel (but which may expand via an alias or mailing list definition back to an external address). With a SEND_ACCESS mapping table one would have to go to extra lengths to allow outsiders to send to mailing lists that expand back out to external users, or to send to users who forward their messages back out to external addresses.

To Use DNS Lookups Including RBL Checking for SMTP Relay Blocking

In the Messaging Server, there are a number of different ways to ensure that all mail accepted for delivery or forwarding comes from an address with a valid DNS name. The simplest way is to put the mailfromdnsverify channel option on the tcp_local channel.

Messaging Server also provides the dns_verify program which allows you to ensure that all mail accepted for delivery or forwarding comes from an address with a valid DNS name using the following rule in ORIG_MAIL_ACCESS:

ORIG_MAIL_ACCESS

  TCP|*|*|*|*|SMTP*|MAIL|*|*@*|*|*  \
$[_MessagingServer_home_/lib/dns_verify.so,\
dns_verify,$7|$$y|$$NInvalid$ host:$ $$7$ -$ %e]

The line breaks in the above example are syntactically significant in such mapping entries. The backslash character is a way of legally continuing on to the next line.

The dns_verify image can also be used to check incoming connections against things like the RBL (Realtime Blackhole List), MAPS (Mail Abuse Prevention System, DUL (Dial-up User List), or ORBS (Open Relay Behavior-modification System) lists as another attempt to protect against UBE. As with the new mailfromdnsverify option, there's also a separate "simpler to configure" approach one can use for such checks rather than doing the dns_verify callout. The simpler approach is to use the DNS_VERIFY_DOMAIN option in the dispatcher configuration. For example, for the smtp service, set instances of the option to the various lists you want to check against:

msconfig
msconfig# set dispatcher.service:smtp.dns_verify_domain sbl-xbl.spamhaus.org
msconfig# set dispatcher.service:smtp.dns_verify_domain list.dsbl.org
msconfig# write

In this case, messages are rejected at the SMTP level, that is, the messages are rejected during the SMTP dialogue and thus never sent to the MTA. The disadvantage of this simpler approach is that it does the checks for all normal incoming SMTP messages including those from internal users. This is less efficient and potentially problematic if your Internet connectivity goes down. An alternative is to call out to dns_verify from a PORT_ACCESS mapping table or ORIG_MAIL_ACCESS mapping table. In the PORT_ACCESS mapping table, you can have an initial entry or entries that don't check for local internal IP addresses or message submitters and a later entry that does the desired check for everyone else. Or, in an ORIG_MAIL_ACCESS mapping table, if you only apply the check on messages coming in the tcp_local channel then you're skipping it for messages coming from your internal systems/clients. Examples using the entry points to dns_verify are shown below.

PORT_ACCESS

! Allow internal connections in unconditionally
  *|*|*|*|* $C$|INTERNAL_IP;$3|$Y$E
! Check other connections against RBL list
  TCP|*|25|*|* \
$C$[_MessagingServer_home_/lib/dns_verify.so,dns_verify_domain_port,$1,\
dnsblock.example.com.,Your$ host$ ($1)$ found$ on$ dnsblock$ list]$E
  * $YEXTERNAL

ORIG_MAIL_ACCESS

  TCP|*|25|*|*|SMTP*|*|tcp_local|*@*|*|*  \
$C$[_MessagingServer_home_/lib/dns_verify.so,\
dns_verify_domain,$1,sbl-xbl.spamhaus.org.]$E

For more information see the discussion on performance tuning DNS realtime blocklists (RBL) lookups in the Messaging Server Installation and Configuration Guide.

The PORT_ACCESS table is probed both by the dispatcher, when accepting connections, and by the tcp_smtp_server process under certain circumstances.

The tcp_smtp_server processes always check the PORT_ACCESS table for channels marked maysaslserver or mustsaslserver, and they will do it for all channels if bit 4 (value 16) of the MTA LOG_CONNECTION option is set.

So if either of those are true, the customer needs to be aware that his PORT_ACCESS table is being processed twice for every connection. This may be a trivial overhead except that callouts to things like DNS RBLs or LDAP lookups can be relatively expensive in terms of their impact on SMTP server response time. For this reason, you want to avoid doing them any more than necessary. That is one reason the callout in the example above is coded after the INTERNAL_IP lookup. If the SMTP client is in your INTERNAL_IP table, then you allow the connection without doing the RBL lookup. Reversing that order would mean your local clients would be delayed by RBL lookups. To prevent doing this twice, add a check for one the flags set by dispatcher or tcp_smtp_server so that you only process that table entry when one of those is set or not. For example, add $:A to the entry:

TCP|*|25|*|*   \
$C$:A$[_MessagingServer_home_/lib/dns_verify.so,dns_verify_domain_port,$1,\
dnsblock.example.com.,Your$ host$ ($1)$ found$ on$ dnsblock$ list]$E
    * $YEXTERNAL

We added the $:A after the $C so the table processing will continue down the table if this does not match. The $:A specifies that this entry be processed only if it is being done by the dispatcher, that is, not when done by tcp_smtp_server. Alternatively, if you wanted to cause it to be done only in tcp_smtp_server, use $:S instead:

TCP|*|25|*|*   \
$C$:S$[_MessagingServer_home_/lib/dns_verify.so,dns_verify_domain_port,$1,\
dnsblock.example.com.,Your$ host$ ($1)$ found$ on$ dnsblock$ list]$E
    * $YEXTERNAL

The negative check would be $;A to check that A is not set, or $;S to check that S is not set.

Support for DNS-based Databases

The dns_verify program supports DNS-based databases used to determine incoming SMTP connections that might send unsolicited bulk mail. Some of the publicly available DNS databases do not contain TXT records that are typically used for this purpose. Instead, they only contain A records.

In a typical setup, the TXT record found in the DNS for a particular IP address contains an error message suitable to return to the SMTP client when refusing a message.

dns_verify supports an option that specifies a default text that is used in the event that no TXT record is available. For example, the following PORT_ACCESS mapping table shows how to enable this option:

PORT_ACCESS

   *|*|*|*|* $C$|INTERNAL_IP;$3|$Y$E
   TCP|*|25|*|*   \
$C$[_MessagingServer_home_/lib/dns_verify.so \
,dns_verify_domain_port,$1,dnsblock.example.com,Your$ host$ ($1)$ \
found$ on$ dnsblock$ list]$E
    * $YEXTERNAL

In this example, if the remote system is found in a query in the domain dnsblock.example.com, but no TXT record is available, then the following message is returned, "Your host a.b.c.d found on dnsblock list."

Handling Large Numbers of Access Entries

Sites that use very large numbers of entries in mapping tables should consider organizing their mapping tables to have a few general wildcarded entries that call out to the general text database for the specific lookups. It is much more efficient to have a few mapping table entries calling out to the general text database for specific lookups than to have huge numbers of entries directly in the mapping table.

One case in particular is that some sites like to have per user controls on who can send and receive Internet email. Such controls are conveniently implemented using an access mapping table such as ORIG_SEND_ACCESS. For such uses, efficiency and performance can be greatly improved by storing the bulk of the specific information (that is, specific addresses) in the general text database with mapping table entries structured to call out appropriately to the general text database.

For example, consider the ORIG_SEND_ACCESS mapping table shown below.

ORIG_SEND_ACCESS

! Users allowed to send to Internet
!
  *|adam@example.com|tcp_local|*    $Y
  *|betty@example.com|tcp_local|*   $Y
! ...etc...
!
! Users not allowed to send to Internet
!
  *|norman@example.com|tcp_local|*  $NInternet$ access$ not$ permitted
  *|opal@example.com|tcp_local|*    $NInternet$ access$ not$ permitted
! ...etc...
!
! Users allowed to receive from the Internet
!
  tcp_*|*|*|adam@example.com        $Y
  tcp_*|*|*|betty@example.com       $Y
! ...etc...
!
! Users not allowed to receive from the Internet
!
  tcp_*|*|*|norman@example.com      $NInternet$ e-mail$ not$ accepted
  tcp_*|*|*|opal@example.com        $NInternet$ e-mail$ not$ accepted
! ...etc...

Rather than using such a mapping table with each user individually entered into the table, a more efficient setup (much more efficient if hundreds or thousands of user entries are involved) is shown in the example below, which shows sample source text file for a general database and a sample ORIG_SEND_ACCESS mapping table. For more information, see the discussion on MTA text databases in the Messaging Server Reference.

DATABASE ENTRIES

SEND|adam@domain.com    $Y
SEND|betty@domain.com   $Y
! ...etc...
SEND|norman@domain.com  $NInternet$ access$ not$ permitted
SEND|opal@domain.com    $NInternet$ access$ not$ permitted
! ...etc...
RECV|adam@domain.com    $Y
RECV|betty@domain.com   $Y
! ...etc...
RECV|norman@domain.com  $NInternet$ e-mail$ not$ accepted
RECV|opal@domain.com    $NInternet$ e-mail$ not$ accepted

MAPPING TABLE

ORIG_SEND_ACCESS

! Check if may send to Internet
!
  *|*|*|tcp_local       $C${SEND|$1}$E
!
! Check if may receive from Internet
!
  tcp_*|*|*|*           $C${RECV|$3}$E

In this example, the use of the arbitrary strings SEND| and RECV| in the general database left-hand sides (and hence in the general database probes generated by the mapping table) provides a way to distinguish between the two sorts of probes being made. The wrapping of the general text database probes with the $C and $E flags, as shown, is typical of mapping table callouts to the general text database.

The above example showed a case of simple mapping table probes getting checked against general text database entries. Mapping tables with much more complex probes can also benefit from use of the general text database.

Controlling the Envelope From: Address in Mappings Strings and Mailing List Named Options and LDAP Attributes

The use_auth_return, use_canonical_return, and use_orig_return MTA options control which envelope address to use in certain mapping tables or mailing list named options (if using the aliases file for mailing lists) or attributes (if using LDAP mailing lists).

For more information on these options, see the discussion on return address type used in checks MTA options in the Messaging Server Reference.

PART 2. MAILBOX FILTERS

Mailbox filters, also called Sieve filters, filter messages containing specified strings found in the message headers and apply specified actions to these mail message. Administrators can filter mail streams going to a user, through a channel, or through an MTA. Messaging Server filters are stored on the server and evaluated by the server, hence, they are sometimes called server-side rules (SSR).

This section contains the following topics:

Sieve Filter Support

Messaging Server filters are based on the Sieve filtering language, Draft 9 of the Sieve Internet Draft. See RFC3028 for more information about Sieve syntax and semantics. In addition, Messaging Server also supports the following Sieve extensions:

  • jettison. Similar to discard in that it causes messages to be silently discarded, but unlike discard, which does nothing but cancel the implicit keep, jettison forces a discard to be performed. The behavioral difference is only relevant when multiple Sieve filters are involved. For example, a system level discard can be overridden by a user Sieve filter explicitly specifying keep, whereas a system level jettison will override anything done by a user Sieve.

  • Head-of-household Sieve filters. Provides a means by which one user can specify a Sieve filter for another user. Uses two LDAP attributes in a user entry controlled by these MTA options:

    • LDAP_PARENTAL_CONTROLS - Specifies an attribute containing a string value of either Yes or No. Yes means a head of household Sieve is to be applied to this entry, No means no such Sieve is to be applied. No default.

    • LDAP_FILTER_REFERENCE - Specifies an attribute containing a DN pointing to a directory entry where the head of household Sieve can be found. No default.

      The entry containing the head of household Sieve must contain two attributes specified by the following MTA options:

    • LDAP_HOH_FILTER - Specifies an attribute containing the head of household Sieve. The value of this option defaults to mailSieveRuleSource.

    • LDAP_HOH_OWNER - Specifies an attribute containing the email address of the owner of the head of household. The value of this option defaults to mail. Both of these attributes must be present for the head of household Sieve to work.

  • Sieve redirect can now add three header fields:

    resent-date: _date-of-resend-operation_
    resent-to: _address-specified-in-redirect_
    resent-from: _addres-of-sieve-owner_
    

    The new :resent and :noresent arguments to redirect can be used to control whether or not these fields are added. If neither argument is specific the system default is used. The system default is controlled by the new SIEVE_REDIRECT_ADD_RESENT MTA option. Setting the option to 1 causes these fields to be generated unless :noresent used. A setting of 0 causes the fields to be generated only if :resent is used. The option defaults to 1, which means the fields are generated by default for regular redirects.

  • Sieve redirect has been enhanced with three new arguments::resetmailfrom - Reset the envelope FROM: address to that of the current Sieve owner.

    :keepmailfrom - Preserve the envelope FROM: address from the original message.

    :notify - Specify a new set of notification flags for the redirected message. A single option is required giving a list of notification flags. The same set of flags accepted by the NOTIFY option of the DSN SMTP extension are accepted here: SUCCESS, FAILURE, DELAY and NEVER. Note that these flags are specified as a Sieve list, for example:

    redirect :notify ["SUCCESS","FAILURE"] "foo@example.com";
    

    The default if :notify isn't specified as the normal SMTP default of FAILURE, DELAY. :keepmailfrom is the default unless :notify is specified, in which case the default switches to :resetmailfrom. The one additional exception is that specification of the SUCCESS flag forces the use of :resetmailfrom unconditionally.

Sieve Filtering Overview

A Sieve filter consists of one or more conditional actions to apply to a mail message depending upon a string found in the message header. As an administrator, you can create channel-level filters and MTA-wide filters to prevent delivery of unwanted mail. Users can create per-user filters for their own mailboxes by using the mail filter interface in either Communications Express or Convergence.

The server applies filters in the following priority:

  1. User-level filters If a personal mailbox filter explicitly accepts or rejects a message, then filter processing for that message finishes. But if the recipient user had no mailbox filter, or if the user's mailbox filter did not explicitly apply to the message in question, Messaging Server next applies the channel-level filter.

  2. Channel-level filter If the channel-level filter explicitly accepts or rejects a message, then filter processing for that message finishes. Otherwise, Messaging Server next applies the MTA-wide filter, if there is one.

  3. MTA-wide filter

By default, each user has no mailbox filter. When a user uses either the Communications Express or Convergence interfaces to create one or more filters, then their filters are stored in the Directory and retrieved by the MTA during the directory synchronization process.

To Create User-level Filters

Per-user mail filters apply to messages destined for a particular user's mailbox. Per-user mail filters can only be created by using either the Communications Express or Convergence interfaces.

To Create Channel-level Filters

Channel-level filters apply to each message enqueued to a channel. A typical use for this type of filter is to block messages going through a specific channel. Table 13-12 shows the filter channel option URL-pattern substitution tags.

Table 13-12 filter Channel Option URL-pattern Substitution Tags (Case-insensitive)

Tag Meaning

*

Perform group expansion.

**

Expand the attribute mailForwardingAddress. This can be a multivalued attribute resulting in several delivery addresses being produced.

$$

Substitute in the $ character.

$

Force subsequent text to lower case.

$^

Force subsequent text to upper case.

$_

Perform no case conversion on subsequent text.

$~

Substitute in the file path for the home directory associated with the local part of the address.

$1S

As $S, but if no subaddress is available just insert nothing.

$2S

As $S, but if no subaddress is available insert nothing and delete the preceding character.

$3S

As $S, but if no subaddress is available insert nothing and ignore the following character.

$A

Substitute in the address, local-part@host.domain.

$D

Substitute in host.domain.

$E

Insert the value of the second spare attribute, LDAP_SPARE_1.

$F

Insert the name of the delivery file (mailDeliveryFileURL attribute).

$G

Insert the value of the second spare attribute, LDAP_SPARE_2.

$H

Substitute in host.

$I

Insert the hosted domain (part of UID to the right of the separator specified by domainUidSeparator). Fail if no hosted domain is available.

$1I

As $I, but if no hosted domain is available just insert nothing.

$2I

As $I, but if no hosted domain is available insert nothing and delete the preceding character.

$3I

As $I, but if no hosted domain is available insert nothing and ignore the following character.

$L

Substitute in local-part.

$M

Insert the UID, stripped of any hosted domain.

$P

Insert the method name (mailProgramDeliveryInfo attribute).

$S

Insert the subaddress associated with the current address. The subaddress is that part of the user part of the original address after the subaddress separator, usually {+}, but can be specified by the MTA option SUBADDRESS_CHAR. Fail if no subaddress is given

$U

Insert the mailbox part of the current address. This is either the whole of the address to the left of the @ sign, or that part of the left hand side of the address before the subaddress separator, {+}.


To Create a Channel-level Filter

  1. Write the filter using Sieve.

  2. Store the filter in a file in the following directory:MessagingServer_home/config/file.filter The file must be world readable and owned by the MTA's uid.

  3. Include the following in the channel configuration:

    destinationfilter file:IMTA_TABLE:<file>.filter
    
  4. Recompile the configuration and restart the Dispatcher. Note that changes to the filter file do not require a recompile or restart of the Dispatcher. The destinationfilter channel option enables message filtering on messages enqueued to the channel to which it is applied. The sourcefilter channel option enables message filtering on messages enqueued by (from) the channel to which it is applied. These options each have one required option which specifies the path to the corresponding channel filter file associated with the channel.

    The syntax for the destinationfilter channel option is:

    destinationfilterURL-pattern

    The syntax for the sourcefilter channel option is: sourcefilterURL-pattern

    where URL-pattern is a URL specifying the path to the filter file for the channel in question. In the following example, channel-name is the name of the channel.

    destinationfilter file:///usr/tmp/filters/<channel-name>.filter
    

    The filter channel option enables message filtering on the channels to which it is applied. The option has one required option which specifies the path to the filter files associated with each envelope recipient who receives mail via the channel.

    The syntax for the filter channel option is:

    filterURL-pattern

    URL-pattern is a URL that, after processing special substitution sequences, yields the path to the filter file for a given recipient address. URL-pattern can contain special substitution sequences that, when encountered, are replaced with strings derived from the recipient address, local-part@host.domain in question. These substitution sequences are shown in Table 13-12, "filter Channel Option URL-pattern Substitution Tags (Case-insensitive)". The fileinto option specifies how to alter an address when a mailbox filter fileinto operator is applied. The following example specifies that the folder name should be inserted as a subaddress into the original address, replacing any originally present subaddress:

    fileinto $U+$S@$D

Managing Sieve Scripts

This document provides information about Oracle Communications Messaging Server's implementation and configuration of ManageSieve, a protocol for user management of Sieve mail filters (RFC 5228) specified in RFC 5804.

This section contains the following topics:

Location of Managed Sieves

The ManageSieve server manages a collection of Sieve scripts belonging to each user. You may select one of these scripts as the active script to filter the user's mail. You can store the scripts either in LDAP or in disk files. In either case, the active script is stored separately from the Sieve collection in either a different attribute or a separate file. You can store the script collection and the active script in different places. For example, you can store the collection on disk and store the active script in the user's LDAP entry.

Active scripts stored in LDAP can consist of multiple values of the same attribute. When the ManageSieve server reads multiple values, it appends them to form a single script. (Note, however, that you lose this storage pattern if the ManageSieve server writes the active script. The server always writes scripts to LDAP as a single attribute value.) The server stores the script collection differently. It uses a single attribute and takes each value to be a separate script.

The server stores active scripts on disk in a single file with a specific name. The server stores each script in the script collection in a separate file. Each file has the same name prefix, but the server appends a unique identifier to create a different file name for each script.

Script Name Storage

Each script in the collection has a name. The server stores this name as a comment at the beginning of the script. The ManageSieve server maintains this comment which does not appear as part of the Sieve data provided to the client.

The server does not store the active script's name in the script itself and therefore the script does not contain an initial comment.

Stored Script Semantics

The ManageSieve server is designed to accommodate the behavior of other agents that both access and modify stored Sieve scripts. It does not assume that stored scripts will remain unaltered and does not cache scripts internally.

Specifically, each ManageSieve operation causes the following initial steps to be performed:

  1. The server reads the active script and script collections from their respective locations. It silently ignores scripts in the collection that do not begin with a valid name comment.

  2. The server computes a hash for the content of each script that is found. Note that this hash does not cover the initial comment containing the script name.

  3. The server performs a sanity check on all scripts in the collection. If two scripts have the same hash value, the server changes one of them by adding sufficient trailing white space to obtain a unique hash. Similarly, the server checks the names of every script in the collection. If two scripts have the same name, the server adds -n, where n is an integer, to make the name unique.

  4. The server checks the hash of each script in the collection against the hash of the active script. The server considers the script with the matching hash to be the active script. If no script in the collection has a matching hash, the server creates a new script with a name of the form ACTIVE-datetime, where datetime is the time the server performs the operation.

  5. The server writes immediately to LDAP, disk, or both any changes the preceding two steps made to the collection.

The server performs the requested operation only after it performs these steps. This operation may cause additional changes that the server writes when the operation finishes.

This rather convoluted approach ensures that the ManageSieve server's view of the user's Sieve state remains consistent even if other agents manipulate the underlying data in unexpected ways.

ManageSieve Service Configuration

ManageSieve runs as a service under the dispatcher. To configure the ManageSieve service, you add a ManageSieve service to the dispatcher, create a channel definition, and set optional channel options. Note that the ManageSieve channel does not act as either a source or destination channel in the conventional sense in the MTA. Instead, it is used to store various ManageSieve configuration settings. In particular, the channel is used to specify where Sieves are stored. The filter channel option specifies where the active Sieve is stored while the destinationfilter channel option specifies where the Sieve collection is stored.

Configuring the ManageSieve Service

To configure the ManageSieve Service:

  1. Edit the dispatcher.cnf file and add the following lines if you are running in a legacy configuration.

    [SERVICE=MANAGESIEVE]
    PORT=4190
    IMAGE=IMTA_BIN:managesieve
    LOGFILE=IMTA_LOG:managesieve_server.log
    STACKSIZE=204800
    PARAMETER=CHANNEL=managesieve
    

    If you have a Unified Configuration, run the following msconfig commands.

    msconfig
    set dispatcher.service:MANAGESIEVE.tcp_ports 4190
    set dispatcher.service:MANAGESIEVE.parameter "CHANNEL=managesieve"
    set dispatcher.service:MANAGESIEVE.stacksize 204800
    set dispatcher.service:MANAGESIEVE.image "IMTA_BIN:managesieve"
    set dispatcher.service:MANAGESIEVE.logfilename "IMTA_LOG:managesieve_server.log"
    write
    
  2. Create a channel definition specifying Sieve storage in LDAP by editing the imta.cnf configuration file in a legacy configuration and adding the following channel definition.

    managesieve smtp_crlf filter ldap:///$A?mailSieveRuleSource \
       destinationfilter ldap:///$A?mailSieveCollection maytlsserver
     managesieve-daemon
    

    If you have a Unified Configuration, run the following commands.

    msconfig
    set channel:managesieve.official_host_name managesieve-daemon
    set channel:managesieve.smtp_crlf
    set channel:managesieve.filter "ldap:///$A?mailSieveRuleSource"
    set channel:managesieve.destinationfilter "ldap:///$A?mailSieveCollection"
    set channel:managesieve.maytlsserver
    set channel:managesieve.scriptlimit 32
    set channel:managesieve.sievelimit 1048576
    set channel:managesieve.sizelimit 4194304
    write
    

    Note:

    The values of the last three channel options shown are the defaults. We include these settings to point out the limits imposed by the ManageSieve server.

    The specification of LDAP URLs in the channel definitions indicates that scripts are to be stored in LDAP. The $A metacharacter substitutes the DN of the user's LDAP entry that was determined when the user authenticated to the ManageSieve server. Note the specification of the maytlsserver channel option. Although TLS is negotiated in the ManageSieve protocol and is therefore optional, most existing ManageSieve clients require it and will not work without TLS being enabled.

  3. Set optional ManageSieve-channel-specific options. If you want to configure a custom implementation string in a legacy configuration, for example, add the following lines to a managesieve_options file.

    CUSTOM_BANNER_STRING=NameCUSTOM_VERSION_STRING=Version
    

    To set these option in a Unified Configuration using msconfig, run the following commands.

    msconfig
    set channel:managesieve.options.custom_banner_string Name
    set channel:managesieve.options.custom_version_string Version
    write
    

    A recipe, managesieve.rcp, is provided to set up a ManageSieve server in a Unified Configuration.

Supported Channel Options

Table 13-13 shows the channel options supported by the ManageSieve server and their descriptions:

Table 13-13 Supported Channel Options

Channel Option Description

filter url

A URL specifying where the active script is stored. Either a file: or LDAP URL can be used. If an LDAP URL is used it must specify exactly one LDAP attribute. The following substitutions may be useful in constructing the URL:

$A - The DN of the user's LDAP entry determined by the authentication process.

$M - The user's UID determined by the authentication process.

$?whatever? - The store's hashdir algorithm is applied to whatever to produce a directory path.

destinationfilter url

A URL specifying where the user's script collection is stored. Either a file: or LDAP URL can be used. If an LDAP URL is used it must specify exactly one LDAP attribute. The same set of substitutions provided for the filter option are available.

scriptlimit integer

Maximum number of scripts allowed in a single user's collection. The default is 32.

sievelimit integer

The maximum size, in octets, of a single script. Note that this limit is imposed at the protocol, not processing, level. The default is 1048576.

sizelimit integer

The maximum combined size, in octets, of a user's scripts. The default is 4194304.

notlscerver, maytlsserver, musttlsserver

Specifies whether TLS cannot be negotiated, may be negotiated, or must be negotiated, respectively. notlsserver is the default, but note that many ManageSieve clients require the availability and use of TLS.

disconnectbadauthlimit integer

Limit on the number of failed authentication attempts that can be done before the server disconnects.

disconnectbadcommandlimit integer

Limit on the number of bad commands the server will allow before disconnecting.

disconnectcommandlimit integer

Limit on the number of commands the server will allow before disconnecting.

slave_debug, noslave_debug

Controls whether or not the server produces debug output. noslave_debug is the default. Note that server logging does not normally include authentication information. Authentication information will be included if the AUTH_DEBUG ManageSieve-channel-specific option is set (see below).

stmp_crlf, smtp_cr, smtp_lf, smtp_crorlf

These options do not imply the use of the SMTP protocol. They are simply used to specify the line termination that the server requires for commands. smtp_crlf is the default and, given the use of counted literals in the protocol, should not be changed except under truly extraordinary circumstances.

ident*

Controls the sort of checks done on the client IP address. This information is only used for logging purposes in ManageSieve.

nameservers ip4-addrss-list

Controls what nameservers are used by any check requested by the ident* options. The default is to use the system default nameservers.


Supported ManageSieve-Channel-Specific Options

Table 13-14 shows the ManageSieve-channel-specific options supported by the ManageSieve server and their descriptions:

Table 13-14 Supported ManageSieve-Channel-Specific Options

ManageSieve-Channel-Specific-Option Description

CUSTOM_BANNER_STRING string

Text to include in the IMPLEMENTATION capability response. The default is the Messaging Server product name.

CUSTOM_VERSION_STRING string

Text to include in the IMPLEMENTATION capability response. The default is the Messaging Server product version and build date.

LOG_CONNECTION integer

Same semantics as the LOG_CONNECTION TCPIP-channel-specific option.

IGNORE_BAD_CERT integer

Same semantics as the IGNORE_BAD_CERT TCPIP-channel-specific option.

COMMAND_TIMEOUT integer

The amount of time in seconds that the ManageSieve server will wait for a command. The default is 300 seconds (5 minutes).

STATUS_TIMEOUT integer

The amount of time in seconds that the ManageSieve server will wait for a status response to be sent. The default is 60 seconds.

TRACE_LEVEL integer

Enables protocol-level tracing of all protocol exchanges just above the TLS layer. Note that this will include authentication exchanges. The default value is 0.

AUTH_DEBUG string

Set of space-separated keys to pass to the authentication subsystem to enable various debug settings. See the HULA documentation for details about what keys are available. Note that setting AUTH_DEBUG and the slave_debug channel option (see above) will cause authentication command and response information to be included in the debug logs. The default is for no keys to be set.

MAX_THREADS integer

Same semantics as the MAX_SERVER_THREADS TCPIP-channel-specific option.


ManageSieve Server Use of PORT_ACCESS Mapping

The dispatcher checks connections to the ManageSieve server with the PORT_ACCESS mapping just as it does with any other connection it handles. Table 13-15 shows the server-specific PORT_ACCESS metacharacters that are relevant to ManageSieve and a description of how they work.

Table 13-15 PORT_ACCESS Metacharacters

PORT_ACCESS Metacharacters Description

$U

$U is the equivalent of setting the slave_debug channel option, except it only affects the current connection.

$G

Set TRACE_LEVEL ManageSieve-channel-specific option value to 2 for this connection only.


Basic Command/Response Test Script

The following output shows a basic command/response test script.

"IMPLEMENTATION" "YoyoDyne file test 0.00000000001"
"VERSION" "1.0"
"MAXREDIRECTS" "32"
"NOTIFY" "mailto"
"SIEVE" "copy date editheader encoded-character envelope-auth envelope envelope-dsn environment ereject extracttext foreverypart ihave index imap4flags mime reject relational redirect-dsn subaddress spamtest spamtestplus variables virustest body extlists fileinto notify enotify regex vacation vacation-seconds"
"STARTTLS"
"SASL" "PLAIN"
OK
noop
OK "NOOP Completed"
noop "doof"
OK (TAG {4}
doof) "Done"
authenticate "plain" "xxxxxxxxxxxx"
OK "Authentication successful"
listscripts
OK
putscript "discard" "discard;"
OK "Sieve added"
listscripts
"discard"
OK
getscript "discard"
{8}
discard;
OK
putscript "keep" "keep;"
OK "Sieve added"
listscripts
"keep"
"discard"
OK
setactive "discard"
OK "Sieve activated"
listscripts
"keep"
"discard" ACTIVE
OK
setactive "keep"
OK "Sieve activated"
listscripts
"keep" ACTIVE
"discard"
OK
setactive "discard"
OK "Sieve activated"
listscripts
"keep"
"discard" ACTIVE
OK
setactive ""
OK "Active Sieve deactivated"
listscripts
"keep"
"discard"
OK
deletescript "keep"
OK "Sieve deleted"
deletescript "discard"
OK "Sieve deleted"
listscripts
OK
putscript "test" "refuse \"this is a test\";"
NO {72}
Refuse not listed in require clause prior to use [ "this is a test" ; ^]
putscript "test" "require \"refuse\"; refuse \"this is a test\";"
OK "Sieve added"
getscript "test"
{42}
require "refuse"; refuse "this is a test";
OK
renamescript "test" "test2"
OK "Sieve renamed"
listscripts
"test2"
OK
getscript "test2"
{42}
require "refuse"; refuse "this is a test";
OK
renamescript "test3" "test"
NO (NONEXISTENT) "Source Sieve does not exist"
putscript "discard" "discard;"
OK "Sieve added"
renamescript "test2" "discard"
NO (ALREADYEXISTS) "Destination Sieve already exists"
putscript "doof" ""
NO "Quoted string too short"
deletescript "discard"
OK "Sieve deleted"
deletescript "test2"
OK "Sieve deleted"
havespace "doof" 1234
OK
havespace "doof" 12345678
NO (QUOTA/MAXSIZE) "Maximum Sieve size exceeded"
havespace "doof" 123456789
NO (QUOTA/MAXSIZE) "Maximum Sieve size exceeded"
havespace "doof" 1234567890
NO "Number is too large"
logout
BYE "Disconnecting"

To Create MTA-Wide Filters

MTA-wide filters apply to all messages enqueued to the MTA. A typical use for this type of filter is to block unsolicited bulk email or other unwanted messages regardless of the messages' destinations. To create an MTA-wide filter:

  1. Write the filter using Sieve

  2. Store the filter in the following file:MessagingServer_home/config/imta.filter This filter file must be world readable. It is used automatically, if it exists.

  3. Recompile the configuration and restart the Dispatcher When using a compiled configuration, the MTA-wide filter file is incorporated into the compiled configuration.

Routing Discarded Messages Out the FILTER_DISCARD Channel

By default, messages discarded via a mailbox filter are immediately discarded (deleted) from the system. However, when users are first setting up mailbox filters (and perhaps making mistakes), or for debugging purposes, it can be useful to have the deletion operation delayed for a period.

To have mailbox filter discarded messages temporarily retained on the system for later deletion, first add a filter_discard channel to your MTA configuration with the notices channel option specifying the length of time (normally number of days) to retain the messages before deleting them, as shown in the following example:

filter_discard notices 7
filter-discard

Then set the MTA option FILTER_DISCARD to 2 by running msconfig set filter_discard 2. Messages in the filter_discard queue area should be considered to be in an extension of users' personal wastebasket folders. As such, note that warning messages are never sent for messages in the filter_discard queue area, nor are such messages returned to their senders when a bounce or return is requested. Rather, the only action taken for such messages is to eventually silently delete them, either when the final notices value expires, or if a manual bounce is requested using a utility such as imsimta return.

The use of the filter_discard channel by the jettison Sieve action is controlled by the FILTER_JETTISON option, which takes its default from the FILTER_DISCARD setting. FILTER_DISCARD in turn defaults to 1 (discards go to the bitbucket channel).

To Debug User-level Filters

If a user complains that a Sieve filter is not behaving as expected, there are a number of steps you can take to debug the filters. These are described here.

  1. For fileinto filtering to work, run msconfig edit channels and check that the ims-ms channel is marked as follows:

    fileinto $U+$S@$D

  2. Get the user level filters from the user's LDAP entry. User level filters are stored in their LDAP entry under the MailSieveRuleSource attribute(s). To retrieve this with a ldapsearch command, remember they are base64 encoded so you will need to decode the output by using the -Bo switch.

    ldapsearch -D "cn=directory manager" -w password -b "o=alcatraz.example.org,o=isp" -Bo uid=test
    

    The imsimta test -rewrite command, described below, will also automatically decode them.

  3. Verify that the use's filters are being seen by the MTA. Issue the command:

    imsimta test -rewrite -filter -debug user@example.org
    

    This should output the user's Sieve filters that you retrieve in the previous step. If you do not see the filters, then you need to figure out why the LDAP entry isn't returning them. If the imsimta test -rewrite output shows the filters, then you know that the user's filters are being seen by the MTA. The next step is to test the interpretation of the filters by using the imsimta test -expression command.

  4. Use imsimta test -exp to debug the user's filter. The following information is required:

    1. The user's Sieve language statements from their mailSieveRuleSource attribute. See the steps above.

    2. The rfc2822 message that was supposed to trigger the filter.

    3. Description of what they expected the filter to do to the message.

  5. a text file (example: temp.filter) containing the Sieve language statements based on the user's mailSieveRuleSource: values. Example:

    require "fileinto";
    if anyof(header :contains
    ["To","Cc","Bcc","Resent-to","Resent-cc", "Resent-bcc"] "commsqa"){
       fileinto "QMSG";
    }
    

    Expected result: if commsqa is a recipient for this message, then file the message into a folder called QMSG.

  6. Create a text file called test.msg that contains the contents of the rfc2822 message file supplied by user. You can either use a .msg file from the user's message store area, or create a text file called test_rfc2822.msg that contains the contents of the rfc2822 message file supplied by user.

  7. Use the imsimta test -exp command:

    imsimta test -exp -mm -block -input=temp.filter -message=test_rfc2822.msg
    
  8. Examine the output. The last lines of the imsimta test -exp command will show the result of the Sieve interpretation. They will look like this:

    Sieve Result: []
    

    or this:

    Sieve Result: [_action_]
    

    where action is the action that would be done as a result of applying the Sieve filter on this message. If the criteria of the filter matched, you will have some action displayed as the result. If nothing matched, then the Sieve result will be blank, and there is either a logic error in the Sieve filter or the .msg file doesn't contain matching information. If you get any other error, then there is a syntax error in the Sieve script file, and you need to debug it. For more details on the output, see "imsimta test -exp Output."

  9. If the filter is syntactically valid and results are correct, then the next step is to examine a tcp_local_slave.log debug log file. It may be that the message file you're testing and the one being sent aren't identical. The only way to see what's being received is to examine a tcp_local_slave.log file. This log will show you the exact message being sent to the MTA and how the filter is being applied to that message. For more information on getting a tcp_local_slave.log debug file, see the slave_debug option in the discussion on debugging channel master and slave programs in the Messaging Server Reference.

imsimta test -exp Output

The full command imsimta test -exp for is as follows:

imsimta test -exp -mm -block -input=temp.filter -message=rfc2822.msg

An example of the output is as follows:

Example - imsimta test -exp Output

# imsimta test -exp -mm -block -input tmp.filter -message=rfc2822.msg
Expression: if header :contains ["to"] ["pamw"]       (1)
Expression: {
Expression: redirect "usr3@example.org";
Expression: keep;
Expression: }
Expression:
Expression: Dump: header:2000114;0  3  1  :contains  1  "to"  1
"pamw"  if  8  ;
Dump: redirect:2000121;0  1  1  "usr3@example.org"  ;  keep:2000117;0  (2)
Dump: 0
Result: 0
Filter result: [ redirect "usr3@example.org" keep ]    (3)

1) The Expression: output lines show the filter being read and parsed from tmp.filter text file. These are not particularly useful in debugging the script.

2) The Dump: output lines are the result of the computer interpreting the Sieve statements. You should not see any errors and the output should seem to match your input. For example the dump shows the word redirect, usr3@example.org which is like the line in the filter file redirect "usr3@example.org";.

If it didn't show this matching text, then you'd be concerned, otherwise, these also are not particularly useful in debugging the script.

3) At the bottom of the output you will get the Filter result: statement. As stated earlier there are two possible results:

Sieve Result: [] or this: Sieve Result: [action]

where action is the action taken by the Sieve script. Note that sometimes the results are expected to be empty. For example, for a discard filter, you should test that it doesn't always discard every .msg file you test it against. If there is some action between the brackets, for example:

Filter result: [fileinto "QMSG" keep]

This means the text in the rfc2822.msg file matched the filter criteria. In this particular example, the filter will file the mail into folder QMSG and keep a copy in the inbox. The resulting actions in this case are fileinto and keep.

When testing filters you should test various .msg files for both results. You should always test that messages that match your filter are filtered, and messages that you do not want to match are not filtered.

Keep in mind that if for wildcard matches, you must use the :matches test and not :contains. For example, if you wish from=*@example.org to match, you must use :matches or the test will fail as it will not ever satisfy the test condition.

imsimta test -exp Syntax

imsimta test -exp tests Sieve language statements against a specified RFC2822 message and sends the results of the filter to standard output.

The syntax is as follows:

imsimta test -exp -mm -block -input=Sieve_language_scriptfile-message=rfc2822_message_file

where,

-block treats the entire input as a single Sieve script. The default is to treat each line as a separate script and to evaluate it separately. The Sieve will only be evaluated once the end of file is reached.