Reload strlist and iplist resource-files only when needed.
[apps/pfixtools.git] / example / postlicyd.conf
1 # POSTLICYD configuration
2 #
3 # Postlicyd configuration contains:
4 #  - a set of filter definition
5 #  - the entry point in the filters for each smtp states
6 #
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
10 #           format:
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.
17 # eg:
18 #  The following format are equivalent:
19 #   (1) this is a str\
20 #   (1)    ing
21 #
22 #   (2) "this is a string"
23 #
24 #   (3) "this " "is a "
25 #   (3) "string"
26 #
27 # Most of the configuration use a format:
28 #     Token = String ;
29 #
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.
33
34 # FILTER DEFINITION
35 #
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
38 #    behaviour)
39 #  - a type
40 #  - a list of type-specific parameters
41 #  - a list of hooks (on_hookname)
42 #
43 # Format:
44 #  A filter look likes that:
45 #
46 #  filter_name {
47 #    type = type_name;
48 #    param1 = parameter value 1;
49 #    ...
50 #    on_hook1 = action1;
51 #    on_hook2 = action2;
52 #    ...
53 #  }
54 #
55 # Hooks:
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.
58 #
59 #   A hook action has the format: (counter:id:incr:)?(filter_name|postfix:ACTION)
60 #
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.
68 #
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}
73 #
74 # eg:
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
79 #
80 # Filter:
81 #   Current defined filter types are:
82 #     - iplist: match the client_address against one or more blacklist files from a rbl
83 #        Parameters:
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
87 #             score of the IP
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
97 #        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
104
105 # Lookup in a rbl
106 spamhaus_and_abuseat {
107   type   = iplist;
108
109   # configuration
110   file   = lock:10:/var/spool/postlicyd/rbl.spamhaus.org;
111   file   = lock:1:/var/spool/postlicyd/cbl.abuseat.org;
112   soft_threshold = 1;
113   hard_threshold = 11;
114
115   # hooks
116   on_soft_match = greylist;
117   on_hard_match = postfix:REJECT optional text;
118   on_fail       = postfix:OK;
119   on_error      = postfix:DUNNO;
120 }
121
122
123 #     - strlist: match strings from the query against a list of list.
124 #        Parameters:
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.
135 #               e.g.:
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
139 #                 postmaster emails.
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"
150 #             typed fields.
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,
161 #                         recipient_domain
162 #              * email fields: sender, recipient
163 #             No space is allowed in this parameter.
164 #        Return value:
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
170 #        State:
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
177
178 # Whitelist some clients
179 client_whitelist {
180   type  = strlist;
181
182   # configuration
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;
186
187   # hooks
188   on_hard_match = postfix:OK;
189   on_fail       = spamhaus_and_abuseat;
190 }
191
192
193 #     - greylist: greylister
194 #        Paramters:
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 #         Return value:
220 #           - if the client is whitelisted, returns whitelist
221 #           - if the client is greylisted, returns greylist
222 #           - if a error occured (not currently possible), returns error
223 #         State:
224 #           this filter is a recipient filter and works in RCPT state onl if no_recipient
225 #           is not specified (smtpd_recipient_restrictions). If no_sender is not given, this
226 #           requires a sender name, and so must be called after MAIL TO.
227
228 # Perform greylisting
229 greylist {
230   type   = greylist;
231
232   # configuration
233   path   = /var/spool/postlicyd/;
234   prefix = greylist_;
235
236   # hooks
237   on_greylist  = postfix:DEFER_IF_PERMIT optional text;
238   on_whitelist = postfix:OK;
239 }
240
241
242 #     - match: direct matching against the query fields
243 #        Parameters:
244 #           - match_all: boolean
245 #             if true, the filter won't match until all conditions
246 #             are verified. If false, the filter match on the first
247 #             verified condition.
248 #           - condition: field_name OP (value)
249 #             * the field_name is one of the field name of the query
250 #              emitted by postfix. This list with description of each
251 #              field is available at:
252 #               http://www.postfix.org/SMTPD_POLICY_README.html
253 #              postlicyd also support fields sender_domain and recipient_domain
254 #             * OP is an operator. Available operators are:
255 #                == field_name is strictly equal to value
256 #                =i field_name is case insensitively equal to value
257 #                != field_name is not equal to value
258 #                !i field_name is not case insensitively equal to value
259 #                >= field_name contains value
260 #                >i field_name contains case insensitively value
261 #                <= field_name is contained by value
262 #                <i field_name is contained case insensitively by value
263 #                #= field_name is empty or not set
264 #                #i field_name is not empty
265 #         Return value:
266 #           - if the conditions are verified (according to match_all strategy), return match
267 #           - if the conditions are not verified, return fail
268
269 # match one of the condition: "stress mode activated", "client_name contains debian.org" or
270 #                             "recipient is empty"
271 match {
272   type = match;
273
274   # configuration
275   match_all = false;
276   condition = stress == yes;
277   condition = client_name >= debian.org;
278   condition = recipient #=;
279
280   # hook
281   on_match = postfix:OK;
282   on_fail = counter:0:1:greylist;
283 }
284
285
286 #    - counter: trig actions depending on the value of a counter
287 #       Parameters:
288 #          - counter: the id of the counter to trig on (0 -> 63)
289 #          - hard_threshold: minimum counter value to trig the hard_match hook
290 #          - soft_threshold: minimum counter value to trig the soft_match hook
291 #       Return value:
292 #          - hard_match if the counter with the given id is greater or equal to hard_threshold
293 #          - soft_match if the counter value is between soft_threshold and hard_threshold
294 #          - fail if the counter value is below soft_match
295
296 # match if the counter 0 value is greater than 8, or between 5 and 7
297 counter {
298   type = counter;
299
300   # configuration
301   counter        = 0;
302   hard_threshold = 8;
303   soft_threshold = 5;
304
305   # hook
306   on_hard_match = postfix:REJECT ${sender_domain};
307   on_soft_match = greylist;
308   on_fail       = counter:1:10:match;
309 }
310
311 # ENTRY POINTS
312 #
313 # Access policy daemon can be used at several protocol states. For each of this states,
314 # you can define a different entry point in the filtering tree. This entry points have
315 # the following format:
316 #
317 #  state = filter_name;
318 #
319 # The filter_name MUST be one of the filter you previously defined.
320 #
321 # The available states are:
322 #  - client_filter: called on CONNECT state (smtpd_client_restrictions)
323 #  - helo_filter (or ehlo_filter): called on HELO/EHLO command (smtpd_helo_restrictions)
324 #  - sender_filter: called on the MAIL FROM command (stmpd_sender_restrictions)
325 #  - recipient_filter: called on the RCPT TO command (smtpd_recipient_restrictions)
326 #  - data_filter: called on the DATA command (smtpd_data_restrictions)
327 #  - end_of_data_filter: called on the END-OF-DATA command
328 #    (smtpd_end_of_data_restrictions)
329 #  - etrn_filter: called on the ETRN command (stmpd_etrn_restrictions)
330 #  - verify_filter: called on the VRFY command (no postfix hook ?)
331
332 recipient_filter = client_whitelist;
333
334
335 # SERVER PORT
336 #
337 # Port to which the server is bound. The default is 10000. If the port is specified as
338 # a command line parameter, the value specified on command line overides this value.
339 #
340 # You must RESTART the server to change the port (reload does not affect the port).
341
342 port = 10000;
343
344 # vim:set syntax=conf: