Configure server for sending signed email DKIM, SPF and DMARC

Posted by admin on October 12, 2017

Although web notifications have started using often, emailing is still an important part of a website. It is also a challenge get in the inbox. I love self-hosting services on my server.

I recently set up a server for an e-commerce website. We used Yandex’s free email service for personal accounts. But using SMTP service of Yandex was inefficient. So I used PHP’s mail() function which uses sendmail. But there was a problem, emails were not signed. So I searched a little bit and found some information about DKIM SPF and DMARC. In this article, I will try to explain how to set up these in server and DNS.

Notice:
For the ones doesn’t care about self-hosted should probably use a mail service like SendGrid or something like that.

What the hell are DKIM, SPF, and DMARC?

If you reading this article you probably already know what these are but here are some short explanations and some links.

For lazy ones, here is a short (2 min.) video about DMARC which also give a basic info about DKIM and SPF.

DKIM:

“DomainKeys Identified Mail (DKIM) lets an organization take responsibility for a message that is in transit. The organization is a handler of the message, either as its originator or as an intermediary. Their reputation is the basis for evaluating whether to trust the message for further handlings, such as delivery. Technically DKIM provides a method for validating a domain name identity that is associated with a message through cryptographic authentication.” from http://www.dkim.org/

In short, it cryptographically signs your emails to associate domain name identity.

SPF (Sender Policy Framework):

To sum up, it lists allowed domains to send an email.

You can read instruction to get some details http://www.openspf.org/Introduction

DMARC:

“DMARC, which stands for “Domain-based Message Authentication, Reporting & Conformance”, is an email authentication, policy, and reporting protocol. It builds on the widely deployed SPF and DKIM protocols, adding linkage to the author (“From:”) domain name, published policies for recipient handling of authentication failures, and reporting from receivers to senders, to improve and monitor the protection of the domain from fraudulent email.”

This is a feedback mechanism from receiver to the sender. With DMARC you can improve your email security. I didn’t dive into all of these. For more information please do your own search.

https://dmarc.org/overview/

Basic DNS

I use Godaddy as domain name registrar. It has a build in DNS manager. If you DNR doesn’t provide a DNS management service you can use https://www.cloudflare.com/

So basic record information:

MX Records:

“A mail exchanger record (MX record) is a type of resource record in the Domain Name System that specifies a mail server responsible for accepting email messages on behalf of a recipient’s domain, and a preference value used to prioritize mail delivery if multiple mail servers are available.”
https://en.wikipedia.org/wiki/MX_record

TXT Records:

A TXT record (short for text record) is a type of resource record in the Domain Name System (DNS) used to provide the ability to associate some arbitrary and unformatted text with a host or other name, such as human-readable information about a server, network, data center, and other accounting information.
https://en.wikipedia.org/wiki/TXT_record

Let’s Begin!

Creating DKIM Keys

DKIM uses asymmetric (public-private key) cryptography to verify email. We define a channel (“selector”) for the key in DNS. And this channel contains a public key. And server uses a private key to sign emails. Receiver checks DNS record and email sign and finally confirm email’s content (i mean it checks email is changed or not) and source.

You can create our keys on your computer and setup by on your own. But will use http://dkimcore.org/tools/ tool to create. It creates a random selector like “1507793285.example”, you can change it.

We need 4 things to setup DKIM:

  1. selector: We might work on different servers or we might need to separate your DKIM sign mechanism.
  2. Private Key: We will use it to sign our emails.
  3. Public Key: We will add this to DNS records so the receiver can validate emails.

 

Let’s start!

Firstly, we need to add our public key to DNS as TXT record. I have used Godaddy’s panel.

Key: selector._domainkey

Value:v=DKIM1;p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDnDqdP0TLlI1zlmjRQLTWbEUUkBolzbMyNQzK9grNOVWKBQXSrpG6nWlINJ8UgaFj8ZnkDVEwjf/clKzSNsmBO4QlcAVBq5LgF6a4hwIxEjYI80Ico+yh6lk24sEsMVxait2vvy/kAesoA3obO4+7CV6eNlK96/Du9rW74glx6QIDAQAB

Next we will add, spf information. Add new TXR record.

Key: @ (or your domain name example.com)

Value: “v=spf1 a include:example.com ~all”

Value is an example. You probably need to change it. For example, if your a record already refers to a domain, you do not have to add include:example.com part. Please read some from spf’s website. I ended up with sample value for Yandex:

v=spf1 a mx include:myvpshostadress.com redirect=_spf.yandex.net

Finally, DMARC TXT record. I just added the code below. DMARC is a little bit complicated. Please read docs.

Key: _dmarc

Value: v=DMARC1; p=none

Now, all DNS stuff is done. All we need to do is signing emails with our private key. I have used PHPMailler class to send an email which uses sendmail command by default.

Sending Email

$mail = new PHPMailer(true); // Passing `true` enables exceptions
try {
//Server settings
$mail->SMTPDebug = 2; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = ‘smtp1.example.com;smtp2.example.com’; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = ‘user@example.com’; // SMTP username
$mail->Password = ‘secret’; // SMTP password
$mail->SMTPSecure = ‘tls’; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587; // TCP port to connect to

//Recipients
$mail->setFrom(‘from@example.com’, ‘Mailer’);
$mail->addAddress(‘joe@example.net’, ‘Joe User’); // Add a recipient

//Content
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = ‘Here is the subject’;
$mail->Body = ‘This is the HTML message body <b>in bold!</b>’;
$mail->AltBody = ‘This is the body in plain text for non-HTML mail clients’;

 

// sign
$mail->DKIM_domain = ‘example.com’;
$mail->DKIM_private = $privatekeyfile;
$mail->DKIM_selector = ‘phpmailer’;
$mail->DKIM_passphrase = ”; //key is not encrypted

$mail->send();
echo ‘Message has been sent’;
} catch (Exception $e) {
echo ‘Message could not be sent.’;
echo ‘Mailer Error: ‘ . $mail->ErrorInfo;
}

You can check phpmailler test cases for detailed information. https://github.com/PHPMailer/PHPMailer/blob/d47a148ebce7d76fa6b4d39ed997887f88cb7ff8/test/PHPMailerTest.php

Test Your Configuration

You worked hard! Now, test your server whether working correctly or not. You can use the site below to test your configuration by sending a test email. It will give you a good brief information.

http://www.appmaildev.com/en/dkim

Bonus for WordPress users:

http://www.appmaildev.com/en/dkim

http://www.appmaildev.com/en/dkim