Skip to content

Verifying

A DKIM signature tells a receiver which domains have taken responsibility for a message, but only once the receiver has verified it. Stalwart verifies the DKIM signatures of the messages it receives at the DATA stage and records the result. The result is used in three places: by DMARC, by the spam filter, and in the Authentication-Results header of the message. Verification is configured on the SenderAuth singleton (found in the WebUI under Settings › MTA › Inbound › Sender Authentication).

dkimVerify is an expression that returns one of three modes. The default is relaxed for every session, which means that signatures are verified but never cause a rejection:

ModeEffect
relaxedVerify the signatures and record the results; never reject. Failure reports are sent to domains that request them.
strictVerify the signatures, and refuse the message unless at least one DKIM signature verifies (DKIM2 signatures do not count): 550 5.7.20 No passing DKIM signatures found., or 451 4.7.20 when the failure is a temporary DNS error. It also defers messages whose DKIM2 chain cannot be verified because of a temporary DNS error, when they would be signed with DKIM2 for a recipient on another system (DKIM2).
disableDo not verify, unless DMARC verification needs the results, in which case the signatures are verified without any rejection.

strict also refuses messages that carry no signature at all. It therefore suits only listeners or senders that are known to sign every message, for example a link with a partner. The following expression applies it only to mail from one network:

{
"dkimVerify": {
"match": {"0": {"if": "is_ip_in_cidr(remote_ip, '198.51.100.0/24')", "then": "strict"}},
"else": "relaxed"
}
}

To act on the sender domain’s own policy for unauthenticated mail, use DMARC verification instead. That policy combines DKIM with SPF and alignment.

Some signatures are treated as if they were absent, with a result of neutral:

  • Signatures that use RSA with SHA-1 (a=rsa-sha1), and RSA signatures made with keys shorter than 1024 bits. RFC 8301 requires verifiers to reject both. Ed25519 (RFC 8463) and RSA-SHA256 signatures are verified.
  • Signatures that carry the l= tag, while dkimStrict is enabled.

The l= tag needs a word of explanation. It limits the signature to the first part of the body, so content appended after that part leaves the signature valid. An attacker can therefore add text or links to a legitimately signed message without breaking its signature. The dkimStrict setting guards against this, and it is enabled by default. It also applies to ARC message signatures that carry the tag. Disabling dkimStrict makes Stalwart evaluate such signatures as well.

Each signature has its own outcome: pass, fail, neutral, temperror or permerror. An unsigned message has the result none. A message has passed DKIM when at least one of its signatures passes. The domains of the passing signatures are recorded in the Authentication-Results header, and system Sieve scripts at DATA can read them as env.dkim.domains (Variables).

When the message carries DKIM2 signatures, they are verified in the same step, as described in DKIM2.

When a signature fails and its domain asks for reports, Stalwart sends that domain a DKIM failure report (DKIM reports).