The Halon platform features DKIM (DomainKeys Identified Mail), which is based on our open source DKIM library. DKIM provides 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 to sign outbound messages using signDKIM (EOD per recipient).
Signing outbound messages
The only requirement to deploy DKIM is domain control, since a DNS record needs to be added for each domain.
- Create a private key (RSA 2048 bit key as recommended by RFC8301). Add a key statically, either in the Halon configuration (on the Configuration -> 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 that can then be queried using API calls. This key should be kept private, as it is used to protect the integrity of your signature.
If using the former alternative, generate a DNS record easily by selecting the new private key on the Certificates and keys page, and clicking on the Details button; this bringing up a new page. Click on the DKIM record button, enter a domain and a selector, and click on Generate; this creating a DNS record that is ready to be used in a DNS editor.
- In the very end of the outbound DATA flow (EOD per recipient), either add a static "DKIM delivery" block, or create a script that invokes the signDKIM function. The graphical "DKIM delivery" block has a function that can help generating the TXT entry for your DNS server to a subdomain of selector._domainkey.domain (for example, spaceship._domainkey.halon.se).
The selector is a sub-domain/name-space/identifier for the key currently being used; this allowing to rotate keys, but still keep the old ones for a while. So when updating the key, the selector should also be updated. Any desired selector can be selected and used, 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 desired domain (halon.se) or $senderdomain. The simplest approach to deploy DKIM is to use a single domain. The only disadvantage is that this does not allow you to deploy, except for that domain (Author Domain Signing Practices, which this document does not cover).
Each signed domain (possibly $senderdomain) should provide the *public key* in its DNS server. Once done, the public key should be verified to be looking valid. In a terminal on a computer, run the following (with the own, specific values).
host -t txt spaceship._domainkey.halon.se
Or, if using Windows, as follows.
nslookup set q=txt spaceship._domainkey.halon.se
The response should look something like the following.
v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCocO7k2Nioo2T...
Both header and envelope from $senderdomain can be spoofed by the sender. In a hosted environment, the DKIM key signing would probably preferably be enforced to be based on a trusted variable, such as $saslusername. The following example illustrates how a system, which 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"]);