mikejsavage.co.uk / blog

RSS feed

21 Jan 2020 / Daily Mail

Alternatively titled: least effort self hosted disposable mail

Email spam is widely considered to be a solved problem. If you open your inbox this is immediately obviously false. Scams and outright virus mail are long gone, but the spammers have adapted. Customer success mails, newsletters after you unchecked the box saying I want newsletters, terms of service updates when you haven’t logged in for five years.

Unfortunately, this new problem is unsolvable. Also, the spammers buy DoubleClick Ads and run Google Analytics and let you sign in with Google on their websites, which are best viewed in Google Chrome.

My first idea was to drop any email containing an unsubscribe link, or ( "terms of service" || "privacy policy" ) && "update", but that seems like it might have too many false positives.

My second idea was to use the date as an email address and drop any emails sent on the wrong day. So you register with like daily21012020@ and they can only email you on the same day. The end result is like a tempo mail provider, but it’s nicer because there is no UI or software. You just type the date in and emails go to your normal inbox.

I did briefly consider making a service out of this but everyone would immediately blacklist the domain and then it turns into a normal temp mail provider which you can get for free so whatever.

OpenSMTPD is great so the implementation is trivial. Drop this in /usr/local/libexec/smtpd/filter-dailymail as an executable:

#! /usr/bin/env lua

local function result( version, sid, token, data )
        if version == "0.4" then
                token, sid = sid, token
        end
        print( ( "filter-result|%s|%s|%s" ):format( sid, token, data ) )
end

for line in io.lines() do
        if line == "config|ready" then
                print( "register|filter|smtp-in|rcpt-to" )
                print( "register|ready" )
                break
        end
end

for line in io.lines() do
        local version, sid, token, rcpt = line:match( "^filter|([^|]*)|[^|]*|smtp%-in|rcpt%-to|([^|]*)|([^|]*)|(.*)" )
        if rcpt then
                local daily = rcpt:match( "^daily(%d+)@" )
                if daily and daily ~= os.date( "%d%m%Y" ) then
                        result( version, sid, token, "reject|550 Email causes cancer" )
                else
                        result( version, sid, token, "proceed" )
                end
        end
end

Then in smtpd.conf:

filter dailymail proc-exec "filter-dailymail"
filter rspamd proc-exec "filter-rspamd"
filter incoming-filters chain { rspamd, dailymail }

listen ... filter incoming-filters

action deliver_local maildir virtual { "@" => mike } # you probably also want something like this