Email deliverability with Linux mail command

Published: 1 year ago web dev

Everyone knows getting emails to land in inboxes is much harder than it used to be. If, like me, you rely on using the mail command to send emails from cron jobs and scripts, mainly to alert to failures, it is important those emails end up in your inbox and not in spam. Today lets take a look at ways to achieve this.

SPF

An SPF record is a TXT record on your domain that says 'hey, these ip addresses can send email from this domain'. If your root domain A record points to the same place as your sending mail server, the SPF record is very simple:

example.org. IN TXT "v=spf1 a ~all"

We simply say allow the root record for the domain to be approved and soft fail on any other sender IP. There are obviously many more configuration options available but that is all needed for our current purposes.

I encourage you to use SPF Wizard to help configure your own SPF record.

DKIM

DKIM (DomainKey Identified Mail) uses keys to verify the sender of an email. The private key remains on the sending server and the public key is added as a TXT record to the domain. We are going to set up DKIM to work with sendmail MTA (Mail Transfer Agent) which is the default on Debian based distributions.

Mostly, you should follow this tutorial.

I'm not going to reproduce it word for word here but I will say, as per the comments on the linked tutorial, I had to set /etc/opendkim folder and its contents to be owned by opendkim.opendkim before it worked. Prior to this I was seeing Connection refused by localhost errors.

Reverse DNS

Reverse DNS associates an IP address with a domain name. Email providers look at the configured rDNS as an anti-spam measure. You should ensure your IPv4 and IPv6 rDNS point to your sending domain. This is usually configured in your hosting/server provider's control panel.

I wrote a bit about adding rDNS for IPv6 recently.

Configure sending server's domain

By default you may find that mail gets sent from a local domain, such as @localhost.localdomain. You can determine your default mail sending domain by running hostname --fqdn. Sendmail uses this as the default sending address. To change it:

To edit your hostname and FQDN,

sudo nano /etc/hostname

and replace with your correct hostname.

sudo hostname [hostname]

for good measure (should change hostname immediately).

sudo nano /etc/hosts

Add your new FQDN and hostname in hosts. Mine ends up looking like:

127.0.0.1 localhost.localdomain localhost
x.x.x.x hostname.fully.qualified hostname

An important note for OpenVZ

Actually for my OpenVZ VPS with RamNode would overwrite /etc/hosts every reboot. You have to change the hostname in the VM control panel. This may affect KVM, xen and other virtual guests too, not sure.

Whitelist your sending address

After adding all these anti-spam methods I was still having issues with email going to spam on Gmail. My conclusion was that previous messages (without these anti-spam methods) were marked as spam, so the sender remained listed as a spam sender. On Gmail to mark a message as not spam, you just have to drag it back into your inbox. Upon doing this the emails started getting delivered directly to the inbox.

If all else fails...

Firstly, check if your IP is on any blacklist. If it's a newish remote machine, the previous user might have used that IP to spam. These are two popular blacklist checkers: MXToolBox and multibl.

The big providers usually have a web form for reporting deliverability issues. It is often a case of not having enough reputation in their system and, in my experience, they usually give senders the benefit of the doubt and allow you through. Obviously you only need to report issues for the provider you are trying to get emails sent to.

Google report

Microsoft report

What about DMARC?

DMARC is another anti-spam technique that allows you to say what you want to happen to delivered emails that fail SPF/DKIM. We won't bother with it in this case because it is generally recommended you configure it to receive reports on sent email and our setup doesn't allow remote senders to email us.