One of the major problems that have to be faced by mail server admins is that, the mails send by their mails servers are flagged as spams by popular mail clients like Gmail and Yahoo. However, not having properly configured DKIM is one out of several reason that cause such problem,
- The IP address of sending mail server is blacklisted.
You can check whether your server IP address is blacklisted by using this tool: Click here.
- The server doesn’t have a FQDN (Fully Qualified Domain Name) and a PRT record (tutorial).
- The SPF record of the domain you are using to send emails is missing or not properly configured.
Setting up a SPF record for your domain is discussed in my previous tutorial. “Configure SPF Record for your Domain”.
- DomainKeys Identified Mail (DKIM) is not available or not properly configured for relevant domains that used to send emails.
Lets’ see what is this DKIM…….
DomainKeys Identified Mail commonly known as DKIM is another technique use by mail servers to authenticate the content of an email send by them. As a result, if a hacker changes the contents of the email at the middle of mail delivery, those changes could be identified by the receiver. Then receiver can simply neglect or mark the mail as a spam.
Explain the process of validation by DKIM record
DKIM uses asymmetric private-public key cryptography and hashing to achieve this sought of security.
Firstly, sending mail server digitally signed an email using the private key of the domain associated with sending email address.
Digitally signed: Generate the hash value of message content including some important mail header details and encrypt it with the private key.
This signature generated using the private key could only be de-crypted using the relevant public key. Hopefully the sender has already published the public key as a DNS record in the domain related to email address.
Receiver obtains the public key from DNS server. De-crypt the signature and obtain the hash of message calculated at senders’ end.
Then receiver recalculated the hash of message and compared that recalculated hash with the hash calculated at the senders end.
If there is a change to message contents / mail header in between sender and receiver, then above hash values won’t match and the email would be rejected or treated as a spam by receiver.
It is clear that, by using DKIM, receiving party could confirm that the content of a valid email hasn’t changed when transferring via internet.
In this tutorial, I am going to show you,
- How to install OpenDKIM: OpenDKIM is an open source implementation of the DomainKeys Identified Mail (DKIM) sender authentication system. This is used for public-private key generation and email signing purposes.
- How to configure OpenDKIM to work with your mail server and domains.
- Generating public-private key pairs.
- How to add pubic key as a DNS record.
- Finally TEST the DKIM record
And I am going to use my newly created Freenom domain, testdkim.cf to illustrate above steps.
This tutorial assumes that,
- You have basic Linux command knowledge.
- You know how to access server over SSH (tutorial).
- Mail server is already installed and configured: At least mail from your server should send to spam folder of receiver (tutorial).
- Hostname, FQDN and PTR are properly configured (tutorial).
- SPF record for your domain(s) is/are properly configured (tutorial).
Firstly, update and upgrade your system packages:
sudo apt-get update sudo apt-get dist-upgrade
Then install OpenDKIM and its dependencies:
sudo apt-get install opendkim opendkim-tools
At this moment you have successfully installed DKIM. Now you need to configure it to work with your mail server and relevant domains. Follow following configuration steps orderly. Note that I am using nano editor to make these configurations.
Important: Replace every instance of testdkim.cf with your own domain in all commands and configuration files. Don’t forget to save your files after editing.
First configure the OpenDKIM main configuration file. Open /etc/opendkim.conf using you favourite text editor.
sudo nano /etc/opendkim.conf
Then append following lines to the end of configuration files.
AutoRestart Yes AutoRestartRate 10/1h UMask 002 Syslog yes SyslogSuccess Yes LogWhy Yes Canonicalization relaxed/simple ExternalIgnoreList refile:/etc/opendkim/TrustedHosts InternalHosts refile:/etc/opendkim/TrustedHosts KeyTable refile:/etc/opendkim/KeyTable SigningTable refile:/etc/opendkim/SigningTable Mode sv PidFile /var/run/opendkim/opendkim.pid SignatureAlgorithm rsa-sha256 UserID opendkim:opendkim Socket inet:12301@localhost
!! Some Extra Stuff !!
DKIM-milter is a milter-based application (dkim-filter) which plugs in to Postfix to provide DomainKeys Identified Mail service for your mail server.
Socket: the milter will listen on the socket specified above, Posfix will send messages to OpenDKIM for signing and verification through this socket; Here in this tutorial, I have use port 12301 as my socket.
12301@localhost defines a TCP socket that listens on
However, you can choose a custom port number for the
Socket. Make sure that it’s not used by a different application.
After that connect the milter to Postfix:
sudo nano /etc/default/opendkim
Append following line to the end of file. Change the port, only if a custom port is used.
Then configure Postfix to use this milter:
sudo nano /etc/postfix/main.cf
Insert following lines at the end of configuration file.
milter_protocol = 2 milter_default_action = accept smtpd_milters = inet:localhost:12301 non_smtpd_milters = inet:localhost:12301
Then create following directories to hold the Trusted Hosts, Key Tables, Signing Tables and Crypto Keys:
sudo mkdir /etc/opendkim sudo mkdir /etc/opendkim/keys
After that specify Trusted Hosts:
sudo nano /etc/opendkim/TrustedHosts
Add following contents to the file.
127.0.0.1 localhost 192.168.0.1/24 *.testdkim.cf #*.example.net #*.example.org
Note: Do not change the first three lines. If necessary, from the fifth line you can add multiple domains. Here I am using testdkim.cf to illustrate you the configuration process. Examples are comment out (using #) at the end of file.
After that, let’s create a Key Table to mention the selector/domain pair and relevant path to their private key.
sudo nano /etc/opendkim/KeyTable
Here I am going to use mail as the selector and it’s not necessary to change it. But if you want, any alphanumeric string can be use as a selector. Remember to change the commands / configurations done from here on-wards accordingly.
Add following contents to the Key Table:
mail._domainkey.testdkim.cf testdkim.cf:mail:/etc/opendkim/keys/testdkim.cf/mail.private #mail._domainkey.example.net example.net:mail:/etc/opendkim/keys/example.net/mail.private #mail._domainkey.example.org example.org:mail:/etc/opendkim/keys/example.org/mail.private
Then Create a Signing Table:
sudo nano /etc/opendkim/SigningTable
Add following contents to the Signing Table.
*@testdkim.cf mail._domainkey.testdkim.cf #*@example.net mail._domainkey.example.net #*@example.org mail._domainkey.example.org
Generate Public and Private Key(s)
Go to keys directory:
Then create a separate folder for the domain to hold the keys:
sudo mkdir testdkim.cf cd testdkim.cf
Issue following command to generate the keys:
sudo opendkim-genkey -s mail -d testdkim.cf
Note: If you are setting up DKIM for more than one domain, then create domain folders inside /etc/opendkim/keys/ accordingly and issue above command inside those folders in an appropriate manner.
Above command will create two files,
mail.private is our private key and
mail.txt contains the public key.
Then change the owner of the private key to
sudo chown opendkim:opendkim mail.private
Now we have successfully created public and private key pairs for relevant domain and now it’s time to add our public key as a DNS record, so that mail-receiver could obtain our public key.
Add Public Key(s) to Domain’s DNS
mail.txt, which contains our public key:
sudo nano -$ mail.txt
Go to your DNS manager which manages the DNS for your domain. For example, I am using DigitalOcean to manage the DNS of testdkim.cf
Then create a new DNS record:
Name / hostname: mail._domainkey.testdkim.cf
You should obtain the Value / Data as follows:
Value: “v=DKIM1; h=sha256; k=rsa; followed by the p parameter ” (end quotation)
For example Value / Data may looks like,
"v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2muIVV6IODVNzf+n3uUpd8ZuQ"
*Change the selector “mail“, if you specify a different selector previously.
Please note that, the DNS may take some time to propagate.
As the last step, restart Postfix and OpenDKIM:
sudo service postfix restart sudo service opendkim restart
Finally, Test DKIM
Test 1: DKIM record check
1. Go to MXToolBox Super-Tool: Click here.
2. Then select DKIM Lookup from the drop-down menu.
3. Then enter yourdomain.com:selector in the text field; In my case, it is
testdkim.cf:mail and click on “DKIM Lookup”.
4. Successfully published DKIM record should certainly give you an output as follows.
If you didn’t obtain a Green-background output as above, then please check whether you have followed each and every step correctly. If you still can’t find the mistake, then please make a comment so that I can help you.
Test 2: Check whether DKIM authentication is working
If you obtain a positive result from Test 1, you can proceed with this step.
1. Send an email to a popular mail client like GMail, Yahoo Mail etc. using you DKIM configured mail server (use a DKIM configured domain name).
For example, I am sending an email to my GMail address email@example.com.
2. Now visit relevant mail client, open the received email and select the option to “Show Original”.
If the received mail is authenticated with DKIM, you’ll obtain an output as follows. That is, the calculated hashes at sender an receiver sides get matched and hence no change has been done to mail content in between sender an receiver.
Note: If you have entered the Value / Data of DKIM record incorrectly, then you’ll pass the Test 1 but there will be a DKIM authentication problem in Test 2. In such a case, double check whether you have entered the Value / Data for DKIM record as per given instructions.