The Halon platform features DKIM (DomainKeys Identified Mail), which is based on our open source DKIM library. DKIM provides a cryptographic mechanisms to verify the integrity of a message. A DKIM signed message includes a DKIM-Signature header which contains a message signature that is based on public-key cryptography. DKIM uses DNS(SEC) as a carrier to provide the public keys.
In this article we will cover how you can sign outbound messages with signDKIM.
Signing outbound messages
The only requirement to deploy DKIM is domain control, since a DNS record needs to be added for each domain.
- Start by creating a private key (RSA 2048 bit key as recommended by RFC8301). You can either add a key statically in the Halon configuration (from the Configuration > Email server > Certificates and keys page, by adding a new PKI of type "private key" and leaving the "data" field empty) or in an external database which you then query using API calls. This key should be kept private as it is used to protect the integrity of your signature.
If you used the former alternative you can easily generate a DNS record by selecting the new private key under the Certificates and keys page, then click on the Details button. This will bring up a new page, here you can click on the DKIM record button and then enter a domain and selector, click on Generate and now you will see a DNS record that is ready to be used in a DNS editor.
- In the outbound DATA flow, either add a static "DKIM delivery" block to the very end of it, or create a script that invokes the signDKIM function.
The graphical "DKIM delivery" block has a help function to generate the TXT entry for your DNS server to a subdomain of selector._domainkey.domain (eg. spaceship._domainkey.halon.se).
The selector is a sub-domain/name-space/identifier for the key you are currently using; this allows you to rotate keys, but still keep the old ones for a while. So when you update the key, you should also update your selector. You can select and use whatever selector you want, as long as it is a valid domain name.
The domain defines which domain that guarantees the integrity of the message, depending on your implementation this can be either a domain of your choice (halon.se) or $senderdomain. The simplest approach to deploy DKIM is to use a single domain. The only disadvantage is that it doesn't allow you to deploy (Author Domain Signing Practices) except for that domain. (which this document doesn't cover).
Each domain (possibly $senderdomain) that you sign, should provide the public key in their DNS server. Once done, you should verify that your public key looks valid. On your computer, in a terminal, run (with your own values);
host -t txt spaceship._domainkey.halon.se
or if using Windows;
nslookup set q=txt spaceship._domainkey.halon.se
which should look something like this;
v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCocO7k2Nioo2T...
Both headers and envelope from ($senderdomain) can be spoofed by the sender. In a hosted environment you probably want to enforce the DKIM key signing based on a trusted variable such as $saslusername. The example below illustrates how a system that uses external API calls to fetch DKIM keys from a database uses the SASL username as a parameter.
$dkim = api_call("?type=dkim&user=$1&domain=$2", [$saslusername, $senderdomain]); if (is_array($dkim)) GetMailMessage()->signDKIM($dkim["selector"], $dkim["domain"], $dkim["rsakey"]);