DragonFly On-Line Manual Pages
MILTER-REGEX(8) DragonFly System Manager's Manual MILTER-REGEX(8)
NAME
milter-regex - sendmail milter plugin for regular expression filtering
SYNOPSIS
milter-regex [-d] [-q] [-c config] [-r pid-file] [-j dirname]
[-l loglevel] [-m number] [-p pipe] [-u user]
DESCRIPTION
The milter-regex plugin can be used with the milter API of sendmail(8) to
filter mails using regular expressions matching SMTP envelope parameters
and mail headers and body.
The options are as follows:
-d Don't detach from controlling terminal and produce verbose
debug output on stdout.
-q Don't send to syslog messages with priority higher than
LOG_NOTICE.
-c config Use the specified configuration file instead of the default,
/usr/local/etc/milter-regex.conf.
-r pid-file
Use the specified pid file to write to. Default is:
/var/run/milter-regex/milter-regex.pid
-j dirname
Change root to the specified directory.
-l loglevel
Only log messages up to and including the specified level.
See syslog(3) for the numerical values, e.g. LOG_INFO=6.
-m number Ignore mail body after the specified number of lines.
-p pipe Use the specified pipe to interface sendmail(8). Default is
unix:/var/run/milter-regex/sock.
-u user Run as the specified user instead of the default, _milter-
regex. When milter-regex is started as root, it calls
setuid(2) to drop privileges. The non-privileged user should
have read access to the configuration file and read-write
access to the pipe.
SENDMAIL CONFIGURATION
The plugin needs to be registered in the sendmail(8) configuration, by
adding the following lines to the .mc file
INPUT_MAIL_FILTER(`milter-regex',
`S=unix:/var/run/milter-regex/sock, T=S:30s;R:2m')
rebuilding /etc/mail/sendmail.cf from the .mc file using m4(1), and
restarting sendmail(8).
PLUGIN CONFIGURATION
The configuration file consists of rules that, when matched, cause
sendmail(8) to reject mails. Emtpy lines and lines starting with # are
ignored, as well as leading whitespace (blanks, tabs). Trailing
backslashes can be used to wrap long rules into multiple lines. Each
rule starts with one of the following commands:
reject <message>
Subsequent rules cause the mail to be rejected with a permanent
error consisting of the specified text part. The SMTP reply
consists of the three-digit code 554 (RFC 2821 "command rejected
for policy reasons"), the extended reply code 5.7.1 (RFC 1893
"Permanent Failure", "Security or Policy Status", "Delivery not
authorized, message refused") and the text part (which defaults to
"Command rejected", if not specified). This is a permanent
failure, which causes the sender to remove the message from its
queue without trying to retransmit, commonly generating a bounce
message to the sender.
tempfail <message>
Subsequent matching rules cause the mail to be rejected with a
temporary error consisting of the specified text part. The SMTP
reply consists of the three-digit code 451 (RFC 2821 "Requested
action aborted: local error in processing"), the extended reply
code 4.7.1 (RFC 1893 "Persistent Transient Failure", "Security or
Policy Status", "Delivery not authorized, message refused") and the
text part (which defaults to "Please try again later", if not
specified). This is a temporary failure, which causes the sender
to keep the message in its queue and try to retransmit it, commonly
for several days.
discard
Subsequent matching rules cause the mail to be accepted but then
discarded silently. Note that connect and helo rules should not
use discard.
quarantine <message>
Subsequent matching rules cause the mail to be quarantined in
sendmail(8).
accept
Subsequent matching rules cause the mail to be accepted without
further rule evaluation. Can be used for whitelist criteria.
A command is followed by one or more expressions, each causing the
previous command to be executed when matched. The following expressions
can be used:
connect <hostname> <address>
Reject the connection if both the sender's hostname and address
match the specified regular expressions. The numerical address is
either dotted-quad (IPv4) or coloned-hex (IPv6). The hostname is
the result of a DNS reverse resolution of the numerical address
(which sendmail(8) performs independantly of the milter plugin).
When resolution fails, the hostname contains the numerical address
in square brackets.
helo <name>
Reject the connection if the sender supplied HELO name matches the
specified regular expression. Commonly, the sender supplies his
fully-qualified hostname as HELO name.
envfrom <address>
Reject the mail if the sender supplied envelope MAIL FROM address
matches the specified regular expression. Addresses commonly have
the form <user@host.doma.in>.
envrcpt <address>
Reject the mail if the sender supplied envelope RCPT TO address
matches the specified regular expression.
header <name> <value>
Reject the mail if a header matches the specified name and value.
For instance, the header "Subject: Test" matches name Subject and
value Test.
body <line>
Reject the mail if a body line matches the specified regular
expression.
macro <name> <value>
Reject the mail if a sendmail macro value matches.
The plugin regularly checks the configuration file for modification and
reloads it automatically. Signals like SIGHUP will terminate the plugin,
according to the milter signal handler. The plugin reacts to any kind of
error, like syntax errors in the configuration file, by failing open,
accepting all messages. When the plugin is not running, sendmail(8) will
accept all messages.
REGULAR EXPRESSIONS
The regular expressions used in the configuration rules are enclosed in
arbitrary delimiters, no further escaping is needed.
The first character of an argument is taken as the delimiter, and all
subsequent characters up to the next occurance of the same delimiter are
taken literally as the regular expression. Since the delimiter itself
cannot be part of the regular expression (no escaping is supported), a
delimiter must be chosen that doesn't occur in the regular expression
itself. Each argument can use a different delimiter, all characters
except spaces and tabs are valid.
Two immediately adjacent delimiters form an empty regular expression,
which always matches and requires no regexec(3) call. This can be used
in rules requiring multiple arguments, to match only some arguments.
See re_format(7) for a detailed description of basic and extended regular
expressions.
Optionally, the following flags can be used after the closing delimiter:
e Extended regular expression. This sets REG_EXTENDED for regcomp(3).
i Ignore upper/lower case. This sets REG_ICASE.
n Not matching. Reverses the matching result, i.e. the mail is
rejected if the regular expression does not match.
BOOLEAN EXPRESSIONS
A rule can consist of either a simple term or more complex expressions.
A term has the form
header /From/ /domain/i
and expressions can be built combining terms with operators "and", "or",
"not" and parentheses, as in
header /From/ /domain/i and body /money/
( not header /From/ /domain/ ) and ( body /sex/ or body /fast/ )
Operator precedence should not be relied on, instead parentheses should
be used to resolve any ambiguities (they usually produce syntax errors
from the parser).
MACROS
Macros allow to store terms or expressions as a name, and $name can be
used as term within other rules, expressions or macro definitions.
Example:
friends = header /^Received$/ /^from [^ ]*(ork.net|home.com)/e
attachments = header ,^Content-Type$, ,multipart/mixed, and \
body ,^Content-Type: application/,
executables = $attachments and body ,name=".*.(pif|exe|scr)"$,e
reject "executable attachment from non-friends"
$executables and not $friends
Macro names must begin with a letter and may contain alphanumeric
characters and punctuation characters. Reserved keywords (like "reject"
or "header") cannot be used as macro names. Macros must be defined
before use, the definition must precede the use in the configuration
file, read from top to bottom.
EVALUATION
Rules are evaluated in the order specified in the configuration file,
from top to bottom. When a rule matches, the corresponding action is
taken, that is the last action specified before the matching rule.
The plugin evaluates the rules every time a line of mail (or envelope) is
received. As soon as a rule matches, the action is taken immediately,
possibly before the entire mail is received, even if further lines might
possibly make other rules match, too. This means the first rule matching
chronologically has precedence.
If evaluation for a line of mail makes two (or more) rules match, the
rule that comes first in the configuration file has precedence.
Boolean expressions are short-circuit evaluated, that means "a or b"
becomes true as soon as one of the terms is true and "a and b" becomes
false as soon as one of the terms is false, even if the other term is not
known, possibly because the relevant mail line has not been received yet.
EXAMPLES
# /usr/local/etc/milter-regex.conf example
# Accept anything encrypted, just to demonstrate sendmail macros
accept
macro /tls_version/ /TLSv/
tempfail "Sender IP address not resolving"
connect /\[.*\]/ //
reject "Malformed HELO (not a domain, no dot)"
helo /\./n
reject "Malformed RCPT TO (not an email address, not <.*@.*>)"
envrcpt /<(.*@.*|Postmaster)>/ein
reject "HTML mail not accepted"
# use comma as delimiter here, as / occurs within RE
header /^Content-type$/i ,^text/html,i
body ,^Content-type: text/html,i
# Swen worm
discard
header /^(TO|FROM|SUBJECT)$/e //
header /^Content-type$/i /boundary="Boundary_(ID_/i
header /^Content-type$/i /boundary="[a-z]*"/
body ,^Content-type: audio/x-wav; name="[a-z]*\.[a-z]*",i
# Some nasty spammer
reject "Business Corp spam, get lost"
body /^Business Corp. for W.& L. AG/i and \
( body /043.*317.*0285/ or body /0041.43.317.02.85/ )
LOGGING
milter-regex sends log messages to syslogd(8) using facility daemon and,
with increasing verbosity, level err, notice, info and debug. The
following syslog.conf(5) section can be used to log messages to a
dedicated file:
!milter-regex
daemon.err;daemon.notice /var/log/milter-regex
GRAMMAR
Syntax for milter-regex in BNF:
file = ( rule | macro ) file
rule = action expr-list
action = "reject" msg | "tempfail" msg | "discard" |
"quarantine" msg | "accept"
msg = ( '"' | "'" ) string ( '"' | "'" )
expr-list = expr [ expr-list ]
expr = term | term "and" expr | term "or" expr | "not" term
term = '(' expr ')' | "connect" arg arg | "helo" arg |
"envfrom" arg | "envrcpt" arg | "header" arg arg |
"body" arg | "macro" arg arg | '$' name
arg = del regex del flags
del = '/' | ',' | '-' | ...
flags = [ 'e' ] [ 'i' ] [ 'n' ]
macro = name '=' expr
FILES
/usr/local/etc/milter-regex.conf
SEE ALSO
mailstats(8), regex(3), syslog(3), syslog.conf(5), re_format(7),
sendmail(8), syslogd(8)
Simple Mail Transfer Protocol, RFC 2821.
Enhanced Mail System Status Codes, RFC 1893.
HISTORY
The first version of milter-regex was written in 2003. Boolean
expression evaluation was added in 2004.
AUTHORS
Daniel Hartmeier <daniel@benzedrine.cx>
DragonFly 6.5-DEVELOPMENT September 24, 2003 DragonFly 6.5-DEVELOPMENT