Configuring email

by Gisle Hannemyr

This chapter explains how to install and configure email (including setting up the Postfix MTA). It also describes how to implement email authentication to ensure delivery to mail providers that use milters to block spam..

Table of contents

http://onlinegroups.net/blog/2014/02/25/how-to-whitelist-an-email-address/

Introduction

This chapter explains how to install and configure email.

Set hostname and mailname

Before proceeding to install the email software, make sure that the system's hostname and mailname sorted out.

A fully qualified domain name (FQDN) is typecally consists of a domain name followed by a tld. In this tutorial, example.com will be used.

We may need to change the configuration of the hostname. For instance, just after creating a DO droplet, the “Static hostname” will by default be the internal DO host identifier:

$ sudo hostnamectl status
   Static hostname: ubuntu-s-1vcpu-2gb-fra1-01
         Icon name: computer-vm
           Chassis: vm
        Machine ID: 5099201dc607419e84f16a61b370e286
           Boot ID: 047255feeb9a444fb932055d98ffff73
    Virtualization: kvm
  Operating System: Ubuntu 20.04.4 LTS
            Kernel: Linux 5.4.0-28-generic
      Architecture: x86-64

To be able to use Gnu mail out of the box, it should be set the hostname to the site's FQDN.

$ sudo hostnamectl set-hostname example.com

This puts the hostname in the file /etc/hostame and the next time you log on, the domain part of the hostname will appear in the CLI prompt on a vanilla Ubuntu configuration.

Next, edit the /etc/hosts file. The values you need to set are at the top of the file. Remember to replace example.com with your FQDN and 192.0.2.0 with your server's public IP address.

127.0.0.1    localhost
127.0.1.1    mail.example.com mail
192.0.2.0    mail.example.com mail

The one line plain text file /etc/mailname (Ubuntu 18.04 LTS) or /etc/hostname (Ubuntu 20.04 LTS) is used by the the s-nail Mail Transfer Agent (i.e. mail server) to know its own hostname. Check that it contains the FQDN and edit it to match if necessary. Example:

example.com

This sets up all the names required for sending and receiving email.

Set up MX

You may want to set up a MX (Mail eXchange) record to direct the emails sent to your domain name to the a appropriate mail server.

Your registrar usually provide a default, but sometimes you will need to add the proper MX records and A records to take more control over email delivery, or to bypass milters.

To set up MX and other advanced settings of your DNS zone at domeneshop, click on “Vis avanserte innstillinger (SRV, TXT, TTL, etc.)”. The result may look like the screen dump below [not yet anonymized]:

domeneshop01.png
Advanced settings for a DNS zone.

Here, the MX record says that mail is handled by “mail.example.com”.

Also make sure an A-record exits for “mail.example.com”, otherwise, mail will not be delivered and you will see the following warning in /var/log/mail.log: “warning: no MX host for example.com has a valid address record”.

Make sure both these tests passes:

$ dig +short example.com mx
10 mail.example.com.
$ host mail.example.com
mail.example.com has address 192.0.2.0

I've also seen this:

$ host mail.example.com
mail.example.com has address 192.0.2.0
Host mail.example.com not found: 3(NXDOMAIN)

Seems to be a transient glitch, so wait until stable. Up to one hour.

Relevant FAQs at Domeneshop and other relevant documentation:

Install PostFix MTA

https://serverfault.com/questions/953104/postfix-connection-refused-error
https://www.linuxbabe.com/mail-server/postfixadmin-create-virtual-mailboxes-ubuntu-20-04
http://techslides.com/mail-server-for-multiple-domains-with-postfix

Postfix is an application to send and receive email (aka. mail transfer agent or MTA).

If you handle your personal mail elsewhere, you do not need to run your own mail server. However, if you manage a web server with applications (such as Drupal) that need to send email notifications, running a send-only SMTP server for that specific purpose is required.

See alsoA tutorial for setting up a local send-only SMTP server is on How to Install and Configure Postfix as a Send-Only SMTP Server on DigitalOcean. For a description of setting up a full Postfix configuration, see How To Install and Configure Postfix on DigitalOcean. You may also want to read these pages: Hostadvice.com, PostFix.org, Change hostname, Configure Postfix to Send Email Using External SMTP Servers.

The most efficient way to install Postfix and other programs needed for testing email is to install the mailutils package. This will install Postfix as well as a few other programs needed for Postfix to function. You should also install s-nail, which is less fussy about hostname than the default Gnu mail.

$ sudo apt update
$ sudo apt install mailutils
$ sudo apt install s-nail

You will be prompted to configure Postfix during installation.

On the general type of email configuration, select ‘Internet Site’. Press TAB to highlight ‘OK’ and then press Enter.

postfix02.png
Configure general type of email.

On the ‘System mail name’ field, enter your FQDN. Do not include “mail.” (e.g. example.com, not ‘mail.example.com’).

postfix03.png
Configure ‘System mail name’.

Edit /etc/postfix/main.cfd (Ubuntu 18.04 LTS) or /etc/postfix/main.cf (Ubuntu 20.04 LTS).

  1. Check the entry myhostname and change its value to “mail.”, followed by the FQDN.
  2. The mydestination entry specifies what domains this machine will deliver locally, instead of forwarding to another machine. Make sure it contains the FQDN and all vhosts that will receive incomping email.
  3. Check entry inet_interfaces and make sure its value is “all” (use “loopback-only” to configure a local send-only SMTP server).

Example:

…
myhostname = mail.example.com
…
mydestination = $myhostname, example.com, example.net, localhost.localdomain, localhost
…
inet_interfaces = all
…

Restart Postfix:

$ sudo systemctl restart postfix

To test that your web server is also capable of sending email, set up s-nail as described in Step 6 and 7 in: How To Install and Configure Postfix on DigitalOcean.

To test, use one of the following:

$ echo "This is the body." | s-nail -s "This is the subject" test@example.com
$ echo "This is the body." | mail -s "This is the subject" test@example.com

The difference is that “s-nail” uses the Gnu/Linux Maildir directory structure to store mail, while “mail” legacy Unix mbox textfile format.

You should also test that the server is capable of receiving email addressed to an exisiting username@FQDN. Doing this will also create your mailbox.

noteNote that your mailbox will not exist until it receives its first email. So make sure you have sent an email to yourself before further troubleshooting.

noteGnu mail is part of the mailutils package. If the sender's domain is not a valid FQDN, outgoing email may be rejected by most recipients with (“550 Unroutable address”) or (“550 Unable to verify sender address”).

If the mail is not accepted by the destination, it is returned to sender:

U 1 Mail Delivery Syst Thu Feb 27 10:00 72/2326 Undelivered Mail Returned to Sender
…
Subject: Undelivered Mail Returned to Sender
…
Diagnostic code: smtp; 550-Improper HELO/EHLO (ubuntu-s-1vcpu-2gb-fra1-01) Not
   fully qualified. 550-RFC 5321, section 4.1.1.1: "The argument clause
   contains the 550-fully-qualified domain name of the SMTP client [...]" 550
   See …

Errors (inluding bounced emails), for s-nail and Gnu mail are recorded here:

/var/log/mail.log

The log should tell you more about why the mail was rejected.

To check the status of postfix do:

$ sudo service postfix status
  postfix.service - Postfix Mail Transport Agent
   Loaded: loaded (/lib/systemd/system/postfix.service; enabled; vendor preset: enabled)
   Active: active (exited) since Sun 2020-02-23 18:40:13 UTC; 2 days ago
 Main PID: 1151 (code=exited, status=0/SUCCESS)
    Tasks: 0 (limit: 1151)
   CGroup: /system.slice/postfix.service

Feb 23 18:40:13 pvn-do-e.roztr.com systemd[1]: Starting Postfix Mail Transport Agent...
Feb 23 18:40:13 pvn-do-e.roztr.com systemd[1]: Started Postfix Mail Transport Agent.

This alternative ending does not necessarily mean trouble:

Oct 21 07:14:06 fqdn.example.com systemd[1]: Starting Postfix Mail Transport Agent...
Oct 21 07:14:06 fqdn.example.com systemd[1]: Finished Postfix Mail Transport Agent.

Set up Postfix to map to users

You should now be able to send mail to your FQDN. You still need to set up Postfix to recognize your vhosts in order to receive mail sent to their users.

Rather than editing /etc/postfix/main.cf directly, you can use Postfix's postconf command to query or set configuration settings.

In these notes we shall use the Gnu/Linux Maildir format, which separates messages into individual files that are then moved between directories based on user action. The alternative (not futher discussed) is legacy Unix mbox textfile format, which stores all messages within a single file.

In /etc/postfix/main.cf, set home_mailbox to Maildir/:

$ sudo postconf -e 'home_mailbox= Maildir/'

Next, set the location of the virtual_alias_maps table, which maps email accounts to Unix system accounts:

$ sudo postconf -e 'virtual_alias_maps= hash:/etc/postfix/virtual'

This maps the table location to a hash database file named /etc/postfix/virtual.db.

Now that you've defined the location of the virtual maps file in your main.cf file, you can create the file itself and begin mapping email accounts to user accounts on your Linux system. Create the file with your preferred text editor. In the file, on each line, list any email addresses that you wish to accept email for, followed by the username of the Unix user you'd like that mail delivered to.

bob@example.com bob
admin@example.com bob

When done, save the file and exit.

Create the hash database file:

$ sudo postmap /etc/postfix/virtual

Restart the Postfix process to apply your changes yo the configuration:

$ sudo systemctl restart postfix

If you've set up ufw, this firewall will block external connections to services on your server by default unless those connections are explicitly allowed. Make sure Postfix (port 25) is allowed:

$ sudo ufw allow Postfix

To make sure you're able to connect, from another computer do:

$ telnet example.com 25
Trying 192.0.2.0
Connected to example.com
Escape character is '^]'.
220 example.com ESMTP Postfix (Ubuntu)
quit
221 2.0.0 Bye
Connection closed by foreign host.

Initialize the Maildir structure

First, meke sure your MAIL environment variable is et correctly. The s-nail client we shall use for testing will look for this variable to figure out where to find mail for your user.

Add the following line to /etc/bash.bashrc and /etc/profile.d/mail.sh (if the latter do not exist, create it):

export MAIL=~/Maildir

To read the variable into your current shell:

$ source /etc/profile.d/mail.sh

Before running s-nail, there are a few settings you need to adjust. Open /etc/s-nail.rc in your preferred text editor and add at the end:

set emptystart
set folder=Maildir
set record=+sent

Here is what these lines do:

To create the Maildir structure within your home own directory is to send yourself an email with s-nail. The -s defines the subject. Because the sent file will only be available once the Maildir is created, you should disable writing to it for this initial email. Do this by passing the -Snorecord option. Provided your username is “bob”, do:

$ echo 'init' | s-nail -s 'init' -Snorecord bob

Verify that it has been created:

$ ls -R ~/Maildir
/home/bob/Maildir:
cur  new  tmp

/home/bob/Maildir/cur:

/home/bob/Maildir/new:
1463177269.Vfd01I40e4dM691221.mail.example.com

/home/bob/Maildir/tmp:

Test that email works

Finally, you should test that both local and remote email works.

To test that the “init” email used to initalize the Maildir structure is received, open the client:

$ s-nail
s-nail version v14.9.15.  Type `?' for help
/home/bob/Maildir: 1 message 1 new
>N  1 bob@example.com     2020-05-19 15:40   14/392   init

Press [Enter] to display the message.

You also should test the following:

The simplest way to do this is to use the custom project Testmail from HNM. See section about Email authentication tools for more.

Block spam

Use a relay MTA

Bypass milters

Due to email spoofing, spam, phishing and other fraudulent practices, some ISPs have introduced use milters (mail filters) that may reject messages that do not authenticate or fail other tests. For instance, AOL will reject any message sent from a server without rDNS, gmail will reject any message that does not use SPF for authentication, and SpamAssassin will penalize missing rDNS and SPF.

You should implement all of the following four concepts to make sure the emails your site send bypass milters:

notePlease note that GMail will classify an email as spam if a PTR record with a valid reverse DNS record for the sending domain's IP address is not set up. The other concepts will also help getting email delivered to GMail. For background, see: Prevent mail to Gmail users from being blocked or sent to spam.

Set up rDNS and PTR records

Reverse DNS lookup or reverse DNS resolution (rDNS) is the determination of a domain name that is associated with a given IP address.

notePlease note that registrars such as Domeneshop does not provide rDNS or PTR records. This is normally provided by your vhost provider (i.e. the owner of the IP-address, such as e.g. DigitalOcean). Turn to you provider for exact instructions.

The rDNS for a single IP address cannot have a PTR record for more than one domain name with a single IP-address. AFAIK, this is not a problem. Milters check that the PTR record for reverse DNS exists, not that it is equivalent to the sending domain. However, SpamAssasin checks that the rDNS match your sending IP.

On DigitalOcean no PTR record is initially configured, but one is created if you rename a droplet via the control panel. The steps are:

  1. Login to the DigitalOcean Control Panel.
  2. Select “Droplets” in the left margin.
  3. In the list, click on the droplet you want to rename.
  4. The screen now shows details about the droplets, as well as name on top. Click on the current name.
  5. It now can be edited. Edit (set it to FQDN), and click on the checkbox on the right to save the change.
  6. Update /etc/hostname /etc/hosts on the server.
  7. Reboot the droplet.

The PTR should be automatically adjusted in few hours due to DNS caching.

Source: DO community: How do I create a reverse DNS (PTR) Record.

Use the CLI and dig to look up the PTR record for the IP-address (this does not work with the FQDN as argument):

$ dig -x 192.0.2.0
…
;; QUESTION SECTION:
;0.2.0.192.in-addr.arpa.   IN      PTR

;; ANSWER SECTION:
0.2.0.192.in-addr.arpa. 79 IN      PTR     fqdn.example.com.
…

The output shows that the IP address is associated with “fqdn.example.com”.

You can see the details in the report from mail-tester.com:

Your server 192.0.2.0 is successfully associated with fqdn.example.com
Here are the tested values for this check:
    IP: 192.0.2.0
    HELO: fqdn.example.com
    rDNS: fqdn.example.com.

You can see the details in the report from IsNotSpam.com:

HELO hostname: fqdn.example.com
Source IP: 192.0.2.0

Postfix uses the value set for “myhostname” in “/etc/postfix/main.cf” for HELO hostname. If you see the following error:

Your IP address 192.0.2.0 is associated with the domain example.com.
Nevertheless your message appears to be sent from mail.example.com.

Check /etc/postfix/main.cf and that the following line matches the rDNS for the domain.

myhostname = fqdn.example.com

Cloud based tools for rDNS lookup:

ComputerWorld: How to setup Reverse DNS and PTR records.

Azure: rDNS.

Set up SPF

A SPF record is a TXT record, that means that the primary record for the domain must be an A record./p>

If email is not included in domain package, create the following TXT record:

"v=spf1 a mx ip4:192.0.2.0 ~all"

If email is included in domain package, change from first to second line.

"v=spf1 include:_spf.domeneshop.no ~all"
"v=spf1 include:_spf.domeneshop.no ip4:192.0.2.0 ~all"

The SPF is validated against the domain indicated by the sender field.

[SPF] ifi.uio.no does not allow your server 167.172.177.32 to use user@ifi.uio.no

Ifi is set up using “?all” in the SPF, instead of “~all”. This resolves to “Neutral”, and also that the recipients can't verify ther SPF isOK, although it might probably be. Most recipents will accept mail when the SPF evaluation resolves to neutral + Pass - Fail ~ SoftFail ? Neutral HELO hostname: do20.roztr.org Source IP: 167.172.177.32 mail-from: gisle@d8.roztr.org

Set up DKIM

First, install OpenDKIM which is an open-source implementation of the DKIM sender authentication system.

$ sudo apt install opendkim opendkim-tools

Then add user postfix to group opendkim.

$ sudo gpasswd -a postfix opendkim

Edit the OpenDKIM main configuration file: /etc/opendkim.conf.

Locate the commonly used options. Uncomment the all three lines. Replace simple with relaxed/simple. After editing, it should look like this:

# Commonly-used options;  the commented-out versions show the defaults.
Canonicalization   relaxed/simple
Mode               sv
SubDomains         no

Then add the following lines below #ADSPAction continue line. If your file doesn't have that line, then just add them below SubDomains no.

AutoRestart         yes
AutoRestartRate     10/1M
Background          yes
DNSTimeout          5
SignatureAlgorithm  rsa-sha256

Add the following lines at the end of this file if missing (on Ubuntu 18.04 and 20.04, the UserID has already been set to opendkim):

#OpenDKIM user
# Remember to add user postfix to group opendkim
UserID             opendkim

# Map domains in From addresses to keys used to sign messages
KeyTable           refile:/etc/opendkim/key.table
SigningTable       refile:/etc/opendkim/signing.table

# Hosts to ignore when verifying signatures
ExternalIgnoreList  /etc/opendkim/trusted.hosts

# A set of internal hosts whose mail should be signed
InternalHosts       /etc/opendkim/trusted.hosts

To create a signing table, key table and trusted hosts file, first create a directory structure for OpenDKIM, and change the owner from root to opendkim and make sure only opendkim user can read and write to the keys directory:

$ sudo mkdir /etc/opendkim
$ sudo mkdir /etc/opendkim/keys
$ sudo chown -R opendkim:opendkim /etc/opendkim
$ sudo chmod go-rw /etc/opendkim/keys

Use preferred editor to create /etc/opendkim/signing.table and add this line to the file. This tells OpenDKIM that if a sender on your server is using a @example.com address, then it should be signed with the private key identified by default._domainkey.example.com.

*@example.com default._domainkey.example.com

Save and close the file.

Create /etc/opendkim/key.table and make it contain the following line, which tells the location of the private key:

default._domainkey.example.com \
  example.com:default:/etc/opendkim/keys/example.com/default.private

Save and close the file.

Create /etc/opendkim/trusted.hosts, and make sure it contains the following lines:

127.0.0.1
localhost

*.example.com

This tells OpenDKIM that if an email is coming from localhost or from the same domain, then OpenDKIM should not perform DKIM verification on the email.

Save and close the file.

Since DKIM is used to sign outgoing messages and verify incoming messages, we need to generate a private key for signing and a public key for remote verifier. Public key will be published in DNS.

Create a separate folder for the domain:

$ sudo mkdir /etc/opendkim/keys/example.com

Generate the keys:

$ sudo opendkim-genkey -b 2048 -d example.com \
  -D /etc/opendkim/keys/example.com -s default -v
opendkim-genkey: generate private key
opendkim-genkey: private ke ywritten to default.private
opendkim-genkey: exteacting public key
opendkim-genkey: DNS TXT record written to default.txt

This will create 2048 bits keys. The -d option specifies the domain. The -D opton specifies the directory where the keys will be stored. The -s opton specifies that we use default as the selector (also known as the name). The private key will be written to a file named default.private and the public key will be written to a file named default.txt.

Make opendkim the owner of the private key:

$ sudo chown opendkim:opendkim /etc/opendkim/keys/example.com/default.private

You need to publish your public key as a TXT record in your zone file. First, examine the contents of the file containing the public key:

$ cat /etc/opendkim/keys/example.com/default.txt
default._domainkey	IN	TXT	( "v=DKIM1; h=sha256; k=rsa; t=y; "
	  "p=KAABIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/fedRNEFQvCdtN0akUCMG686…"
	  "WN8G0212XiFLyyQuxJixQL04BMG0bvBW8xrNDiNuiAkDGea/nUxKRMnuVKOvAa5JAhi/hN…" )
; ----- DKIM key default for example.com

The canidate for the TXT record is the text inside parentheses. However, only the version (v) and the public key (p) is required. To clean up, remove all double quotes, all white space and all parameters except v and p. The result should be a single line like this.

v=DKIM1;p=KAABIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/fedRNEFQvCdtN0akUCMG686…

In your DNS manager, create a TXT record, enter default._domainkey.example.com in the name field and paste the single line into the value field of the DNS record.

domeneshop02.png
Pasting the public key as a single line.

Wait for the TXT record to become visible. You may use dig to check:

$ $ dig default._domainkey.example.com txt
…
;; QUESTION SECTION:
;default._domainkey.example.com. IN    TXT

;; ANSWER SECTION:
default._domainkey.example.com. 3599 IN TXT "v=DKIM1;p=KAABIjANBgkqhkiG9w0BAQEFA…"
…

To test the newly created key pair, enter the following command:

$ sudo opendkim-testkey -d example.com -s default -vvv
opendkim-testkey: using default configfile /etc/opendkim.conf
opendkim-testkey: checking key 'default._domainkey.example.com'
opendkim-testkey: key secure
opendkim-testkey: key OK

If you get the above response, everything is fine.

If you see “key OK”, but also “key not secure”, don't panic. This is because DNSSEC isn't enabled on your domain name. DNSSEC is a security standard for secure DNS query. Some domains haven't enabled DNSSEC. There's no need to worry about this. You can continue the setup.

The final step is to set up a connection between Postfix and OpenDKIM.

Postfix can talk to OpenDKIM via a Unix socket file. The default socket file used by OpenDKIM is /var/run/opendkim/opendkim.sock, as shown in /etc/opendkim.conf. But the postfix SMTP daemon shipped with Ubuntu runs in a chroot jail, which means the SMTP daemon resolves all filenames relative to the Postfix queue directory (/var/spool/postfix). So we need to change the OpenDKIM Unix socket file.

Create a directory to hold the OpenDKIM socket file and allow only the user opendkim and the group postfix to access it.

$ sudo mkdir /var/spool/postfix/opendkim
$ sudo chown opendkim:postfix /var/spool/postfix/opendkim

Edit the OpenDKIM main configuration file /etc/opendkim.conf.

Find one of the following lines (the first is Ubuntu 18.04 the second is Ubuntu 20.04):

Socket    local:/var/run/opendkim/opendkim.sock
Socket    local:/run/opendkim/opendkim.sock

Replace it with the following line. (If you can't find the above line, then add the following line.)

Socket    local:/var/spool/postfix/opendkim/opendkim.sock

Save and close the file.

If you can find the following line in /etc/default/opendkim:

SOCKET="local:/var/run/opendkim/opendkim.sock"
SOCKET=local:$RUNDIR/opendkim.sock

Change it to:

SOCKET="local:/var/spool/postfix/opendkim/opendkim.sock"

Save and close the file.

Finally, you need to edit the Postfix main configuration file /etc/postfix/main.cf:

Add the following lines at the end of this file, so Postfix will be able to call OpenDKIM via the milter protocol.

# Milter configuration
milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters

Save and close the file.

Restart opendkim and postfix.

$ sudo systemctl restart opendkim postfix

That's it! You can now proceed to test that your email authenticates.

Sources:

Set up DMARC

DMARC (Domain-based Message Authentication, Reporting, and Conformance), is a TXT Record that can be published for a domain to control what happens if a message fails authentication (i.e. the recipient server can't verify that the message's sender is who they say they are). A DMARC record serves two purposes:

  1. Tell the recipient server to either: Quarantine the message or Reject the message or Allow the message to continue delivery.
  2. Sends reports to an email address or addresses with data about all the messages seen from the domain.

Those two benefits alone drive home the huge value of setting up DMARC! Once published, a DMARC record is used by receiving mail servers (think Gmail or Yahoo! Mail) to determine what to do with a failed message. The receiving mail server at Gmail looks at the DMARC record for the policy to follow from the following choices:

Action is taken by the recipient mail server on one of those 3 options above if the domain has published a DMARC record. If the domain has not published a DMARC record, the recipient server makes its own determination if the message should be delivered. With phishing, malware threats, and a variety of other security concerns; the direct value of being able to tell recipient mail servers to quarantine or reject messages that fail DMARC has now become the gold standard for sending legitimate email by blocking spammers.

A DMARC policy allows a sender to indicate that their emails are protected by SPF and/or DKIM, and give instruction if neither of those authentication methods passes. Please be sure you have a DKIM and SPF set before using DMARC.

To have one add a TXT record to a subdomain named _dmarc.example.com with the following inital value:

v=DMARC1; p=none

However, if you have a DMARC DNS entry, it is ignored until SPF is set up and message is signed with DKIM.

MXtoolbox.com: How to Add DMARC at your DNS Provider.

Test tool: MXtoolbox.

The List-Unsubscribe header field

The USA CAN-SPAM (Controlling the Assault of Non-Solicited Pornography And Marketing) act obligates senders of bulk email to implement opt-out mechanisms. One of these was the “List-Unsubscribe” header field.

This field is also described in RFC 2369. It is a header field that may look like this:

List-Unsubscribe: <mailto:unsubscribe@example.com?subject=unsubscribe>,
  <https://www.example.com/unsubscribe.html?address=user@example.net>

The above provide two common unsubscibe methods: mailto and http. The first lets the user send a mail to a special addrees. When a mail is received, the sender address should automatically ore manually unsubscribed. The second provides a link that, when clicked, automatically unsubscribes the address.

Currently, this header is not supported by very many email clients, and Gmail.com and Outlook.com only make the method available to the user if the sender has a high reputation. If you send bulk email, you may need to use this header to satisfy the law in the USA, but to provide recipients with a working unsubscribe option, you must also embed a unsubscribe link in the body of the mail.

See alsoSee emailtrap.io: List-Unsubscribe header in email to see how various email clients support this. You may also want to read SO: Gmail unsubscribe link does not appear.

Email authentication tools

To make sure that your email hardening works as intended, you need to test them.

The simplest way to test is to use the email authentication tools listed below is to use the custom project Testmail from HNM. Install it, and navigate to Configuration » Development » Testmail to send mail to various email-addresses, with instructions about how to check the resuilts.

See also: woodpecker.co.

Gmail

If you have a Gmail account, you can use it to check email authentication.

To see if SPF, DKIM and DMARC checks are passed, send a test email from your mail server to your Gmail account. Open the test message, expand the drop-down menu on the right under the three vertical dots, and select “Show original”. Authentication results are shown above the original message.

gmail_original.png
Gmail authentication results (these are displayed above the original message).

Failing tests are not listed.

This tool is free.

Website: mail.google.com.

mail-tester.com

Mail-tester.com is well made. When you vist their website it will generate an unique email address for you. You send sample email to this address and visit a link to view an easy to understand report.

The report will show you your email server IP, info about your SPF, DKIM and DMARC configuration, the score from SpamAssassin, the assessment of your message content as viewed by spam filters, your potential presence on some deny-lists, and info about any broken links in your message. The report also provide helpful hints about how to fix what is wrong.

Then, based on all those factors, you'l get a score from zero to ten. The screenshot below shows a perfect result.

mail-tester-com.png
A perfect score on mail-tester.com.

A score less than five indicates that there are serious problems with your email configuration.

It is free for up to three checks per day, then paid:

There is also a different price list for a white label reseller service.

Website: mail-tester.com.

Check-auth

This free email-tool allows you to check the SPF records, rDNS, DKIM, DomainKey, SenderID and SpamAssasin score for your domain and to see an evalutation of these authentication checks on any message you send.

To use the tool, simply send an empty email from the domain you want to test to this email-address: check-auth@verifier.port25.com. You will receive a return email containing a report with an analysis of the status of the message you sent. The report is useful, but IMHO not as easy to read and helpful as the report provided by mail-tester.com.

The first section in the report is headed “Summary of Results”. It provides four key data points. Example:

SPF check:          pass
"iprev" check:      pass
DKIM check:         pass
SpamAssassin check: ham

The “SPF”, “DKIM” and “SpamAssassin” checks are what they say. The “iprev check” does a rDNS (reverse IP) and forward IP lookup and pass if they are in agreement.

The next section is headed “Details” and provides the following details at the top:

HELO hostname: fqdn.example.com
Source IP:     192.0.2.0
mail-from:     bob@example.com

The rest of this section expands on the tests that is presented in the summary in the first section.

The last section is headed “Original Email” and provides the the full message source.

This tool is free.

Website: ESPC.

IsNotSpam.com

This tool uses a slightly different version version of the software used by Check-auth to perform roughly the same checks, but the report are available as a web page instead of being returned by email.

One difference: The "iprev" (rDNS) check is replaced by something called an “Sender-ID Check” that just look like a repeat of the SPF check.

This tool is free.

Website: IsNotSpam.com.

Xeams.com

This free email-tool allows you to check HELO, rDNS, SPF, [DKIM] and DMARC for outgoing email from your domain and to see an evalutation of these authentication checks on any message you send.

It also does some checks that affects incoming emils: MX, IP-address, STARTTLS, SMTP Auth., that your MTA is not and open relay, and that you reject emails for invalid users.

To use the tool, simply send an email to with the word “validate” in the subject line. from the domain you want to test to this email-address: validate.server@synametrics.com.

The tool will mail you back a HTML report. If your email UA does not parse HTML, save the file and inspect it using a web browser.

xeams-report.png
A report with grade “C” from Xeams.com.

Clicking on “Details…” for the DKIM check takes you to the following explanation:

“DKIM is a mechanism that checks if an incoming email's FROM address is forged.
You see this warning in two case:

The test message used to produce the above report was signed with a valid DKIM signature (accepted by Gmail, mail-tester.com, IsNotSpam.com et al), so I think the DKIM test in this tool is broken..

This tool is free.

Website: Xeams.com.

Not tested

Websites:

Unwashed:

  https://www.sparkpost.com/blog/understanding-spf-and-dkim/
  https://www.emailonacid.com/signup
  https://www.litmus.com/spam-filter-tests/
  https://talosintelligence.com/reputation_center/lookup

  https://www.senderscore.org/
  
  https://www.validity.com/products/250ok/ (being reworked)

Case: example.com

Below is a breakdown of testing one of my domains (here anonymized to “example.com”) on mail-tester.com.

Here is the ratings I've seen during testing:

10  - Wow! Perfect, you can send.
9.0 - Wow! Perfect, you can send.
8.0 - Good stuff. Your email is almost perfect.
7.3 - Good stuff. Your email is almost perfect.
7.0 - Good stuff. Your email is almost perfect.
6.8 - Not bad. Some inboxes might still refuse you.
6.1 - Not bad. Some inboxes might still refuse you.
5.0 - Not bad. Some inboxes might still refuse you.
3.8 - Consider yourself lucky if your email goes to an inbox.
3.1 - Consider yourself lucky if your email goes to an inbox.
0.8 - Your email may never see the light of an inbox.

Below is a breakdown of the segments that make up their report:

Message

Adresses:

From : bob@example.com
Bounce address : postmaster@example.net

Text:

Greetings test-XXX@srvX.mail-tester.com, this is sent to you from
Testmail  
Blåbærsyltetøy.

-- 
This is an automatic email sent from Testmail to test email.

Source. This sample was recorded early on in the process, with a lot of failures.

Received: by mail-tester.com (Postfix, from userid 500)
	id B3DB7A8922; Tue, 20 Oct 2020 18:49:27 +0200 (CEST)
X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail-tester.com
X-Spam-Level: **
X-Spam-Status: No/2.2/5.0
X-Spam-Test-Scores: RDNS_NONE=1.274,SPF_SOFTFAIL=0.972,URIBL_BLOCKED=0.001
X-Spam-Last-External-IP: 192.0.2.0
X-Spam-Last-External-HELO: fqdn.example.com
X-Spam-Last-External-rDNS: 
X-Spam-Date-of-Scan: Tue, 20 Oct 2020 21:07:09 +0200
X-Spam-Report: 
	*  0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was
	*      blocked.  See
	*      http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block
	*      for more information.
        *      [URIs: mail-tester.com]
        *  1.0 SPF_SOFTFAIL SPF: sender does not match SPF record (softfail)
        *  1.3 RDNS_NONE Delivered to internal network by a host with no rDNS
Received-SPF: Softfail (domain owner discourages use of this host) identity=mailfrom;
  client-ip=192.0.2.0; \
  helo=fqdn.example.com; \
  envelope-from=bob@example.com; \
  receiver=test-XXX@srvX.mail-tester.com 
DMARC-Filter: OpenDMARC Filter v1.3.1 mail-tester.com A87E1A6EFA
Authentication-Results: mail-tester.com; dmarc=none header.from=example.com
Received: from fqdn.example.com (unknown [192.0.2.0])
	(using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits))
	(No client certificate requested)
	by mail-tester.com (Postfix) with ESMTPS id 41B9FA8E66
	for ; Tue, 20 Oct 2020 21:07:05 +0200 (CEST)
Received: by fqdn.example.com (Postfix, from userid 33)
	id CF5E0FF621; Tue, 20 Oct 2020 19:07:04 +0000 (UTC)
To: test-XXX@srvX.mail-tester.com
Subject: Testmail for test-XXX@srvX.mail-tester.com from Testmail
MIME-Version: 1.0
Content-Type: text/plain;charset=utf-8
X-Mailer: Drupal
Sender: postmaster@example.net
From: bob@example.com
List-Unsubscribe: 
Message-Id: <20201020190704.CF5E0FF621@fqdn.example.com>
Date: Tue, 20 Oct 2020 19:07:04 +0000 (UTC)
Content-Transfer-Encoding: quoted-printable

Greetings test-XXX@srvX.mail-tester.com, this is sent to you from
Testmail.
Bl=C3=A5b=C3=A6rsyltet=C3=B8y.

--=20
This is an automatic email sent from Testmail to test email.

SpamAssassin

During the testing, I noticed various SpamAssassin failures. Below are the keys recorded, and scores associated with them:

SPF_PASS          [+0.001]
SPF_NEUTRAL       [-0.652]
SPF_SOFTFAIL      [-0.972]
SPF_HELO_SOFTFAIL [-0.896] SPF: HELO does not match SPF record (softfail)
RDNS_NONE         [-1.274] Delivered to internal network by a host with no rDNS

Authentication

During the testing, I noticed various authentication failures. Below are these recorded, and the scores associated with them.

Format

Blacklist or deny-list

Your IP-address is not deny-listed.

Security

To able three conditions need to be satisfied:

  1. Trustworthy certificates
  2. Trustworthy protocol
  3. DANE (DNS-based Authentication of Named Entities)

STARTTLS

https://howtoinstall.co/en/starttls

Enforce TLS

Security check tools

https://serverfault.com/questions/131627/how-to-inspect-remote-smtp-servers-tls-certificate

This webbased tool: www.checktls.com

Will just returm the TLS vesion the site is running.

This webbased tool: ssl-tools.net/mailservers will check:

  1. STARTTLS support
  2. SSL certificate quality
  3. PFS (Perfect Forward Secrecy)
  4. Heartbleed

However, many properly configured servers are protected against port-scanning and you will only get:

No connection to the mailservers of example.net could be established.

This does not mean that the server is unable to receive encrypted email.

Troubleshooting

If you see the following log message in /var/log/mail.log:

… opendkim …: signing table references unknown key 'default._domainkey.example.com'

… check for typos in /etc/opendkim/key.table.

Final word

[TBA]


Last update: 2020-10-25 [gh].