Signing with DKIM
The Halon platform has support for 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.
Signing outbound messages
The only requirement to deploy DKIM is domain control, since a DNS record needs to be added for each domain. Do the following steps to enable DKIM signing.
- Create a private key (RSA 2048 bit key as recommended by RFC8301) and put it either in the Halon configuration 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.
- In the outbound EOD context add a script that invokes the signDKIM function.
The selector is a sub-domain/name-space/identifier for the key currently being used; this allows for rotation of 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 any desired domain (halon.se) or $transaction["senderaddress"]["domain"]
. 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).
DNS records
Each signed domain (possibly $transaction["senderaddress"]["domain"]
) 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 your 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...
Conditional signing
Both the "From" header and the envelope from ($transaction["senderaddress"]["domain"]
) can be spoofed by the sender. In a hosted environment, the DKIM signing should instead be based on a trusted variable, such as $connection["auth"]["username"]
. 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", [$connection["auth"]["username"], $transaction["senderaddress"]["domain"]]);
if (is_array($dkim))
$arguments["mail"]->signDKIM($dkim["selector"], $dkim["domain"], $dkim["rsakey"]);