DKIM¶
What is DKIM?¶
From Wikipedia:
DomainKeys Identified Mail (DKIM) is an email authentication method designed to detect forged sender addresses in emails (email spoofing), a technique often used in phishing and email spam.
DKIM allows the receiver to check that an email claimed to have come from a specific domain was indeed authorized by the owner of that domain. It achieves this by affixing a digital signature, linked to a domain name, to each outgoing email message. The recipient system can verify this by looking up the sender's public key published in the DNS. A valid signature also guarantees that some parts of the email (possibly including attachments) have not been modified since the signature was affixed. Usually, DKIM signatures are not visible to end-users, and are affixed or verified by the infrastructure rather than the message's authors and recipients.
Installing and Configuring DKIM¶
First ensure you're in a sudo shell and install OpenDKIM which is an open source implementation of the DKIM sender authentication system:
apt update && sudo apt install opendkim opendkim-tools
Enable the service:
systemctl enable opendkim
Then add the postfix user to the opendkim group:
gpasswd -a postfix opendkim
Edit the OpenDKIM main configuration file:
nano /etc/opendkim.conf
Uncomment or add lines as below:
Canonicalization relaxed/simple
Mode sv
SubDomains no
UMask 007
AutoRestart yes
AutoRestartRate 10/1M
Background yes
DNSTimeout 5
SignatureAlgorithm rsa-sha256
#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
InternalHosts /etc/opendkim/trusted.hosts
Now we create a directory structure for OpenDKIM:
mkdir /etc/opendkim
mkdir /etc/opendkim/keys
Change the owner from root to opendkim and make sure only the opendkim user can read and write to the keys directory:
chown -R opendkim:opendkim /etc/opendkim
chmod go-rw /etc/opendkim/keys
Create the signing table:
nano /etc/opendkim/signing.table
Add this line to the file. Note that your-domain.com and your-domain is different. The latter should not contain the top-level domain. If you have more than one domain, use one line per domain entry.
*@example.com default._domainkey.example.com
Then create the key table:
nano /etc/opendkim/key.table
Add the following line - or multiple lines for multiple domains:
default._domainkey.example.com example.com:default:/etc/opendkim/keys/example.com/default.private
Save and close the file.
Create the trusted hosts file:
nano /etc/opendkim/trusted.hosts
Add the following lines to the newly created file:
127.0.0.1
localhost
hostname
example.com
*.example.com
The above means that messages coming from the above IP addresses and domains will be trusted and signed.
Generating the DKIM keys¶
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. The public key will be published in DNS.
Create a separate folder for the domain:
mkdir /etc/opendkim/keys/example.com
Generate keys using the opendkim-genkey tool:
opendkim-genkey -b 2048 -d example.com -D /etc/opendkim/keys/example.com -s default -v
The above command will create 2048 bits keys. -d (domain) specifies the domain. -D (directory) specifies the directory where the keys will be stored and we use default as the selector (-s), also known as the name. Once the command is executed, the private key will be default.private and default.txt will be the TXT record that contains public key.
Make opendkim as the owner of the private key:
chown opendkim:opendkim /etc/opendkim/keys/example.com/default.private
Display the public key:
cat /etc/opendkim/keys/example.com/default.txt
The string after the p parameter is the public key.
In your DNS manager, create a TXT record, enter default._domainkey in the name field. Then copy everything in the parentheses and paste it into the value field. Delete all double quotes and white spaces. If you don’t delete them, then the key test in the next step will fail.
Enter the following command to test your key:
opendkim-testkey -d example.com -s default -vvv
If everything is OK, you will see
key OK
It may also say key not secure
. If so then it doesn't mean there's an error. It is an expected consequence of not using DNSSSEC. DNSSEC can be setup by following the instructions on the Cloudflare DNS management page if you require it (and are using Cloudflare to manage DNS!).
Postfix can talk to OpenDKIM via a Unix socket file. The default socket file used by OpenDKIM is at /var/run/opendkim/opendkim.sock. But the postfix SMTP daemon shipped with Ubuntu runs in a chroot jail, which means that the SMTP daemon resolves all filenames relative to the Postfix queue directory (/var/spool/postfix). So we need to change the socket file.
Create a directory to hold the OpenDKIM socket file and only allow opendkim user and postfix group to access it:
mkdir /var/spool/postfix/opendkim
chown opendkim:postfix /var/spool/postfix/opendkim
Then edit the socket configuration file:
nano /etc/default/opendkim
Find the following line:
SOCKET="local:/run/opendkim/opendkim.sock"
Replace it with:
SOCKET="local:/var/spool/postfix/opendkim/opendkim.sock"
Save and close the file.
Now check the /etc/default/opendkim file:
nano /etc/default/opendkim
If you can find the following line:
SOCKET="local:/run/opendkim/opendkim.sock"
or
SOCKET=local:$RUNDIR/opendkim.sock
Then change it to
SOCKET="local:/var/spool/postfix/opendkim/opendkim.sock"
Configuring Postfix¶
Next, we need to edit Postfix main configuration file:
nano /etc/postfix/main.cf
Add the following lines after smtpd_recipient_restriction section:
# 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. Then restart opendkim and postfix service:
systemctl restart opendkim postfix
Testing¶
To test SPF and DKIM, send a test email from one of your new addresses to check-auth@verifier.port25.com and wait for the reply. It can sometimes be an issue sending emails to an outlook.com address as Microsoft use their own internal blacklist that incorrectly blocks many legitimate IP addresses. If you have this issue, try completing the form at https://support.microsoft.com/en-us/getsupport?oaspworkflow=start_1.0.0.0&wfname=capsub&productkey=edfsmsbl3&locale=en-us&ccsid=635714983457075069 or alternatively going through the process here: https://sendersupport.olc.protection.outlook.com/snds/
Testing Email Score and Placement
You can also go to https://www.mail-tester.com. You will see a unique email address. Send an email from your domain to this address and then check your score. As you can see, I got a perfect score. Mail-tester.com can only show you a sender score. There’s another service called GlockApps that allow you to check if your email is placed in the recipient’s inbox or spam folder, or rejected outright. It supports many popular email providers like Gmail, Outlook, Hotmail, YahooMail, iCloud mail, etc
Further Reading:
https://www.emailonacid.com/blog/article/email-development/what_is_dkim_everything_you_need_to_know_about_digital_signatures/
https://wiki.archlinux.org/index.php/OpenDKIM