1 # POSTLICYD configuration
3 # Postlicyd configuration contains:
4 # - a set of filter definition
5 # - the entry point in the filters for each smtp states
7 # The configuration format use 2 types of data:
8 # Token: [[:alpha:]]([[:alnum:]_]*)
9 # String: string format is a bit more complex. It can be one of the two following
11 # - C-like strings "[^\n\r]*". In this kind of string, the \ character is used to
12 # escape any character \c = c (\n = n, \\ = \, ...). This format allow non-ascii
13 # strings and string concatenation " abcd " "ef" = " abcd ef".
14 # - ASCII-only strings can be written without double-quotes. They can be splitted
15 # into several lines using shell-like escaping of EOL. A string begins and ends on
16 # on a non-blank character. This king of string can not contain semi-colons.
18 # The following format are equivalent:
22 # (2) "this is a string"
27 # Most of the configuration use a format:
30 # When not in a string, spaces and line breaks are ignored. You can use comments
31 # everywhere out of a string. It starts with a '#' character and ends at the end of the
32 # line. Comments are strictly equivalents to white spaces.
36 # A definition of a filter contains:
37 # - the name of the filter. This name MUST be uniq (non-uniq names can lead to undefined
40 # - a list of type-specific parameters
41 # - a list of hooks (on_hookname)
44 # A filter look likes that:
48 # param1 = parameter value 1;
56 # A filter can returns different values. Each return value is given a name. The
57 # configuration associates an action to run to a return value name.
59 # A hook action has the format: (counter:id:incr:)?(filter_name|postfix:ACTION)
61 # The action can contains the reference to a counter to update. This counters are "message"-wide
62 # counters that stay valid until the end of the filtering of the message. This counters are useful
63 # to trig different actions depending on the number of failures encountered during the processing
64 # of a message. There are 64 counters (0..63), accessible from all the filters. By specifying
65 # counter:id:incr as a prefix of the hook action, you tell postlicyd to add (incr) to counter
66 # (id) when this hook is reached. The "counter" filter type allow you to run actions depending
67 # on the value of a counter.
69 # The action can be either a postfix access(5) value or a filter name. Postfix access
70 # parameters must be prefixed by 'postfix:'. The text argument given to a postfix reply
71 # may contain format strings to be replaced by the parameters of the query. This arguments
72 # have the following format: ${fieldname}
75 # on_match = postfix:REJECT Blacklisted;
76 # on_fail = postfix:450 Greylisted, see http://www.example.org/${sender_domain}.html
77 # on_error = counter:0:1:postfix:DUNNO
78 # on_match = counter:63:10:whitelist
81 # Current defined filter types are:
82 # - iplist: match the client_address against one or more blacklist files from a rbl
84 # - file: (no)?lock:weight:filename
85 # declare a file to load. If lock is given, the klist is locked into the
86 # RAM. The weight is a number giving the weight of this blaclist file in the
88 # - rbldns: (no)?lock:weight:filename
89 # this is an alias for file.
90 # - dns: weight:hostname
91 # use a rbl via DNS resolution with the given weight. If a DNS lookup error occurs
92 # the IP is considered as beeing "not found".
93 # - soft_threshold: score (default: 1)
94 # minimum score to match the soft_match return value
95 # - hard_threshold: score (default: 1)
96 # minimum score to match the hard_match return value
98 # The score of a query is the sum of the weight of the blacklist it matched.
99 # - If the IP can not be parsed, returns error
100 # - If no rbl was available (no file and all dns down), returns error.
101 # - If the score is strictly greater >= than hard_threshold, returns hard_match
102 # - If the score is strictly greater >= than soft_threshold, returns soft_match
103 # - Else, returns fail
106 spamhaus_and_abuseat {
110 file = lock:10:/var/spool/postlicyd/rbl.spamhaus.org;
111 file = lock:1:/var/spool/postlicyd/cbl.abuseat.org;
116 on_soft_match = greylist;
117 on_hard_match = postfix:REJECT optional text;
118 on_fail = postfix:OK;
119 on_error = postfix:DUNNO;
123 # - strlist: match strings from the query against a list of list.
125 # - file: (no)?lock:(partial-)?(pre|suf)fix:weight:filename
126 # declare a file to load. If lock is given, the list is locked into the
127 # RAM. Prefix/Suffix is a parameter to tell the matcher which is the most
128 # efficient storage order. The strings are internally stored into a trie that
129 # allow high compression if a lot of prefix are shared by several strings. If
130 # you choose "prefix", string are stored in the natural order in memory and
131 # prefix compression is performed. If you choose "suffix", strings are stored
132 # in reverse order in memory and suffix compression is performed. If you add "partial-"
133 # to the match order, the entry will match if the file contains a prefix (resp. suffix)
134 # of the string. The weight is a number giving the weight of this list in the string score.
136 # * a file that contains ".polytechnique.org" in "partial-suffix" mode will match
137 # all subdomains of "polytechnique.org".
138 # * a file that contains "postmaster@" in "partial-prefix" mode will match all
140 # * a file open without "partial-" modifier match exact strings.
141 # - rbldns: (no)?lock:weight:filename
142 # declare a rbldns zone file to load. This is exactly the same as file excepted that it wraps
143 # parsing of hostname to split them into 2 categories:
144 # * names beginning with '*' are sorted as 'domains' and are matched as suffix
145 # * names starting with an alphanumirical character are sorted as 'hostnames' and are
146 # process via exact matching.
147 # - dns: weight:hostname
148 # use a rhbl via DNS resolution with the given weight. If a DNS lookup error occurs
149 # the hostname is considered as beeing "not found". This can only be used with "hostnames"
151 # - soft_threshold: score (default: 1)
152 # minimum score to match the soft_match return value
153 # - hard_threshold: score (default: 1)
154 # minimum score to match the hard_match return value
155 # - fields: field_name(,field_name)*
156 # list of field the match the string against.
157 # currently only email OR hostname fields are supported. You MUST choose only
158 # one of these types per strlist, and be carefull that the field you requested
159 # are available in the protocol state you want to use this filter for.
160 # * hostname fields: helo_name, client_name, reverse_client_name, sender_domain,
162 # * email fields: sender, recipient
163 # No space is allowed in this parameter.
165 # The score of a query is the sum of the weight of the list it matched.
166 # - If no rhbl was available (no file and all dns down), returns error.
167 # - If the score is strictly greater >= than hard_threshold, returns hard_match
168 # - If the score is strictly greater >= than soft_threshold, returns soft_match
169 # - Else, returns fail
171 # - to match helo_name, you must be on HELO state or later
172 # (stmpd_helo_restrictions)
173 # - to match sender, you must be on MAIL state or later
174 # (smtpd_sender_restrictions)
175 # - to match recipient, you must on RCPT state (stmpd_recipient_restrictions)
176 # - client_name and reverse_client_name are always available
178 # Whitelist some clients
183 file = lock:1:suffix:/var/spool/postlicyd/client_whitelist;
184 rbldns = lock:1:/va/spool/postlicyd/abuse.rfc-ignorant.org;
185 fields = client_name,sender_domain,helo_name;
188 on_hard_match = postfix:OK;
189 on_fail = spamhaus_and_abuseat;
193 # - greylist: greylister
195 # - path: /my/path/ (required)
196 # path where to store the greylist database
197 # - prefix: name (default: "")
198 # prefix to the name of the greylist database
199 # - lookup_by_host: boolean (default: false)
200 # perform lookup per host. The default behaviour is to remove the last number of the IP
201 # to match a domain. This behaviour is disabled if a part of the IP is contained in the
202 # hostname (look like a dialup ip from a provider). With this flag on, the "domain"
203 # matching is always disable.
204 # - no_sender: boolean (default: false)
205 # do not use the sender address. Default behaviour is to greylist using the tuple
206 # (client_address, sender, recipient). With this flag on, the sender is not used.
207 # - no_recipient: boolean (default: false)
208 # same as no_sender but with recipient.
209 # - delay: number (default: 300)
210 # number of seconds the client must wait before retrial.
211 # - retry_window: (default: 2 * 24 * 3600)
212 # number of seconds we wait for a retry.
213 # - client_awl: number (default: 5)
214 # number of successful greylisting before the client get whitelisted (0 means,
215 # no-auto-whitelist).
216 # - max_age: number (default: 30 * 3600)
217 # lifetime of a greylist/whitelist session: ie, if a client does ne reappear during
218 # max_age seconds, the entries associated to this client are invalidated.
219 # - cleanup_period: number (default: 86400)
220 # minimum time between two cleanup of the database. You must keep in mind that cleanup
221 # is important since it remove useless entries from the database and thus help
222 # speeding up the lookups. A cleanup can take a few minutes if the database contains
225 # - if the client is whitelisted, returns whitelist
226 # - if the client is greylisted, returns greylist
227 # - if a error occured (not currently possible), returns error
229 # this filter is a recipient filter and works in RCPT state onl if no_recipient
230 # is not specified (smtpd_recipient_restrictions). If no_sender is not given, this
231 # requires a sender name, and so must be called after MAIL TO.
233 # Perform greylisting
238 path = /var/spool/postlicyd/;
242 on_greylist = postfix:DEFER_IF_PERMIT optional text;
243 on_whitelist = postfix:OK;
247 # - match: direct matching against the query fields
249 # - match_all: boolean
250 # if true, the filter won't match until all conditions
251 # are verified. If false, the filter match on the first
252 # verified condition.
253 # - condition: field_name OP (value)
254 # * the field_name is one of the field name of the query
255 # emitted by postfix. This list with description of each
256 # field is available at:
257 # http://www.postfix.org/SMTPD_POLICY_README.html
258 # postlicyd also support fields sender_domain and recipient_domain
259 # * OP is an operator. Available operators are:
260 # == field_name is strictly equal to value
261 # =i field_name is case insensitively equal to value
262 # != field_name is not equal to value
263 # !i field_name is not case insensitively equal to value
264 # >= field_name contains value
265 # >i field_name contains case insensitively value
266 # <= field_name is contained by value
267 # <i field_name is contained case insensitively by value
268 # #= field_name is empty or not set
269 # #i field_name is not empty
271 # - if the conditions are verified (according to match_all strategy), return match
272 # - if the conditions are not verified, return fail
274 # match one of the condition: "stress mode activated", "client_name contains debian.org" or
275 # "recipient is empty"
281 condition = stress == yes;
282 condition = client_name >= debian.org;
283 condition = recipient #=;
286 on_match = postfix:OK;
287 on_fail = counter:0:1:greylist;
291 # - counter: trig actions depending on the value of a counter
293 # - counter: the id of the counter to trig on (0 -> 63)
294 # - hard_threshold: minimum counter value to trig the hard_match hook
295 # - soft_threshold: minimum counter value to trig the soft_match hook
297 # - hard_match if the counter with the given id is greater or equal to hard_threshold
298 # - soft_match if the counter value is between soft_threshold and hard_threshold
299 # - fail if the counter value is below soft_match
301 # match if the counter 0 value is greater than 8, or between 5 and 7
311 on_hard_match = postfix:REJECT ${sender_domain};
312 on_soft_match = greylist;
313 on_fail = counter:1:10:match;
318 # Access policy daemon can be used at several protocol states. For each of this states,
319 # you can define a different entry point in the filtering tree. This entry points have
320 # the following format:
322 # state = filter_name;
324 # The filter_name MUST be one of the filter you previously defined.
326 # The available states are:
327 # - client_filter: called on CONNECT state (smtpd_client_restrictions)
328 # - helo_filter (or ehlo_filter): called on HELO/EHLO command (smtpd_helo_restrictions)
329 # - sender_filter: called on the MAIL FROM command (stmpd_sender_restrictions)
330 # - recipient_filter: called on the RCPT TO command (smtpd_recipient_restrictions)
331 # - data_filter: called on the DATA command (smtpd_data_restrictions)
332 # - end_of_data_filter: called on the END-OF-DATA command
333 # (smtpd_end_of_data_restrictions)
334 # - etrn_filter: called on the ETRN command (stmpd_etrn_restrictions)
335 # - verify_filter: called on the VRFY command (no postfix hook ?)
337 recipient_filter = client_whitelist;
342 # Port to which the server is bound. The default is 10000. If the port is specified as
343 # a command line parameter, the value specified on command line overides this value.
345 # You must RESTART the server to change the port (reload does not affect the port).
352 # Format of the log printed in syslog. The actual format is "${log_format}: ..."
354 # This parameter uses the same format as used to reply to postfix (${field_name} to
357 log_format = "request client=${client_name}[${client_address}] from=<${sender}> "
358 "to=<${recipient}> at ${protocol_state}";
360 # vim:set syntax=conf: