Procmail + SpamAssassin

Setting up procmail and spamassassin on your DreamHost Virtual Private Server is really quite easy. Take it step-by-step and you should not have any problems. The solution does not scale well for many users, but if you only have a couple of email users on your that you want to have this feature, then set aside a couple of hours and you should be good to go. This tutorial will provide two email solutions that will give you bullet-proof spam protection. One solution will process your email and then forward it to gmail for ultimate reading. The other solution will leave the email on the DreamHost server for reading.

The first thing to understand is exactly how your mail will be processed. You must have a domain that is fully hosted by DreamHost (on a VPS). Add an email account that is not to be hosted by gmail. We shall call that account user@mydomain.com. Under normal circumstances, that users mail would come in and the user would set up mail clients (either POP or IMAP) to read that mail. In this case, we will eventually need to forward all of this users email to another email address (more on that in just a second), so your user will not be able to directly set up an email client to retieve that mail.

The next thing you will need is a shell user that will serve as the account for processing that one user's email with procmail and spamassassin. Create a shell account that can be related to that user, such as firstnamelastname. The trick here is that all shell users have an email account that goes with that account. The address for that shell user is username@ps#####.dreamhostps.com, where ps##### is the server name of your vps. Now, be very careful to never, ever give this email address out to anyone. The whole point is, you want to receive email at user@mydomain.com, right? It's not anything bad will happen if anyone gets that email address, but it won't be the normal way for you to receive email. In fact, if someone were to send an email to that address, you would still get it. You might want to consider writing a rule that looks for mail sent directly to that address, because if it is, then it is probably spam due to the fact that they scraped it from an email header. We will assume that you created an account named firstlast on box ps99999 (DreamHost will eventually get that big, right?)

So, you have your shell user set up and your email account set up. Now go into the settings for that email account and set it up to auto-forward all incoming email to username@ps###.dreamhostps.com.

Next, log into your shell account, firstlast on ps99999. Create a file in your home directory, which will be /home/user, or /home/firstlast in this case. Create a file named ".forward.postfix" (note the dot at the beginning) and that file will have exactly one line in it: "|/usr/bin/procmail". To create the file, just type firstlast@ps99999:~$ pico .forward.postfix and then type in, including the quotes "|/usr/bin/procmail" Press ctrl-x to exit out, be sure to save it (answer "yes" when prompted)

By the way, pico is a nice text editor if you are afraid of emacs or vi. If you know what emacs and vi are, then you already know what you want to use for editing text.

Also, while you are logged in, note that you have a directory named Maildir. This is where your mail will go if you choose to keep your email stored on the DreamHost servers. After being processed by procmail and spamassassin, it will be filed in the "new" directory under Maildir. If you chose to forward your email to Gmail, then you won't have any email in the Maildir direcotries, except maybe an ocasional bounce message under unusual circumstances.

Next, you need to write a .procmailrc file in your home directory. Use pico again to create it firstlast@ps99999:~$ pico .procmailrc You might want to start off with setting a few variables:

DEFAULT=$HOME/Maildir/ MAILDIR=$HOME/Maildir PMDIR=$HOME/Procmail LOGFILE=$PMDIR/log SHELL=/bin/sh SENDMAIL=/usr/sbin/sendmail FORMAIL=/usr/bin/formail LOG=" ************************************************************************** " VERBOSE=YES :0c:${PMDIR}/copy.lock $HOME/email_saves
 * 1) place a bunch of stars between indivual messages in the log, to make it easier to read
 * 1) this rule makes a copy of every incoming message and puts it in a directory called "email_saves"
 * 2) this way if something goes wrong below, you will always have this backup copy. Be sure to create
 * 3) the email_saves directory first

Now you might want to send the message through spamassassin. :0 * < 256000 { :0fw:${PMDIR}/spamassassin.lock | spamassassin -D --prefspath=${HOME}/.spamassassin/user_prefs }

Here, you can see that the spamassassin is called with an argument to look for a user_prefs file in the .spamassassin directory. Read the spamassassin documentation for typical settings for spamassassin that can be set there. One setting might be to include a whitelist file: include /home/firstlast/.spamassassin/whitelist

In the whitelist there will be entries such as whitelist_from *@dreamhost.com whitelist_from *@*dreamhost.com whitelist_from mybestfriend@theirdomain.com

The last step is delivering messages. First, how to deliver messages to Gmail using their "plus addressing" feature (which, by the way is also available at DreamHost)

This recipe will check to see if spamassassin found the message to be spam, and it will also check to see if the sender was in the whitelist.

{ #add the X-Loop header to all emails that are being delivered. #This way, if it gets kicked back to us, the step above will catch it. :0fw:${PMDIR}/formail.lock | /usr/bin/formail -A "X-Loop: mydomain.com" #If spamassassin said it was spam, then we will deliver it to #the special address. Gmail can easily filter this and you #can do whatever you want with it from there. :0 * ^X-Spam-Flag: YES !mygmailaddress+SPAM@gmail.com #Was this email processed by spamassassin? Remember, some messages #that are too big are not, and therefore will not have any #additional spamassassin headers. :0E * ^X-Spam-Checker-Version: {   #If the user was in the whitelist, then send it to the regular gmail address :0   * ^X-Spam-Report:.*USER_IN_WHITELIST !mygmailaddress@gmail.com #otherwise, send it to the notinwhitelist plus address #this allows you to easily see who is not in the whitelist. #You can then decide if you want to add them to the whitelist or not. :0E !mygmailaddress+notinwhitelist@gmail.com } #this step is executed only for messages that were not processed by spamassassin. #In this case, send it to the regular gmail address. :0E !mygmailaddress@gmail.com } :0E /dev/null
 * 1) first, make sure the email isn't bouncing back and forth. VERY IMPORTANT!
 * 2) Look to see if there is an X-Loop: mydomain.com header.
 * 3) If there is, for some reason, procmail has already
 * 4) seen this email once before and therefore, we need to put an end to the bouncing.
 * 1) if a message comes in and it does have the X-Loop header, then we have
 * 2) already seen it (it's bouncing). Vaporize it.

With these plus address, you can easily set up Gmail filters. For instance, to look for messages tagged as SPAM, create a filter that "Has the words" and fill in the box with "deliveredto: mygmailaddress+spam@gmail.com". Then for the actions, have it do whatever you want. Perhaps "skip the inbox", add a label such as "Spammy", or "Delete it". Depending on your labels that you have in place, you could write all kinds of procmail rules to automatically label them as they enter gmail's system. Ain't it great?

One important note. If you are forwarding your mail to a gmail account or something like that (such as yahoo or msn), note that if you are testing your procmail + SpamAssassin installation by sending yourself emails from those same accounts, most likely you will not see those emails in your inbox. That's because they have systems in place to make sure emails aren't stuck in continuous loops (remember that X-Loop: header above???). Anyway, the net result is that even though procmail will indeed process the incoming email, it won't make it back into your gmail/yahoo/msn account. So, try testing using your work email account to send the emails.

Finally, if you want to keep your email on the Dreamhost server, and set up email clients to read email that way, simply replace the delivery lines with destinations such as instead of

!mygmailaddress+SPAM@gmail.com

you would use $MAILDIR/.Spam

And that would deliver the message into the .Spam directory under Maildir (better create it first--use an IMAP email client to create a folder under Inbox. Then look for it here).

Now that everything is working, you might want to look at activating some of the other plugins, such as Razor2, URICountry, and many others.