Using DKIM to Sign and Validate Mail
Background
Domain Keys Identified Mail (DKIM) is an email authentication method designed to detect email spoofing. It 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 is intended to prevent forged sender addresses in emails, a technique often used in phishing and email spam. - Wikipedia
Requirements
In order to implement DKIM you need your own domain and a functioning SMTP Server (postfix) for the domain. I will use mydomain.com as an example domain.
Installation and Configuration
Install the app:
yum install opendkim
To set up the key I suggest using date type identifier in the format YYYYMM, using the current month e.g. 201801. In the guide replace YYYYMM with the identifier you have chosen.
Generate the key:
mkdir /etc/opendkim/keys/mydomain.com cd /etc/opendkim/keys/mydomain.com opendkim-genkey -r -h sha256 -b 2048 -d mydomain.com -s YYYYMM -v chown -R opendkim:opendkim /etc/opendkim/keys/mydomain.com
Add to '/etc/opendkim/KeyTable':
YYYYMM mydomain.com:YYYYMM:/etc/opendkim/keys/mydomain.com/YYYYMM.private
Add to '/etc/opendkim/SigningTable':
*@mydomain.com YYYYMM
Edit the file '/etc/opendkim.conf' and:
- Change “Mode” to “sv”
- Change “SoftwareHeader” to “no” but can leave as “yes”. no cuts down the header a bit.
- Comment out “KeyFile”
- Uncomment KeyTable
- Uncomment SigningTable
- Uncomment ExternalIgnoreList
- Uncomment InternalHosts
- Add:
AutoRestart Yes AutoRestartRate 10/1h RemoveOldSignatures True
You should end up with a file like (comments and blank lines removed):
PidFile /var/run/opendkim/opendkim.pid Mode sv Syslog yes SyslogSuccess yes LogWhy yes UserID opendkim:opendkim Socket inet:8891@localhost Umask 002 SendReports yes SoftwareHeader no Canonicalization relaxed/relaxed Selector default MinimumKeyBits 1024 KeyTable /etc/opendkim/KeyTable SigningTable refile:/etc/opendkim/SigningTable ExternalIgnoreList refile:/etc/opendkim/TrustedHosts InternalHosts refile:/etc/opendkim/TrustedHosts OversignHeaders From AutoRestart Yes AutoRestartRate 10/1h RemoveOldSignatures True
Now you need to update your DNS records. Open the file '/etc/opendkim/keys/mydomain.com/YYYYMM.txt'. In your DNS records, create a new TXT record with a subdomain as the first field in the file which you can just copy. In this case it is “YYYYMM._domainkey”. For TXT Data copy and paste everything between the first and last set of quotes, excluding the first and last quotes and removing the middle quotes and whitespace between them.
As an example for the TXT record (shortened as real one breaks the howto formatting):
YYYYMM._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; s=email; " "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8" "4CbTaxZtzVcoVrkrHUTo" ) ; ----- DKIM key YYYYMM for mydomain.com
becomes:
v=DKIM1; h=sha256; k=rsa; s=email; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ84CbTaxZtzVcoVrkrHUTo
Now start OpenDKIM and set it to start automatically:
systemctl start opendkim.service systemctl enable opendkim.service
Test your DNS record and signing:
dig -t any YYYYMM._domainkey.mydomain.com opendkim-testkey -d mydomain.com -s YYYYMM -vvv
The first command should return your TXT record you have just created. The second should give a “key OK” message.
Set up SMTP Server (postfix) by adding to /etc/postfix/main.cf:
smtpd_milters = inet:127.0.0.1:8891 non_smtpd_milters = $smtpd_milters milter_default_action = accept milter_protocol = 6
You can put this anywhere in the file. The usual practice is to put it after the smtpd_recipient_restrictions entry.
Then restart postfix:
systemctl restart postfix.service
After this you can also send a test e-mail to check-auth@verifier.port25.com and you should get an automatic reply with a few test results including DKIM testing.
Periodic Maintenance
Periodically you should be generating and using new keys. Best practice says to do this monthly. Semi-yearly should be the minimum. This is why we have generated keys in the YYYYMM format. To change keys, you should:
- Generate a new key
- Add a new line to /etc/opendkim/KeyTable
- Change the line in /etc/opendkim/SigningTable to the new YYYYMM
- Create a new DNS TXT record with the data in the new YYYYMM.txt file. Do not remove the old record yet
- Validate the new record with opendkim-testkey
If the new key validates correctly:
- Restart OpenDKIM and Postfix
- Validate your new key by sending a test e-mail to check-auth@verifier.port25.com and checking the reply.
- A couple of weeks later you can then delete the old DNS TXT record from your DNS as all mail in transit will have been delivered.
Optional
Author Domain Signing Practices (ADSP)
You can add an ADSP policy to your domain saying that all emails from your domain should be DKIM-signed. It’s done with another TXT record for your mail domain _adsp._domainkey.domain in your domain with a value of dkim=all or dkim=discardable. You don’t need to set this up, but, if you do, it makes it harder for anyone to forge email from your domains because recipient mail servers will see the lack of a DKIM signature and reject the message.
Domain Message Authentication, Reporting & Conformance (DMARC)
DMARC is a way of publishing a policy which advises receiving mail servers how to treat e-mail failing DKIM and/or SPF validation. It uses another DNS record to do this but the implementation is not covered by this guide. It also gives the recipient an e-mail address to report e-mails failing the DMARC policy.
dmarc.org
Sonicwall explanation of DMARC
Wizard to create DMARC TXT record
SPF Wizard