ProcmailFiltering
From Apis Networks Wiki
Contents |
Some useful things to do with procmail filters
Filtering mail for different domains into different folders
One of the many useful things that you can do with procmail is to use it to filter messages to different folders or forward to different locations based on the recipient address. This can be particularly useful if you're using the Multiple Domain Manager to host several shared domains (meaning that email to multiple users will come in to the some "master" domain).
Let's assume that you are hosting three domains: dom1.com, dom2.com, dom3.com. Further, let's assume that you have a user "chris" who receives email at each of those domains. Functionally, as far as Chris is concerned, each of those domains is "different", so Chris has decided that the email for each domain needs to be handled separately. Further, Chris is using SpamAssassin, so email that's flagged as spam should be filtered out to a spam mailbox for further review. Finally, we'll assume that all mail folders will be located under Chris's home directory in the mail subdirectory, /home/chris/mail/ (or, more simply, ~/mail).
While there are some more sophisticated techniques (such as nesting mentioned in the Procmail explanation), we're going to keep this pretty simple. So, the first rule in our .procmailrc will get rid of the spam:
:0 * ^X-Spam-Flag:.*YES mail/spam
This says that any mail with the Spam flag set will be sent to the spam mailbox. Note that it's not necessary to specify the full directory prefix, as procmail assumes that relative (versus absolute) directory references are relative to the users home directory.
The next thing that we want to do is to start breaking out the mail for each of the domains and filing it as appropriate. The following method isn't foolproof, but it is pretty simple, especially if you just have a limited number of shared domains.
:0 * ^TO@dom1.com mail/dom1 :0 * ^TO@dom2.com mail/dom2 :0 * ^TO@dom3.com mail/dom3
What these lines say is that if any part of the "To:" field contain dom1.com (or dom2.com, etc.), then file that message in a folder named "dom1" (or dom2, etc.). One problem with this is that if the message comes in to the user because of participation in a mailing list, where often the To: field is simply the list address, then the message won't be filed properly. There are other ways around this, but this will work for the simple cases and can be used as a basis for more advanced experimentation. Another possible problem is that this particular check will fail if a [subdomain] is used (e.g., sub1.dom2.com), but for many users this won't be an issue, and there are ways around this as well.
Here's another interesting case: What if Chris only wanted email to one particular domain to stay on the server, but have everything else get forwarded elsewhere? Something like this is an easy (though not perfect) way to do this:
:0 * !^TOdom3.com !someone@somewhereelse.com
This says that if mail is not addressed to a user in dom3.com, then forward it to someone@somewhereelse.com. Otherwise, it will stay in the default inbox.
Removing catch-all functionality on a single domain
Let's say you have a few domains setup in the Multiple Domain Manager, with a catch-all alias to receive all e-mail sent to your domains. One particular domain should never receive e-mail, but as it's part of your account via the MDM, it implicitly receives e-mail. Procmail solves this dilemma nicely.
Expounding on the previous example, we can modify the recipe to delete the e-mail (deliver to /dev/null), instead of sticking it in a normal file-based mailbox.
:0 * ^TO@dom1.com /dev/null
And that's all there is to it!
Things to be careful about
If you edit your .procmailrc file directly from a shell using an editor like vi, vim, or pico, this won't be an issue, but if you edit on a system that uses \r\n (return + newline) between lines of a text file (most notably, Windows does this; *nix variants such as Linux, OpenBSD, and the like don't), be sure that when you transfer your file to the system that the transfer program you're using knows that it's a text file. While programs like WinSCP and SmartFTP have an "automatic" setting to do this conversion during transfer, they can't always tell for certain if a file contains text, especially if it doesn't end in a well-known file extension, like .txt or .html. So, to be on the safe side, make sure that you explicitly tell the transfer program to use text mode for the transfer.
