I have documented some aspects of running a small business/home server on a Raspberry Pi. One advantage is that you retain control over email rather than handing over that critical function to a third party.  It really is quite straight forward to set up postfix and dovecot for this, and I have documented on this blog various astonishingly effective anti-spam options too.  Sending email remains under your control too, and there are various things you can add that help ensure your email server is regarded as a first class net citizen, such as adding an SPF record to your DNS that just gives the receiver some certainty that you are who you say you are.

Another such option is the domain keys identified mail standard, DKIM. This system merely adds to the certainty of the receiver that your email is from who you say you are. It does not directly mean your email will not be flagged as spam (inadvertently, of course....) but it does increase the chance of being a more trusted communication.  Some service providers place a greater emphasis on DKIM-signed email than others, but it is becoming more worth while to add this service.

There are plenty of how-to's on the internet to help set up a server.  The simplest example was from the Gentoo project, long known for the excellence of their documentation.   However, we run multiple domains on our little server, so, it seemed, we needed to follow the instructions for how to sign email from multiple domains.  However, this seems overkill.  Al the domains are under our control, so surely it would be possible to use just a single key?

This turned out to be harder than it seemed.  Part of the problem is the confusing terminology the DKIM standard uses, an inevitable legacy of competing systems being amalgamated into the standard.  Words like "selector", "domain" (not always what you think), need to be understood, as well as the rather subtle difference between a file called SigningTable and KeyTable.  I had difficulty wrapping my head around it al conceptually, but fortunately this is one of those services that it is safe to experiment with, for a short time anyway, as an invalid DKIM signature is, unfortunately, not too rare an event. So I cobbled something together to get the system to sign emails than pieced together a way of achieving the outcome I wanted. I installed opendkim as per various instructions and went ahead.

The first change was to get opendkim to use a local socket rather than a port, a personal preference when there is a choice.  This meant editing /etc/default/opendkim (this is on Raspbian Stretch, by the way).  I made the socket line

  SOCKET="local:/var/spool/postfix/opendkim/opendkim.sock" # default

Note the full path, which means the socket is accessible to the chroot jail in which postfix runs.  (Also remember later that you drop the "/var/spool/postfix" bit when telling postfix about it, because the jail becomes the top level.)  Follow instructions if adding Milter lines, as you wil find on the web, but you may have to check permissions of the socket. I had to add the postfix user to the opendkim group for it to work.  The system log, or the wretched journalctl systemd equivalent, will give you errors to point out the issue.

I decided to call my selector "mail" and generated keys for the main domain on which the server runs, using the opendkim-genkey utility.  This created a pair of keys, mail.private and mail.txt

To cut a long story short, and if you are reading this, chances are you have read loads else on the subject, I ended up with a KeyTable file with a single line, with <MAIN_DOMAIN> standing in for my domain name, in the hope of making this clear:-

mail._domainkey.<MAIN_DOMAIN> <MAIN_DOMAIN>:mail:/etc/opendkim/keys/mail.private

Also, the SigningTable file was a single line:-

* mail._domainkey.<MAIN_DOMAIN>

The two files above mean that al email going through the server will be signed as coming from the domain <MAIN_DOMAIN>, which is fine, as the email server advertises itself as mail.<MAIN_DOMAIN>.  If you wanted to use a single key, but wanted the DKIM domain to be the same as the sender's domain, alter the KeyTable file, and instead of the second <MAIN_DOMAIN> entry, use a percentage sign, %.  However, I think this may add complications, unless your server advertises itself by various domains too.

I could now send an email, and find that the email included a DKIM header, noting the selector as "mail" and the domain of <MAIN_DOMAIN>, in spite of the fact that I was sending from a different domain name.

Then came adding the public key to the DNS.  At first, I thought I would have to do this for all the domains under our control, but in fact, it only needs to be set in the <MAIN_DOMAIN> DNS, as that is the domain where the receiver checks. This seems to me to be another advantage of running it this way.  You'll add a TXT entry for a subdomain <SELECTOR>._domainkey.<MAIN_DOMAIN> and then add the contents of the mail.txt public key you generated earlier.  This was a little confusing, as the public key was in two blocks, separated by quote marks, and my DNS provider seemed to want it all on one line.  I simply edited the generated file to make it a single block.

The easiest test is to send an email to a gmail account, and then check the email. In my case, after some fiddling with the DNS, I saw a "PASS" notification.  Job done.

I know some enviable people will be able to read the documentation for services like this, and get it, but I'm the type who needs to learn by doing. Fortunately that's possible in this case, and allows starting with following the guides on the internet and then making alterations as I understood the various pieces better, eventually ending up with my bespoke installation.

I should add that I may well have completely misunderstood DKIM and how to implement it, so use your own discretion and understanding in deciding whether the info on this page is a help or a hindrance to you.