1MILTER-REGEX(8) BSD System Manager's Manual MILTER-REGEX(8)
2
4 milter-regex — sendmail milter plugin for regular expression filtering
5
7 milter-regex [-d] [-c config] [-p pipe] [-u user]
8
10 The milter-regex plugin can be used with the milter API of sendmail(8) to
11 filter mails using regular expressions matching SMTP envelope parameters
12 and mail headers and body.
13
14 The options are as follows:
15
16 -d Don't detach from controlling terminal and produce verbose
17 debug output on stdout.
18
19 -c config Use the specified configuration file instead of the default,
20 /etc/mail/milter-regex.conf.
21
22 -p pipe Use the specified pipe to interface sendmail(8). Default is
23 unix:/var/spool/milter-regex/sock.
24
25 -u user Run as the specified user instead of the default, mregex.
26 When milter-regex is started as root, it calls setuid(2) to
27 drop privileges. The non-privileged user should have read
28 access to the configuration file and read-write access to the
29 pipe.
30
32 The plugin needs to be registered in the sendmail(8) configuration, by
33 adding the following lines to the .mc file
34
35 INPUT_MAIL_FILTER(`milter-regex',
36 `S=unix:/var/spool/milter-regex/sock, T=S:30s;R:2m')
37
38 rebuilding /etc/mail/sendmail.cf from the .mc file using m4(1), and
39 restarting sendmail(8).
40
42 The configuration file consists of rules that, when matched, cause
43 sendmail(8) to reject mails. Emtpy lines and lines starting with # are
44 ignored, as well as leading whitespace (blanks, tabs). Trailing back‐
45 slashes can be used to wrap long rules into multiple lines. Each rule
46 starts with one of the following commands:
47
48 reject <message>
49 Subsequent rules cause the mail to be rejected with a permanent
50 error consisting of the specified text part. The SMTP reply con‐
51 sists of the three-digit code 554 (RFC 2821 "command rejected for
52 policy reasons"), the extended reply code 5.7.1 (RFC 1893 "Perma‐
53 nent Failure", "Security or Policy Status", "Delivery not autho‐
54 rized, message refused") and the text part (which defaults to "Com‐
55 mand rejected", if not specified). This is a permanent failure,
56 which causes the sender to remove the message from its queue with‐
57 out trying to retransmit, commonly generating a bounce message to
58 the sender.
59
60 tempfail <message>
61 Subsequent matching rules cause the mail to be rejected with a tem‐
62 porary error consisting of the specified text part. The SMTP reply
63 consists of the three-digit code 451 (RFC 2821 "Requested action
64 aborted: local error in processing"), the extended reply code 4.7.1
65 (RFC 1893 "Persistent Transient Failure", "Security or Policy Sta‐
66 tus", "Delivery not authorized, message refused") and the text part
67 (which defaults to "Please try again later", if not specified).
68 This is a temporary failure, which causes the sender to keep the
69 message in its queue and try to retransmit it, commonly for several
70 days.
71
72 discard
73 Subsequent matching rules cause the mail to be accepted but then
74 discarded silently. Note that connect and helo rules should not
75 use discard.
76
77 quarantine <message>
78 Subsequent matching rules cause the mail to be quarantined in
79 sendmail(8).
80
81 accept
82 Subsequent matching rules cause the mail to be accepted without
83 further rule evaluation. Can be used for whitelist criteria.
84
85 A command is followed by one or more expressions, each causing the previ‐
86 ous command to be executed when matched. The following expressions can
87 be used:
88
89 connect <hostname> <address>
90 Reject the connection if both the sender's hostname and address
91 match the specified regular expressions. The numerical address is
92 either dotted-quad (IPv4) or coloned-hex (IPv6). The hostname is
93 the result of a DNS reverse resolution of the numerical address
94 (which sendmail(8) performs independantly of the milter plugin).
95 When resolution fails, the hostname contains the numerical address
96 in square brackets.
97
98 helo <name>
99 Reject the connection if the sender supplied HELO name matches the
100 specified regular expression. Commonly, the sender supplies his
101 fully-qualified hostname as HELO name.
102
103 envfrom <address>
104 Reject the mail if the sender supplied envelope MAIL FROM address
105 matches the specified regular expression. Addresses commonly have
106 the form <user@host.doma.in>.
107
108 envrcpt <address>
109 Reject the mail if the sender supplied envelope RCPT TO address
110 matches the specified regular expression.
111
112 header <name> <value>
113 Reject the mail if a header matches the specified name and value.
114 For instance, the header "Subject: Test" matches name Subject and
115 value Test.
116
117 body <line>
118 Reject the mail if a body line matches the specified regular
119 expression.
120
121 macro <name> <value>
122 Reject the mail if a sendmail macro value matches.
123
124 The plugin regularly checks the configuration file for modification and
125 reloads it automatically. Signals like SIGHUP will terminate the plugin,
126 according to the milter signal handler. The plugin reacts to any kind of
127 error, like syntax errors in the configuration file, by failing open,
128 accepting all messages. When the plugin is not running, sendmail(8) will
129 accept all messages.
130
132 The regular expressions used in the configuration rules are enclosed in
133 arbitrary delimiters, no further escaping is needed.
134
135 The first character of an argument is taken as the delimiter, and all
136 subsequent characters up to the next occurance of the same delimiter are
137 taken literally as the regular expression. Since the delimiter itself
138 cannot be part of the regular expression (no escaping is supported), a
139 delimiter must be chosen that doesn't occur in the regular expression
140 itself. Each argument can use a different delimiter, all characters
141 except spaces and tabs are valid.
142
143 Two immediately adjacent delimiters form an empty regular expression,
144 which always matches and requires no regexec(3) call. This can be used
145 in rules requiring multiple arguments, to match only some arguments.
146
147 See re_format(7) for a detailed description of basic and extended regular
148 expressions.
149
150 Optionally, the following flags can be used after the closing delimiter:
151 e Extended regular expression. This sets REG_EXTENDED for regcomp(3).
152 i Ignore upper/lower case. This sets REG_ICASE.
153 n Not matching. Reverses the matching result, i.e. the mail is
154 rejected if the regular expression does not match.
155
157 A rule can consist of either a simple term or more complex expressions.
158 A term has the form
159
160 header /From/ /domain/i
161
162 and expressions can be built combining terms with operators "and", "or",
163 "not" and parentheses, as in
164
165 header /From/ /domain/i and body /money/
166 ( not header /From/ /domain/ ) and ( body /sex/ or body /fast/ )
167
168 Operator precedence should not be relied on, instead parentheses should
169 be used to resolve any ambiguities (they usually produce syntax errors
170 from the parser).
171
173 Macros allow to store terms or expressions as a name, and $name can be
174 used as term within other rules, expressions or macro definitions. Exam‐
175 ple:
176
177 friends = header /^Received$/ /^from [^ ]*(ork.net|home.com)/e
178 attachments = header ,^Content-Type$, ,multipart/mixed, and \
179 body ,^Content-Type: application/,
180 executables = $attachments and body ,name=".*.(pif|exe|scr)"$,e
181
182 reject "executable attachment from non-friends"
183 $executables and not $friends
184
185 Macro names must begin with a letter and may contain alphanumeric charac‐
186 ters and punctuation characters. Reserved keywords (like "reject" or
187 "header") cannot be used as macro names. Macros must be defined before
188 use, the definition must precede the use in the configuration file, read
189 from top to bottom.
190
192 Rules are evaluated in the order specified in the configuration file,
193 from top to bottom. When a rule matches, the corresponding action is
194 taken, that is the last action specified before the matching rule.
195
196 The plugin evaluates the rules every time a line of mail (or envelope) is
197 received. As soon as a rule matches, the action is taken immediately,
198 possibly before the entire mail is received, even if further lines might
199 possibly make other rules match, too. This means the first rule matching
200 chronologically has precendence.
201
202 If evaluation for a line of mail makes two (or more) rules match, the
203 rule that comes first in the configuration file has precendence.
204
205 Boolean expressions are short-circuit evaluated, that means "a or b"
206 becomes true as soon as one of the terms is true and "a and b" becomes
207 false as soon as one of the terms is false, even if the other term is not
208 known, possibly because the relevant mail line has not been received yet.
209
211 # /etc/mail/milter-regex.conf example
212
213 # Accept anything encrypted, just to demonstrate sendmail macros
214 accept
215 macro /tls_version/ /TLSv/
216
217 tempfail "Sender IP address not resolving"
218 connect /\[.*\]/ //
219
220 reject "Malformed HELO (not a domain, no dot)"
221 helo /\./n
222
223 reject "Malformed RCPT TO (not an email address, not <.*@.*>)"
224 envrcpt /<(.*@.*|Postmaster)>/ein
225
226 reject "HTML mail not accepted"
227 # use comma as delimiter here, as / occurs within RE
228 header /^Content-type$/i ,^text/html,i
229 body ,^Content-type: text/html,i
230
231 # Swen worm
232 discard
233 header /^(TO|FROM|SUBJECT)$/e //
234 header /^Content-type$/i /boundary="Boundary_(ID_/i
235 header /^Content-type$/i /boundary="[a-z]*"/
236 body ,^Content-type: audio/x-wav; name="[a-z]*\.[a-z]*",i
237
238 # Some nasty spammer
239 reject "Business Corp spam, get lost"
240 body /^Business Corp. for W.& L. AG/i and \
241 ( body /043.*317.*0285/ or body /0041.43.317.02.85/ )
242
243
245 milter-regex sends log messages to syslogd(8) using facility daemon and,
246 with increasing verbosity, level err, notice, info and debug. The fol‐
247 lowing syslog.conf(5) section can be used to log messages to a dedicated
248 file:
249
250 !milter-regex
251 daemon.err;daemon.notice /var/log/milter-regex
252
254 Syntax for milter-regex in BNF:
255
256 file = ( rule | macro ) file
257 rule = action expr-list
258 action = "reject" msg | "tempfail" msg | "discard" |
259 "quarantine" msg | "accept"
260 msg = ( '"' | "'" ) string ( '"' | "'" )
261 expr-list = expr [ expr-list ]
262 expr = term | term "and" expr | term "or" expr | "not" term
263 term = '(' expr ')' | "connect" arg arg | "helo" arg |
264 "envfrom" arg | "envrcpt" arg | "header" arg arg |
265 "body" arg | "macro" arg arg | '$' name
266 arg = del regex del flags
267 del = '/' | ',' | '-' | ...
268 flags = [ 'e' ] [ 'i' ] [ 'n' ]
269 macro = name '=' expr
270
272 /etc/mail/milter-regex.conf
273
275 mailstats(1), regex(3), syslog.conf(5), re_format(7), sendmail(8),
276 syslogd(8)
277
278 Simple Mail Transfer Protocol, RFC 2821.
279
280 Enhanced Mail System Status Codes, RFC 1893.
281
283 The first version of milter-regex was written in 2003. Boolean expres‐
284 sion evaluation was added in 2004.
285
287 Daniel Hartmeier ⟨daniel@benzedrine.cx⟩
288
289BSD September 24, 2003 BSD