I have for a long time been borderline-obsessive about fighting spam with my personal e-mail. Back in the days when I ran my own e-mail system based on Hula (R.I.P.), I had a fairly complex implementation of Spamassassin that worked quite well. When I switched to Google Apps for my home domain several years ago, I started using Postini for spam prevention. It does work pretty well once you tweak it to strike the right balance between too many false positives, and too much spam getting through.
The one thing I missed from my old homegrown setup was the ability to move a message into a “blacklist” folder and have it learned as spam and added to the blacklist by Spamassassin.
One Saturday morning, I decided to do a little research to figure out if Postini had the requisite facilities to allow for this. Lo and behold, I discovered postini-ezcommand-shell.
What follows is a tutorial on setting up a “blacklist” folder in your e-mail that will let you drag spam into the folder and have Postini blacklist the sender automatically.
- You will need some sort of shell account with the ability to run bash and perl scripts, and schedule cron jobs. I use DreamHost.
- fetchmail must be available, or you will have to download and compile it with SSL support.
- Create a folder in your e-mail hierarchy called “Blacklist”. This should work with any e-mail provider/client, but I am using Gmail along with Mail.app on the Mac. You simply need the ability to drag and drop e-mails from your inbox or other folder, to the Blacklist folder.
- All of the scripts and commands below use conventions like “/homedir”. Be sure to adjust all paths for your environment.
Initial Deployment Steps
- Download postini-ezcommand-shell.
- Create a directory called “postini” in your shell account
- Unzip postini-ezcommand-shell into the postini directory in your shell account
- You will need two shell scripts as follows, both placed in the postini directory, plus a .fetchmailrc:
- proc-postini.sh is the calling script that will eventually be scheduled with cron
- postiniblacklist.sh is a custom MDA for fetchmail, which will actually add the sending address to your blacklist
# the -s in the following line can be removed for initial testing, and -v can be added for verbose logging /homedir/fetchmail --invisible -a -s -n -K -F -f /homedir/postini/.fetchmailrc -m '/homedir/postini/postiniblacklist.sh %F' exit 0
# read the whole message through and discard it cat - >> /dev/null # add sender address to the blacklist - assumes makeauth has been run already /usr/local/bin/perl -I/homedir/postini/ /homedir/postini/ezcommand.pl modifyuser firstname.lastname@example.org, blocked_senders=+$1 exit 0
.fetchmailrc (example for Gmail)
poll imap.gmail.com protocol IMAP user "email@example.com" password 'passwordhere' folder 'Blacklist' ssl
The first script fetches any mail in your Blacklist folder and passes it directly to the postiniblacklist.sh script, with the sender’s address as a command line argument. Because fetchmail expects the second script to be a delivery agent, we have to make it handle the entire message, even though we don’t care about it because we already know the sender’s address. cat’ing it to /dev/null accomplishes this. Without that step, larger messages will result in the MDA exiting before the whole message is passed, which will cause fetchmail to exit with an error and the whole thing will fail. Finally, postiniblacklist.sh then calls ezcommand.pl to add the address to the blacklist.
First, we have to create an authentication.txt file, which will be used by postini-ezcommand.pl each time it is run.
First, you will need to log in to Postini and set or determine your EZCommand Shared Secret.
Here’s how you find an EZCommand Shared Secret.
- In the Administration Console, go to Orgs & Users > Orgs.
- Choose the organization from the Choose Org pull-down, or click the name in organization list.
- In the Organization Management page, scroll to the Organization Settings section and click General Settings.
- On the General Settings page, enter the shared secret in the EZCommand Shared Secret field and click Save.
- Add shared secrets to other organizations that contain administrators who will submit EZCommands. With EZCommand, the shared secret must be set for each organization; the shared secrets are not inherited down the organization hierarchy.
Also, take note of the Postini host you are logged into. For example, ac-s7.postini.com.
Test postini-ezcommand-shell by changing to your postini directory and trying the makeauth command as follows:
perl ezcommand.pl makeauth <admin>, <secret>, <hostname>
The following is how I have to call it on my system, to ensure the Postini libs are included. You will also need full paths on everything to use it with cron later. For example:
/usr/local/bin/perl -I/homedir/postini /homedir/postini/ezcommand.pl makeauth firstname.lastname@example.org, sharedsecrethere, ac-s8.postini.com
If this succeeds, you should have a credentials.txt file in your postini directory. You should not have to do this step again, as these credentials will be used every time you run ezcommand.pl in the future. However, it only seems to look for credentials.txt in the current directory, so you will need to make sure you are actually in the postini directory every time you run ezcommand.pl (important for cron later).
Now you are ready to try processing some spam. Place a junk e-mail or two in your Blacklist folder in your e-mail client, change to your postini directory, and run proc-postini.sh.
If everything is working, you should see something like:
Success. Modified email@example.com: Set blocked_senders to +firstname.lastname@example.org.
Implementation in Cron
The only thing left to do is to schedule the process to run periodically via Cron. Here is a sample crontab file that will run it hourly:
# Postini-blacklist MAILTO="user@domain" # Optional, for results to be e-mailed to you. */60 * * * * cd /homedir/postini; /homedir/postini/proc-postini.sh
Please let me know if you find any inaccuracies, or if anything needs to be clarified. Thanks!