1tumgreyspf README
2Sean Reifschneider <jafo@tummy.com>
3Homepage: http://www.tummy.com/Community/software/tumgreyspf/
4Code/bugfixes: https://github.com/linsomniac/tumgreyspf
5=============================================================
6
7This is tumgreyspf, an external policy checker for the postfix mail
8server. It can optionally greylist and/or use spfquery to check SPF
9records to determine if email should be accepted by your server.
10
11It uses the file-system as it's database, no additional database is
12required to use it.
13
14LICENSE
15
16 tumgreyspf is licensed under the GPL.
17
18BENEFITS
19
20 High Accuracy
21 SPF is information published by the domain owner about what systems
22 may legitimately send e-mail for the domain. Greylisting takes
23 advantage of spam and viruses that do not follow the RFCs and retry
24 deliveries on temporary failure. We use these checks as part of our
25 mail system and have seen several orders of magnitude reduction in
26 spam, lower system load, and few problems with legitimate mail
27 getting blocked.
28
29 Low Maintenance
30 tumgreyspf requires no regular attention from the administrator to
31 remain effective.
32
33 Easy Setup
34 Installation should be as easy as installing an RPM or Debian package
35 on your system. There are few additional requirements. Extensive
36 time has been devoted to installation automation and documentation.
37
38REQUIREMENTS
39
40 Python
41 http://www.python.org/
42
43 Postfix 2.1 or above
44 http://www.postfix.org/
45
46 Optional: spfquery or pyspf
47 http://www.libspf2.org/
48 http://spf.pobox.com/downloads.html
49 http://www.wayforward.net/spf/
50
51NOTE BEFORE YOU USE TUMGREYSPF
52
53 tumgreyspf stores the greylist data in the file-system using many small
54 files. This has a few benefits, namely that you do not need to install
55 or configure any database software. It also makes you immune to to
56 database corruption issues that other greylist systems have.
57
58 However, this does mean that if not configured properly you may
59 experience extremely poor performance. There are details in one of my
60 blog posts:
61
62 http://www.tummy.com/blogs/2005/10/01/tumgreyspf-considered-useful/
63
64 However, the short answer is that you need to be careful about blocking
65 known bad recipient and sender addresses in Postfix before handing
66 messages off to tumgreyspf, and you probably should configure SPF to be
67 checked before greylisting.
68
69 If you are going to be storing your tumgreyspf database on an "ext2" or
70 "ext3" file-system, you have to be particularly careful about this
71 problem.
72
73 I have run a number of production e-mail servers using this with
74 extremely good results and absolutely no problems, however I do
75 acknowledge that there is a potential for problems. Read the above URL
76 for more details on preventing these problems.
77
78 Over the last 18 months that it's been in use, and more than a year that
79 it's been publicly available, I've received many responses saying that
80 it worked great, and one blog post reporting the above problems.
81 tumgreyspf may not be for everyone, but many people do find it useful.
82
83QUICK-START INSTALL
84
85 There is a script called "tumgreyspf-install" provided with this
86 software. I have had a report that it didn't work, so I would recommend
87 against running it, instead see the "INSTALL INSTRUCTIONS" section at
88 the end of this document for manual installation instructions. The
89 install process is fairly easy, requiring some simple changes to the
90 Postfix configuration files.
91
92LOGGING
93
94 tumgreyspf will log messages to syslog about it's activities. The
95 "debugLevel" value in "tumgreyspf.conf" can be increased to get
96 additional information to be logged. When set to a value of "0", only
97 test results (greylist/SPF hits/misses) are logged. Look for
98 "tumgreyspf" in your mail log files.
99
100TESTING
101
102 The best way to test tumgreyspf is to simulate SMTP connections, then
103 watch the logs and look in the ".../data/" directory for greylist
104 settings. This testing probably needs to be done from a remote system.
105
106 For example, suppose we have a machine "10.9.8.7" that we want to run
107 tests against our mail server "10.1.2.3":
108
109 Log into 10.9.8.7.
110 Run "telnet 10.1.2.3 25"
111 Type "helo example.com"
112 Type "mail from: <user1@example.com>"
113 Type "rcpt to: <user2@example.com>"
114
115 Note that "user2@example.com" needs to be a valid local e-mail address
116 in most cases, and that "user1@example.com" is subject to SPF blocking.
117 The first time you do this, you should receive the response:
118
119 450 <user2@example.com>: Recipient address rejected: Service
120 unavailable, greylisted.
121
122 This indicates that the greylisting is working.
123
124 Check the logs, you should see something similar to:
125
126 Aug 22 19:52:49 mail tumgreyspf[12182]: Initial greylisting:
127 REMOTEIP="10.9.8.7" HELO="example.com"
128 SENDER="user1@example.com" RECIPIENT="user2@example.com" QUEUEID=""
129 Aug 22 19:52:49 mail databytes[12184]: RCPT_INFO:
130 REMOTEIP="10.9.8.7" HELO="example.com"
131 SENDER="user1@example.com" RECIPIENT="user2@example.com" QUEUEID=""
132 Aug 22 19:52:49 mail postfix/smtpd[11992]: NOQUEUE: reject: RCPT
133 from testhost.example.com[10.9.8.7]: 450
134 <user2@example.com>: Recipient address rejected: Service unavailable,
135 greylisted.; from=<user1@example.com> to=<user2@example.com>
136 proto=SMTP helo=<example.com>
137
138 The "Initial greylisting" indicates that the record was not found in the
139 database, and that a new entry was created.
140
141 Now look in the greylist data for this entry:
142
143 ls /path/to/data/client_address/10/9/8/7/greylist/user1@example.com/user2@example.com
144
145 Wait 10 minutes (or whatever you set the greylisting time to) and try
146 it again. This time, in response to your "rcpt to" line, you should
147 get:
148
149 250 Ok
150
151 or (if you have enabled SPF blocking for your domain):
152
153 554 <user2@example.com>: Recipient address rejected: Please see
154 http://spf.pobox.com/why.html?sender=user2%40example.com&ip=10.9.8.7&receiver=spfquery
155
156 The only way to get around the SPF block is to either disable SPF
157 checking in tumgreyspf (perhaps for this IP only, see the
158 "CONFIGURATION" section below), or change your SPF configuration so that
159 it allows mail from your test machine.
160
161CONFIGURATION
162
163 NOTE: After changing "tumgreyspf.conf", you should run
164 "tumgreyspf-configtest" to ensure that it's correct. This only applies
165 to changes made to the "tumgreyspf.conf" master configuration file.
166
167 Configurations are processed from the top down, in the order specified
168 by "OTHERCONFIGS". So, settings in a top-level __default__ file will be
169 overridden if set in a configuration below that top level.
170
171 There is the __default__ file at the top level that is used as a
172 default for all decisions. If you wish to disable SPF or greylist for
173 a specific IP/subnet/sender/recipient, you simply make a __default__
174 file in a subdirectory under config matching the entity you wish to
175 match, with SPF or other checks disabled.
176
177 For example, if you want to disable SPF queries for hosts in 192.168.10.0/24:
178
179 mkdir /var/spool/tumgreyspf/config/client_address/192/168/10/
180 edit /var/spool/tumgreyspf/config/client_address/192/168/10/__default__
181
182 The __default__ file should contain:
183
184 SPFSEEDONLY=0
185 GREYLISTTIME=300
186 CHECKERS=
187 OTHERCONFIGS=
188
189 Note that for a specific IP address, the last component is a file,
190 having the same structure as the __default__. For example, to block the
191 address "10.1.2.3", you would create a file named "3" under the
192 directory ".../config/client_address/10/1/2".
193
194 The above sets CHECKERS and OTHERCONFIGS to nothing, so for that subnet
195 no checks are done. All other IP address blocks are still using the top
196 level __default__
197
198 CONFIGURATION VALUES
199
200 SPFSEEDONLY=1 will only check SPF, not use it for decisions.
201
202 GREYLISTTIME is the number of seconds to wait before allowing a
203 an incoming message. Unless you have a good reason for it, this
204 should never be more than 3 hours or it may cause warnings about
205 undeliverable e-mail to be sent.
206
207 CHECKERS is one of the set of 'spf' and 'greylist'. This is a list
208 of checks to perform. Note that they are done in the listed order.
209
210 OTHERCONFIGS specifies which configurations will be used. Note that
211 these configurations are read a maximum of once, and are applied in
212 order. If another configuration changes this list, any
213 configurations that are already done will be skipped. Allowed values
214 are:
215
216 client_address
217
218 Look for configuration values based on the remote IP address.
219 For example, if the remote host "10.9.8.7" is connecting,
220 the following will be tried:
221
222 .../config/client_address/10/__default__
223 .../config/client_address/10/9/__default__
224 .../config/client_address/10/9/8/__default__
225 .../config/client_address/10/9/8/7
226
227 envelope_sender
228
229 Split the envelope sender (not the header "From" address) into
230 "domain" and "local" parts, and look for a domain-specific
231 configuration, or a configuration specific to a particular
232 sender. So, if "user@example.com" sends a message, the
233 following files would be tried:
234
235 .../config/envelope_sender/example.com/__default__
236 .../config/envelope_sender/example.com/user
237
238 Note that special characters other than @, _ (underscore), -
239 (dash), . (dot), and + (plus) are escaped using "%DD" format,
240 where "DD" is the hex value of the ASCII character. Also note
241 that a leading "." in a domain or user is converted to "%2e",
242 to prevent the confusion of "hidden files".
243
244 envelope_recipient
245
246 This is handled the same as envelope_sender, but is the
247 envelope recipient. Note that this is not the value of the
248 "To" header in the message, but the value in the envelope.
249
250 GREYLISTEXPIREDAYS is a floating point number of days since receiving
251 the last piece of e-mail after which a greylist entry will be
252 expired. This value is used by "tumgreyspf-clean".
253
254INSTALL INSTRUCTIONS
255
256 The fastest way to install tumgreyspf is to use the package for your
257 system. This will use "tumgreyspf-install" to attempt to automatically
258 configure postfix for tumgreyspf. However, it's recommended that you
259 carefully review the Postfix configuration changes and verify that they
260 are as you expect.
261
262 INSTALLING THE SOFTWARE
263
264 This does not need to be done if you've installed the RPM/Debian
265 package.
266
267 tumgreyspf uses two directories. One is for the main tumgreyspf
268 code, and the other is for it's data/configuration. I call these
269 directories "$TGSPROG" and "$TGSDATA" in the instructions below.
270 Additionally, the user which tumgreyspf runs as is "$TGSUSER".
271
272 Run the following commands:
273
274 TGSPROG=/usr/local/lib/tumgreyspf
275 TGSDATA=/var/local/lib/tumgreyspf
276 TGSUSER=nobody
277
278 # set up directories
279 mkdir -p "$TGSPROG" "$TGSDATA"/config
280 mkdir "$TGSDATA"/data
281 chown -R nobody "$TGSDATA"/data
282 cp __default__.dist "$TGSDATA"/config/__default__
283
284 # install programs
285 cp tumgreyspf tumgreyspf-clean tumgreyspf-configtest "$TGSPROG"
286 cp tumgreyspf-install tumgreyspf-stat tumgreyspfsupp.py "$TGSPROG"
287 cp tumgreyspf.conf "$TGSDATA"/config/
288
289 # change permissions and ownership
290 chown -R "$TGSUSER" "$TGSDATA"
291 chown -R root "$TGSPROG" "$TGSDATA"/config
292 chmod 700 "$TGSDATA"/data
293 chmod -R 755 "$TGSDATA"/config
294
295 If you have changed the values of TGSPROG or TGSDATA, you will need
296 to change the the paths in the following files. In the .conf file,
297 you will need to review the whole file, the other files have the
298 required changes isolated to the top of the file:
299
300 "$TGSDATA"/config/tumgreyspf.conf
301 "$TGSPROG"/tumgreyspfsupp.py
302 "$TGSPROG"/tumgreyspf
303 "$TGSPROG"/tumgreyspf-clean
304 "$TGSPROG"/tumgreyspf-stat
305
306 CRONTAB
307
308 WARNING: Make *SURE* you do this step, as not cleaning out the
309 database may result in resource exhaustion in your file-system.
310
311 Next, you will need to add a cron job which runs daily to clean out
312 the the expired SPF entries. On many systems, there is a
313 "/etc/cron.d" directory, and the following can be be used to add an
314 entry:
315
316 echo 0 0 * * * $TGSUSER $TGSPROG/tumgreyspf-clean \
317 >/etc/cron.d/tumgreyspf
318
319 Otherwise, you will need to use "crontab -e -u $TGSUSER" to add the
320 following entry:
321
322 0 0 * * * $TGSPROG/tumgreyspf-clean
323
324 Note that you cannot use the literal "$TGSPROG", you will have to
325 replace it with whatever the real value is.
326
327 CONFIGURING POSTFIX
328
329 WARNING: In these examples, you cannot use the literal "$TGS"
330 variables. You will have to manually replace the appropriate values,
331 they are simply there to mark where the changes need to be.
332
333 Add to your postfix master.cf:
334
335 tumgreyspf unix - n n - - spawn
336 user=nobody argv=$TGSPROG/tumgreyspf
337
338 Next, main.cf must be configured so that "smtpd_recipient_restrictions"
339 includes a call to the tumgreyspf policy filter. If you already have
340 a "smtpd_recipient_restrictions" line(s), you can add the following line
341 anywhere after the line which reads "reject_unauth_destination".
342
343 check_policy_service unix:private/tumgreyspf
344
345 WARNING: It's very important that you have
346 "reject_unauth_destination" before the "check_policy_service". If
347 you do not, your system may be an open relay.
348
349 So, for example, a minimal "smtpd_recipient_restrictions" may look like:
350
351 smtpd_recipient_restrictions = \
352 reject_unauth_destination, \
353 check_policy_service unix:private/tumgreyspf
354
355 Please consult the postfix documentation for more information on
356 these and other settings you may wish to have in the
357 "smtpd_recipient_restrictions" configuration.
358
359 You will also need to have a line in the main.cf which reads:
360
361 tumgreyspf_time_limit = 3600
362
363 SPF INSTALLATION
364
365 NOTE: SPF is optional, but it's use, particularly it's use before
366 greylisting, will help reduce spam and will reduce the size of the
367 greylist database. This may prevent or lessen the problems mentioned
368 in the "NOTE BEFORE YOU USE TUMGREYSPF" section.
369
370 tumgreyspf can also use an external SPF program to do SPF lookups.
371 You can use any of the following:
372
373 Download libspf2 from http://www.libspf2.org/ untar and run
374 "./configure; make", then copy "src/spfquery/spfquery_static" to
375 "$TGSPROG".
376
377 The Mail::SPF::Query Perl module includes a "spfquery" package
378 that tumgreyspf can be used with. Once installed, change your
379 tumgreyspf.conf file to list the path to "spfquery".
380 Information on downloading this package is available
381 from http://spf.pobox.com/downloads.html
382
383 The Python pyspf package from http://www.wayforward.net/spf/ can
384 also be used. If this is installed, tumgreyspf will automatically
385 use it.
386
387COMMON PROBLEMS
388
389 SPF checks need to be bypassed for relays for the domain, such as
390 secondary MX servers. Putting an mx entry in your SPF TXT record is
391 not sufficient to do this, as that only covers your *OUTGOING* e-mail.
392 Incoming e-mail is controlled by the senders SPF record, which probably
393 doesn't list your secondary MX hosts. :-)
394
395 One way of bypassing this check would be to ensure that MX servers are
396 listed in mynetworks, and that permit_mynetworks is ahead of the call to
397 tumgreyspf.
398
1I have run tests of this code on two machines to determine the performance
2it is capable of. The first is my development laptop, a 1.2GHz Celeron
3(with cpufreq pushing it down to 800MHz), running on the JFS filesystem.
4The other is our mail server, a 2.66Ghz P4 running on the XFS filesystem
5running on a two-drive RAID-1 storage system. This RAID array was two
67200RPM Hitachi 80GB SATA drives using a 3ware controller.
7
8Both machines had the "safe writing" disabled for maillog in syslog.conf
9(by prefixing the maillog path name with a "-").
10
11My test data was 50,756 greylist requests culled from the log files
12accumulated over a few days of actual traffic. The test used greylisting
13first, and then SPF if greylisting did not block. I believe that in most
14cases greylisting would be blocking.
15
16On the development laptop, it took 5 minutes 1 second, for an overall rate
17of 168 RCPTs per second.
18
19On the mail server, it took 2 minute 12 seconds, for an overall rate of 384
20RCPTs per second.
21
22These both seemed to be using 100% CPU time. Obviously, with other mail
23processing going on there will be less CPU and disc bandwidth available for
24tumgreyspf. However, greylisting is blocking well over 80% of incoming
25messages right now on our server. Thus, there are around 5x fewer mesages
26being processed, leading to much more overall available resources.
27