PCR-360 Wiki

Configuring Sendmail with DKIM

DKIM Configuration Guide for Sendmail

Overview

DKIM requires two parts: a private key on the sending server (signs outgoing mail) and a public key in DNS (receiving servers verify against it).


Part 1: Server Side

  1. Install OpenDKIM

Debian/Ubuntu

apt install opendkim opendkim-tools

RHEL/CentOS

yum install opendkim

  1. Generate the Key Pair

mkdir -p /etc/opendkim/keys/yourdomain.com
opendkim-genkey -b 2048 -d yourdomain.com -D /etc/opendkim/keys/yourdomain.com -s mail -v

Creates:

mail.private (keep secret on the server)

mail.txt (goes into DNS as a TXT record)

  1. Set Permissions

chown -R opendkim:opendkim /etc/opendkim/keys
chmod 600 /etc/opendkim/keys/yourdomain.com/mail.private

  1. Configure OpenDKIM (/etc/opendkim.conf)

Mode sv
Canonicalization relaxed/simple
Domain yourdomain.com
Selector mail
KeyFile /etc/opendkim/keys/yourdomain.com/mail.private
Socket inet:8891@localhost
TrustAnchorFile /usr/share/dns/root.key

  1. Connect OpenDKIM to Sendmail (/etc/mail/sendmail.mc)

Add this line before the MAILER definitions:
INPUT_MAIL_FILTER(opendkim', S=inet:8891@localhost')dnl

Rebuild and restart:
m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
systemctl restart opendkim
systemctl restart sendmail

  1. Verify OpenDKIM is Signing

Watch opendkim logs

journalctl -u opendkim -f

Send a test and inspect headers for DKIM-Signature

echo "Test" | sendmail -v someone@gmail.com


Part 2: DNS Side

What to publish

Get the public key generated earlier:
cat /etc/opendkim/keys/yourdomain.com/mail.txt
It will look like:
mail._domainkey IN TXT ( "v=DKIM1; k=rsa; "
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..." )

Records to add

┌──────┬────────────────────────────────┬──────────────────────────────────┐
│ Type │ Name │ Value │
├──────┼────────────────────────────────┼──────────────────────────────────┤
│ TXT │ mail._domainkey.yourdomain.com │ contents of mail.txt │
├──────┼────────────────────────────────┼──────────────────────────────────┤
│ TXT │ yourdomain.com │ v=spf1 ip4:<your-server-ip> ~all │
└──────┴────────────────────────────────┴──────────────────────────────────┘

Note: Use ~all (softfail) on SPF while testing, then harden to -all (hardfail) once confirmed working.


Part 3: Verify End-to-End

Once DNS propagates (minutes to 48hrs):

Confirm DNS record is live

dig txt mail._domainkey.yourdomain.com

Test key is valid and matches DNS

opendkim-testkey -d yourdomain.com -s mail -vvv

Send a test to a Gmail or Outlook account and check the message headers:
dkim=pass
spf=pass

Or use https://www.mail-tester.com — send an email to the address it provides and it will score your full mail configuration including DKIM, SPF, and DMARC.


Summary Checklist

Server:

  • OpenDKIM installed and configured

  • Key pair generated

  • Sendmail connected to OpenDKIM via milter

  • Services restarted

DNS (whoever manages your domain's DNS):

  • mail._domainkey.yourdomain.com TXT record added (DKIM public key)

  • yourdomain.com TXT record added (SPF)

Verification:

  • dig confirms DNS records are live

  • opendkim-testkey passes

  • Test email shows dkim=pass and spf=pass in headers

Checking everything works

From server logs

By default OpenDKIM logs to the syslog, so you can tail the log to see if signing is successful using:

sudo tail -f /var/log/syslog | grep -i dkim

You should see something like this example taken from one of the web servers that host this blog:

Mar 16 09:25:02 web2 sm-mta[7705]: u2G9P2Dp007705: Milter insert (1): header: DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=web2.lon.codacity.net;\n\ts=linode; t=1458120302;\n\tbh=C8sxHQz0QeFsCiNzhPYF8u2GVHRax8cSsYISckkpuEk=;\n\th=Date:From:Subject:To:From;\n\tb=ymr4SQ67DqXBMkVPPfjTJUEWBPFpO4jix7oZXsranp6MQrzcXg8ysbwkL0+6VdcqA\n\t DrzTrz3O6SfVh9Aok6H+tGcPIb9jMGTn1ceLlAZhy18O5qmjkZOTHr2MWtKeaf1u2M\n\t FfBBOID4M9vef7FZBJaUa0j+Zg9LarLaYW518TEo=

From your mail client

View the source of an email sent from your server and look for the Authentication-Results header. It should contain dkim=pass if everything is working. There is also a DKIM-Signature header which contains the signing data.