IPv4 Address:-
IPv6 Address:-
Service Provider:-
SSL Information:-
HTTP Protocol:-
Add DKIM Signing to FreeBSD Servers [01/Jun/2016]   NetFlow v9 Exporting from FreeBSD routers/firewalls     CARP (IPv4 and IPv6) in FreeBSD 10+ (for failover IPs)  

In today's very spammy internet, it becomes increasingly important to verify the source of emails are valid (this is especially true if you want to send emails to gmail or outlook.com!)

One method is to add DKIM signing to outbound emails.

This will detail how to add DKIM signing to a stock FreeBSD server (e.g. a webserver) using sendmail.

First, we need to install the DKIM package:

pkg install opendkim Copy

Now, we need to edit /usr/local/etc/mail/opendkim.conf and change the following lines:

Canonicalization  relaxed/simple
KeyTable          refile:/usr/local/etc/mail/opendkim.keytable
LogWhy            yes
Selector          myselector
SigningTable      refile:/usr/local/etc/mail/opendkim.signingtable
Socket            local:/var/run/dkim/opendkim.sock
SyslogSuccess     Yes
UserID            mailnull:mailnull Copy

You can change myselector to anything you wish to use.  This will form part of the DNS entry required for signature verification so it should be fairly unique (this allows you to have different DKIM signing keys for different servers/services.  I often call them based on the server name.

And we need to do a few steps to setup things:

touch /usr/local/etc/mail/opendkim.keytable
touch /usr/local/etc/mail/opendkim.signingtable
mkdir -p /var/run/dkim /var/db/dkim
chown mailnull:mailnull /var/run/dkim /var/db/dkim
chmod 0700 /var/run/dkim Copy

This creates some files and folders, and sets the necessary permissions.

Now we need to tell opendkim to start on boot, add to /etc/rc.conf the following:

milteropendkim_cfgfile="/usr/local/etc/mail/opendkim.conf" Copy

and now we can start with:

service milter-opendkim start Copy

If all is well, you'll see two copies of opendkim running in your process list.

Finally, we need to tell sendmail to sign emails that go out.

cd /etc/mail
cp freebsd.mc dkimsigned.mc Copy

Now edit /etc/mail/dkimsigned.mc and add the following lines just before the 'MAILER' lines:

INPUT_MAIL_FILTER(`opendkim’, `S=local:/var/run/dkim/opendkim.sock’)dnl
define(`confINPUT_MAIL_FILTERS', `opendkim')dnl Copy

Now we can build a new sendmail configuration file and activate it:

cd /etc/mail
make dkimsigned.cf
mv sendmail.cf sendmail.cf.pre-dkim
cp dkimsigned.cf sendmail.cf
service sendmail restart Copy

Now, at this point, nothing has really changed as we haven't given opendkim any domains to sign.

I wrote a handle script for generating new DKIM configuration... Add the following lines to a script called generate-dkim somewhere in your path:



if [ -z ${1} ]; then
        echo "Usage: ${0} <domain>"
        exit 1

if [ -f /var/db/dkim/${DOMAIN}/${SELECTOR}.txt ]; then
        echo "=> ERROR: found DKIM keys for ${DOMAIN} already"
        /bin/cat /var/db/dkim/${DOMAIN}/${SELECTOR}.txt
        exit 1

echo "==> Generating DKIM key for ${DOMAIN}..."
/bin/mkdir /var/db/dkim/${DOMAIN}
/usr/sbin/chown mailnull:mailnull /var/db/dkim/${DOMAIN}
/usr/local/sbin/opendkim-genkey -a -b 2048 -d ${DOMAIN} -D /var/db/dkim/${DOMAIN} -s ${SELECTOR}
/usr/sbin/chown mailnull:mailnull /var/db/dkim/${DOMAIN}/*
echo "==> Done"
echo "==> Updating config to enable DKIM signing..."
echo "${SELECTOR}._domainkey.${DOMAIN}      ${DOMAIN}:${SELECTOR}:/var/db/dkim/${DOMAIN}/${SELECTOR}.private" >> /usr/local/etc/mail/opendkim.keytable
echo "*@${DOMAIN}       ${SELECTOR}._domainkey.${DOMAIN}" >> /usr/local/etc/mail/opendkim.signingtable
echo "==> Done"
echo "==> Reloading OpenDKIM configuration…"
/bin/pkill -USR1 -F /var/run/milteropendkim/pid
echo "==> Done"
echo "DKIM DNS entry to add is below:"
/bin/cat /var/db/dkim/${DOMAIN}/${SELECTOR}.txt Copy

If you chose a different 'selector' in the earlier step, remember to change the SELECTOR= line above to match or your signing wont work!

And dont forget to make it executable:

chmod a+x generate-dkim Copy

Now, whenever we want to add a new signing domain, for example dan.me.uk, we can run

generate-dkim dan.me.uk Copy

This will generate a new key, add it to the opendkim configuration files, reload opendkim, and output the required DNS entry to you.

If you've previously added the domain, it will just show the DNS entry to you without modifying anything.

Now any emails sent out with a sender of *@dan.me.uk will be DKIM signed using the key generated in the step above.

You MUST add the DNS entry to the domain's DNS zone for DKIM signing to work.  If the receiving mailserver can't lookup the DNS entry then it can't verify your email!

If you ever need to remove a domain from signing, you have to do this manually...

Remove it from /usr/local/etc/mail/opendkim.keytable and /usr/local/etc/mail/opendkim.signingtable (one line in each file), then there's a folder in /var/db/dkim/ named after the domain which needs to be removed.

For the best chance of delivering to the world's biggest spammers (gmail/outlook/aol/yahoo/etc), I would recommend SPF, DKIM and DMARC!

  NetFlow v9 Exporting from FreeBSD routers/firewalls     CARP (IPv4 and IPv6) in FreeBSD 10+ (for failover IPs)  
Copyright © 2023 Daniel Austin MBCS.
Proudly hosted using the FreeBSD operating system.
E-mail me
E-mail me
padlock icon
LOGIN ERROR#123: random error here