Install and Configure OpenDKIM on CentOS 8/RHEL 8 Mail Server
Previously I showed you how to set up SPF and DKIM on CentOS/RHEL mail server. Two common pieces of software that can do DKIM signing and verification on Linux are OpenDKIM and Amavis. In that tutorial I used Amavis, because at the time OpenDKIM isn’t included in any CentOS 8/RHEL 8 repository. As of now, OpenDKIM is included in the EPEL repository. Some folks prefer to use OpenDKIM so I will show you how in this tutorial.
What is DKIM?
DKIM (DomainKeys Identified Mail) is a type of TXT records in DNS that can help with preventing email spoofing and making legitimate emails delivered into the recipient’s inbox instead of spam folder. DKIM uses a private key to add a signature to emails sent from your domain. Receiving SMTP servers verify the signature by using the corresponding public key, which is published in your domain’s DNS records.
Disabling DKIM in Amavis
If you followed my previous Amavis tutorial, but now you want to use OpenDKIM, you need to disable DKIM in Amavis. Edit the main configuration file.
sudo nano /etc/amavisd/amavisd.conf
Find the following lines.
$enable_dkim_verification = 1; # enable DKIM signatures verification $enable_dkim_signing = 1; # load DKIM signing code, keys defined by dkim_key
Add a #
character at the beginning of each line to comment them out.
#$enable_dkim_verification = 1; # enable DKIM signatures verification #$enable_dkim_signing = 1; # load DKIM signing code, keys defined by dkim_key
Save and close the file. Then restart Amavis.
sudo systemctl restart amavisd
Step 1: Install and Configure OpenDKIM on CentOS 8/RHEL8
First enable the EPEL (Extra Packages for Enterprise Linux) repository and install OpenDKIM.
sudo dnf install epel-release sudo dnf install opendkim opendkim-tools
Edit OpenDKIM main configuration file.
sudo nano /etc/opendkim.conf
Find the following line.
Mode v
By default, OpenDKIM runs in verification mode (v), which will verify the DKIM signature of incoming email messages. We need to sign outgoing emails, so change this line to the following to enable signing mode.
Mode sv
Then find the following lines.
## Specifies whether or not the filter should generate report mail back ## to senders when verification fails and an address for such a purpose ## is provided. See opendkim.conf(5) for details. SendReports yes ## Specifies the sending address to be used on From: headers of outgoing ## failure reports. By default, the e-mail address of the user executing ## the filter is used (executing_user@hostname). # ReportAddress "Example.com Postmaster" <[email protected]>
When a signature verification fails and the signature included a reporting request (“r=y”) and the signing domain advertises a reporting address (i.e. ra=user) in a reporting record in the DNS, OpenDKIM will send a structured report to that address containing details needed to reproduce the problem. You may want to use a particular From email address to send the report. Uncomment the ReportAddress
parameter and change email address. Note that this will not create the backscatter problem, because report emails will sent to an email address specified in the sender domain’s DNS record.
Find the following line and comment it out, because we will use separate keys for each domain name.
KeyFile /etc/opendkim/keys/default.private
Next, find the following 4 lines and uncomment them.
# KeyTable /etc/opendkim/KeyTable # SigningTable refile:/etc/opendkim/SigningTable # ExternalIgnoreList refile:/etc/opendkim/TrustedHosts # InternalHosts refile:/etc/opendkim/TrustedHosts
Save and close the file.
Step 2: Create Signing Table, Key Table and Trusted Hosts File
Edit the signing table file.
sudo nano /etc/opendkim/SigningTable
Add the following line at the end of this file. This tells OpenDKIM that if a sender on your server is using a @your-domain.com
address, then it should be signed with the private key identified by 20200308._domainkey.your-domain.com
.
*@your-domain.com 20200308._domainkey.your-domain.com
20200308 is the DKIM selector. A domain name might have multiple DKIM keys. The DKIM selector allows you to choose a particular DKIM key. You can use whatever name for the DKIM selector, but I found it’s convienent to use the current date (March 8, 2020) as the DKIM selector. Save and close the file. Then edit the key table file.
sudo nano /etc/opendkim/KeyTable
Add the following line, which specifies the location of the DKIM private key.
20200308._domainkey.your-domain.com your-domain.com:20200308:/etc/opendkim/keys/your-domain.com/20200308.private
Save and close the file. Next, edit the trusted hosts file.
sudo nano /etc/opendkim/TrustedHosts
127.0.0.0.1
and ::1
are included in this file by default. Now add the following line. This tells OpenDKIM that if an email is coming from your own domain name, then OpenDKIM should sign the email but don’t perform DKIM verification on the email.
.your-domain.com
Save and close the file.
Note: You should not add an asterisk in the domain name like this: *.your-domain.com
. There should be only a dot before the domain name.
Step 3: Generate Private/Public Keypair
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/your-domain.com
Generate keys using opendkim-genkey
tool.
sudo opendkim-genkey -b 2048 -d your-domain.com -D /etc/opendkim/keys/your-domain.com -s 20200308 -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. I use 20200308
as the DKIM selector. Once the command is executed, the private key will be written to 20200308.private
file and the public key will be written to 20200308.txt
file.
By default, only root can read and write to the key files. Make opendkim
as the owner of the private key.
sudo chown opendkim:opendkim /etc/opendkim/keys/ -R
Step 4: Publish Your Public Key in DNS Records
Display the public key
sudo cat /etc/opendkim/keys/your-domain.com/20200308.txt
The string after the p
parameter is the public key.
In you DNS manager, create a TXT record, enter 20200308._domainkey
in the name field. (You need to replace 20200308 with your own DKIM selector.) Then go back to the terminal window, copy everything in the parentheses and paste it into the value field of the DNS record. You need to delete all double quotes and line breaks in the value field. If you don’t delete them, then key test in the next step will probably fail.
Step 5: Test DKIM Key
Enter the following command on your CentOS 8/RHEL 8 server to test your key.
sudo opendkim-testkey -d your-domain.com -s 20200308 -vvv
If everything is OK, you will see the key OK
message.
opendkim-testkey: using default configfile /etc/opendkim.conf opendkim-testkey: checking key '20200308._domainkey.linuxbabe.com' opendkim-testkey: key OK
Note that your DKIM record may need sometime to propagate to the Internet. Depending on the domain registrar you use, your DNS record might be propagated instantly, or it might take up to 24 hours to propagate. You can go to https://www.dmarcanalyzer.com/dkim/dkim-check/, enter 20200308
as the selector and enter your domain name to check DKIM record propagation.
If you see “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. Most domain names haven’t enabled DNSSEC. You can continue to follow this guide.
Now we can start the opendkim service.
sudo systemctl start opendkim
And enable auto-start at boot time.
sudo systemctl enable opendkim
OpenDKIM listens on 127.0.0.1:8891
.
Step 6: Connect Postfix to OpenDKIM
Edit Postfix main configuration file.
sudo nano /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. Note that you should use 127.0.0.1
as the address. Don’t use localhost
.
# Milter configuration milter_default_action = accept milter_protocol = 6 smtpd_milters = inet:127.0.0.1:8891 non_smtpd_milters = $smtpd_milters
Save and close the file. Then add postfix
user to opendkim
group.
sudo gpasswd -a postfix opendkim
Restart postfix
service.
sudo systemctl restart postfix
Step 7: SPF and DKIM Check
Now you can use your desktop email client or webmail client to send a test email to [email protected]
and get a free email authentication report. Here’s the report I got from port25.com.
You can also send a test email from your mail server to your Gmail account to see if SPF and DKIM checks are passed. On the right side of an opened email message in Gmail, if you click the show original
button from the drop-down menu, you can see the authentication results.
If your message is not signed and DKIM check failed, you may want to check postfix log (/var/log/maillog
) to see what’s wrong in your configuration.
Your email server will also perform DKIM verification on incoming emails. You can see the results in the email headers. The following is SPF and DKIM check on a sender using Gmail.
Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2607:f8b0:4864:20::c2d; helo=mail-yw1-xc2d.google.com; [email protected]; receiver=<UNKNOWN> Authentication-Results: email.linuxbabe.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com [email protected] header.b="XWMRd2co"; dkim-atps=neutral
How to Configure OpenDKIM For Multiple Domains
I have written a guide to hosting multiple domains on CentOS 8/RHEL 8 mail server with PostfixAdmin. In that article, I used Amavis for DKIM signing and verification. I you use OpenDKIM, then you need to skip step 3 in that article.
To configure OpenDKIM for multiple domains, you need to add the other domains in the signing table, key table and trusted hosts file like below.
Signing table:
*@domain1.com 20200308._domainkey.domain1.com *@domain2.com 20200308._domainkey.domain2.com
Key table:
20200308._domainkey.domain1.com domain1.com:20200308:/etc/opendkim/keys/domain1.com/20200308.private 20200308._domainkey.domain2.com domain2.com:20200308:/etc/opendkim/keys/domain2.com/20200308.private
Trusted hosts:
127.0.0.1 localhost .domain1.com .domain2.com
Then generate the DKIM Private/Public keypair and add the DKIM public key in DNS as mentioned in step 3, step 4 and step 5 for other domains. Restart OpenDKIM and you are done.
sudo systemctl restart opendkim
Configuration Error in Email Client
DKIM signing could fail if you don’t use the correct SMTP/IMAP settings in your email client.
Correct Settings:
- SMTP protocol: enter
mail.your-domain.com
as the server name, choose port 587 and STARTTLS. Choosenormal password
as the authentication method. - IMAP protocol: enter
mail.your-domain.com
as the server name, choose port 143 and STARTTLS. Choosenormal password
as the authentication method.
or
- SMTP protocol: enter
mail.your-domain.com
as the server name, choose port 465 and SSL/TLS. Choosenormal password
as the authentication method. - IMAP protocol: enter
mail.your-domain.com
as the server name, choose port 993 and SSL/TLS. Choosenormal password
as the authentication method.
Wrong Settings:
- Use port 25 as the SMTP port in mail clients to submit outgoing emails.
- No encryption method was selected.
Port 25 should be used for SMTP server to SMTP server communication. Please don’t use it in your email client to submit outgoing emails.
You should select an encryption method (STARTTLS or SSL/TLS) in your email client.
Next Step
I hope this tutorial helped you install and configure OpenDKIM on CentOS 8/RHEL 8 mail server. Now you may want to read the following tutorial to set up OpenDMARC to block email spoofing.
As always, if you found this post useful, then subscribe to our free newsletter to get more tips and tricks. Take care 🙂
Thank you !
Your tutorials are pure gold.
Thanks for the tutorials, they are clear and well written!
I followed all the steps thus far and everything is working as expecting, however there is a problem with the connection between Postfix and OpendKim.
When checking the logs I see the following:
Therefore, the DKIM signature is not coming through with my emails.
When sending an email through PostfixAdmin it also takes a while because it is timing out I suppose.
I hope you have a clue what it might be. (I checked the internet and tried many things but I can’t seem to find an answer)
Please note, I run Centos 7.
Well, after a good night of sleep and some coffee I finally tackled the problem this morning.
I was my own fault because I set up iptables configuration to strict and therefore not allowing any internal traffic.
Added following rules and it works:
I note I always get the same private and public strings as you do in the example when I run opendkim-genkey. How do I seed it differently?
Ah dumb question – it just looks he same near the beginning and the end.
Hello, at step 5 when i execute the opendkim-testkey command i receive: key 20200527._domainkey.localdomain.com: invalid key version ‘spf1-all’. Why? Can’t find any thread about that.
It seems you put your SPF record into the DKIM record.
This doesn’t seem to be a valid RSA public key: RSA.xs:178: OpenSSL error: bad base64 decode at blib/lib/Crypt/OpenSSL/RSA.pm (autosplit into blib/lib/auto/Crypt/OpenSSL/RSA/new_public_key.al) line 91.
Thanks man, it work for me ^_^
Hi,
Thanks for putting together these tutorials, they have been of immense help over the years.
I used most of your CentOS 8 postfix setup, including spf, dmarc, and dkim. This was over a year ago and things have been running fine since. One of my users contacted me recently saying they couldn’t send email. It was a case of it working on the Friday to not working on the Monday morning. No manual changes, deletions or additions had been made on the mail server, there were automated updates that installed over that weekend but none that obviously related to the problem. All other domains continued working just fine.
A check in the logs showed (the only change made is substituting the domain name with ‘example’ and the content of the keys):
Dig from the mail server worked:
The key test worked:
I removed the /etc/opendkim/keys/example.co.uk directory and contents.
Shutdown, halted and restarted the server
Recreated the directory
I switched out the key using:
Made the necessary changes in SigningTable:
and to the KeyTable:
The key test worked:
Dig from the mail server worked:
After rebooting it continues with the original error:
I have double checked paths and permissions.
I have several other domains in the same mail server, configured identically, none of which exhibit this behaviour, even after I update their keys.
I have tried doing the test with opendkim and postfix as the user with the same (correct) results
I have tried reducing the dns ttl to 10 minutes. I’m pretty sure DNS itself is not the issue, but I’m aware caching can be an issue, hence dropping the ttl (which apparently did nothing) after the original ttl expired.
I’m hoping you might have some suggestions, I’m stumped.
Kind regards and many thanks
Nigel.
I have installed opendkim but when i run the following command, it show an error:
Any ideas?
sudo dnf install opendkim-tools
sudo dnf install opendkim-tools
Problem:
In you DNS manager, create a TXT record, enter 20200308._domainkey in the name field.
Test DKIM Key
So, it looks like you need to append your domain name to the TXT record name
This helps me with err about opendkim not signing mails.
https://serverfault.com/a/861701
Thanks a lot! I had to add this to my /etc/opendkim.conf because it just refused to listen on port 8891. Other than this, I followed the guide to a tee and it went flawlessly.
Socket inet:[email protected]