Email Sieve Filtering with Simplelogin

By Brad Lazaruk, Sat 10 September 2022, modified Sat 10 September 2022, in category Note to self

sieve filtering, simplelogin

Recently I started using Simplelogin. A wonderful service, it lets you create temporary email addresses and disable or delete them when you don’t want them anymore.

I also get to redirect all my domain email through there so I can use throwaway email addresses with my own @lazaruk.com domain.

But on the downside, once I turned it on, all my email filters broke. Most of them were based on sender email addresses or domains in the SMTP header from field, and with Simplelogin intercepting all the emails the addresses all changed and the domain for all email reaching me is now simplelogin.co.

I’ve had the same email address for 25 years, and I have no intention of disabling it. So for those spammers that are sending to my main address I need to filter their mail after Simplelogin has forwarded it.

This gave me the reason to finally figure out the Sieve email filtering that my mail service provider has.

In the end I was able to work out three filters: one for the name that the sender included in their email, one for their original from address, and another for the Message-ID.

To-Do: I’m sure there are too many commands in the require statements. I still need to go through those and reduce them to the minimum required.

Name

By far the easiest to implement, probably the most useful for filtering people that I know, and also the least likely to be useful for filtering spammers. Spammers will easily change the “name” that they appear to send their email from. On the other hand, my friends “Bob McGoodGuy” and “Alice SeemsFriendly” always configure their email accounts to send their name as the from field.

So to file emails from my friends, I use this:

require ["include", "environment", "variables", "relational", "comparator-i;ascii-numeric"];
require ["fileinto"];

if allof (address :all :comparator "i;unicode-casemap" :contains "From" ["Bob McGoodGuy", "Alice SeemsFriendly"]) {
    fileinto "Mail from friends";
}

While to reject emails from “Eve Real-Person”, who just won’t leave me alone, this does the trick:

require ["include", "environment", "variables", "relational", "comparator-i;ascii-numeric"];
require ["reject"];

if allof (address :all :comparator "i;unicode-casemap" :contains "From" "Eve Real-Person") {
    reject "550 5.1.1: Recipient address rejected: Address does not exist";
}

From: Address

Now some spammers will fiddle with their from name, but leave the email address they are sending from alone. Also, this filter works for catching those distribution lists that are not respecting unsubscribe requests. They often send from the same addresses or domains and so are easy to filter. It can also be used to reject entire domains.

But as I noted above, the from field is always changed by Simplelogin. You can set it up so that the “name” portion is retained and still comes through in the from field. But the address is always changed.

To resolve this, I configured Simplelogin to include to original sender in the email headers (just a click in their settings). And now I just have to have my sieve filter scan the X-Simplelogin-Envelope-From field in the header and compare the original name and email address information with those that I want to filter.

All this also has the nice effect of surviving and functioning if I choose to change the way Simplelogin presents the original sender name to me. There are a few options, but changing them won’t break these sieve filters.

require ["include", "environment", "variables", "relational", "comparator-i;ascii-numeric"];
require ["imap4flags", "reject"];

if anyof (header :is "X-Simplelogin-Envelope-From" ["daily-list.ext", "newsletter@daily-list.ext", "idiot06@yahoo.ca", "Spammer McSpammyPants"]) {
    reject "550 5.1.1: Recipient address rejected: Address does not exist";
}

Message-ID

The most complicated so far is for those spammers that change the name and email domain in the header from field. This, of course, is most of them.

Now I’m sure this will be an evolving battle.

Even if their names and domains are forged, they still need to send the emails from somewhere. And those spammers that are concerned about not wasting their time and resources will put in legitimate addresses to catch bouncebacks from mailboxes that no longer exist. That way when they receive a “550” error that my mailbox doesn’t exist they stop sending mail to that address.

I know that this field is set by the spammers so they can technically forge it too, but right now the Message-ID field is giving me enough to filter them with.

Checking into the headers of the recent batches of spam, I noted they were coming from a few specific domains. So I added a filter to scan the Message-ID field and trigger if those domains are found.

require ["include", "environment", "variables", "relational", "comparator-i;ascii-numeric", "imap4flags", "reject"];

if anyof (header :contains "Message-Id" ["@spammer-domain.com", "@alter.spammers.co", "@another.spammer.net"]) {
    reject "550 5.1.1: Recipient address rejected: Address does not exist";
}

And voila. Regardless of the name and email address that the spammer uses, this does the job in rejecting messages that include those domains in the Message-ID.

So for so good!