Forwarding email to your domain with generic email naming pattern (update 2020)

in #haraka5 years ago (edited)

This post happens 2 years after my previous post.

In the previous post, I've shown how to install a mail server on a domain public.com that's forwarding emails in the form fwd.facebook@public.com (in fact any: fwd.*@public.com) to your own private email address.

In order to do this, I've shown how to install a Haraka SMTP server and configure it. At the time, DKIM and SPF were new technologies, and spammer were using them better than regular server so there were efficient in classifying SPAM from HAM.

Since those last 2 years, the situation evolved and now many SMTP server will use DKIM and SPF to trigger a DMARC assertion and if it fails, your forwarded message will be classified as SPAM.

This post contains updated instruction to evolve your SMTP server configuration so it supports DKIM signature and use SRS technology to maintain DMARC validation status.

Glossary

If all those terms seems gibberish to you, it's because they are.

In short:

  • DKIM answers the question "Is the server sending this email legitimate and not spoofed ?"
  • SPF answers the question "Who is allowed to send an email for this domain ?"
  • DMARC answers the question "What should I do if the email is not received by one of the allowed server or if the server sending the email is illegitimate ?"
  • SRS answers the question with "Fuck SPF, you're too restrictive."

So, in Web2020, domain sending emails likely have a SPF policy telling only mail.domain.com or gmail.com can send an email with @domain.com at the end.

They also are signing some of the email's headers with a private key and publish their public key in the DNS record so that spammer can not forge a valid email from this domain since he does not have the private key (DKIM).

Finally domain also have a clé-de-voute for protection telling final SMTP receiver if either SPF or DKIM is broken, reject the email, it's SPAM

How to have a working forwarding in that case

The above rules seems very strict and they usually are. However, forwarding email is a legitimate feature and as such must work somehow with the technologies above.
Refering to the usual RFC standard, forwarding is possible provided:

  1. No modification is allowed on the email's essential part (typical headers like From, To, Date...)
  2. The distribution chain must be verified and verifiable.

In order to do that, one must ensure that an email is not modified and sign each email with a verified signature.
However, if you remember correctly, we are trying to change an email send to fwd.bob@domain.com to me@secretemail.com. How can we achieve this without breaking rule #1 above ?

Answer: With SRS.
SRS allows to change the email's Envelope From address in the form mail@sender.com to SRS=glibberish=source.com@domain.com so that the domain to check validity against is not sender.com but your SMTP's server domain.

That way the validity for each email transported can be asserted and the forwarding is secure.

No more technical talk, show me the code!

Ok, so first few pre-command. Please make sure you've followed the initial tutorial for installing Haraka as I'll bootstrap from this one.

Adding missing plugin and header

You'll need to install SRS.js as it's used by my plugin.

$ npm install -g SRS.js

Then, download my alias forwarding plugin using SRS

$ cd ~
$ git clone --depth 1 https://github.com/X-Ryl669/haraka-alias-forward.git
$ cd haraka-alias-forward
$ cp plugins/rcpt_to.alias_forward.js ~/.nvm/versions/node/v10.15.0/lib/node_modules/Haraka/plugins/
$ sudo cp config/srs.ini /var/lib/haraka/config

Then edit /var/lib/haraka/config/srs.ini to fill a secret you choose and your SMTP server's domain.

You'll then need to enable DKIM_sign plugin for Haraka.

Beware that, by the time of writing (until my pull request is accepted), the DKIM_sign plugin is failing for forwarded email, so you need to use my version (please check if line 359 reads if (!txn.header || txn.notes.forward) return domain; else do this:

$ cd ~/.nvm/versions/node/v10.15.0/lib/node_modules/Haraka/plugins
$ curl https://raw.githubusercontent.com/X-Ryl669/Haraka/master/plugins/dkim_sign.js > dkim_sign.js 

Then you'll need to create a signature for DKIM and install it on your domain's nameserver.
This is done easily by these commands:

$ cd /var/lib/haraka/config/dkim
$ ./dkim_key_gen.sh domain.com

Then follow the instruction founds in /var/lib/haraka/config/dkim/domain.com/dns (about installing the TXT record in your domain's nameserver).

Then create a /var/lib/haraka/config/dkim_sign.ini containing:

[main]
disabled = false
selector = <the content of /var/lib/haraka/config/dkim/domain.com/selector>
domain = domain.com
headers_to_sign = To, From, Subject, Content-Type, Message-ID, Date

Very important step, if you run haraka with a different user, you must make sure haraka's user is allowed to read /var/lib/haraka/config/dkim/domain.com/private so a chown/chmod with haraka's user on this file is a good idea.

Finally, you'll need to enable the plugin before restarting Haraka, so your /var/lib/haraka/config/plugins should read:

syslog
dnsbl
helo.checks
tls
rcpt_to.alias_forward
data.headers
dkim_sign
queue/discard
limit

(Pay attention to rcpt_to.alias_forward and not anymore rcpt_to.alias_forword)

A little bit more magic:

$ sudo systemctl restart haraka

Et voilà!

Your emails shouldn't be classified as spam anymore.