mjl- / mox

modern full-featured open source secure mail server for low-maintenance self-hosted email
https://www.xmox.nl
MIT License
3.61k stars 105 forks source link

DKIM failing with MXToolbox #15

Open maskimfr opened 1 year ago

maskimfr commented 1 year ago

Hello,

I'm testing mox on a test with a test domain, and I really like it. Thank you for your work !

Everything seems to works correctly for now, except that mxtoolbox is issuing an issue with DKIM (DKIM is working find with other tools). Here is the report: https://mxtoolbox.com/deliverability/4ae934f5-ed69-494e-9562-9a84191461f3

Do you know why it happens ?

mjl- commented 1 year ago

Good to hear you're giving it a try!

It's not immediately obvious from the report what the problem is.

The first error is about selector 2023a. That selector uses ed25519. Not all mail servers support that yet. They seem to recognize ed25519 in the selector DNS record, but not in the DKIM-Signature message header. Clicking the red message shows some details. It fails on "DKIM Signature Syntax Check". I doesn't say what part of the syntax isn't correct. It shouldn't be the unknown algorithm ed25519, because that isn't invalid syntax to them, just an unrecognized algorithm. But perhaps they are being a bit loose with terminology. Anyway, I think they just don't implement ed25519, like more mail servers. This is why there is a second signature.

The second error is about selector 2023b. That selector uses rsa. All dkim verifiers support rsa signatures. This fails on signature verification. That means the DKIM-Signature looks valid, and probably the "body hash" ("bh=") is valid. But verifying the rsa signature ("b=") over the headers + bodyhash fails. This could happen if the DKIM public key record they fetched does not match the DKIM private key used to sign the headers+bodyhash. It could also be due to a different interpretation of the message headers, leading them to a different signature. The page you linked mentions the public key, it is what I'm getting back now too when I look up the DNS record. I also saved your message to a local file test.eml (with \r\n line endings), and ran "mox dkim verify test.eml", and mox thinks the signatures are valid. So, it's not a problem with the DKIM DNS record. There may be something different with how they interpret the email headers. I have a few ideas, I'll try to do a few tests to see if I can make the error go away. If you want to try the mox dkim verify command, be sure to try the validation with a modified body (should return an error "dkim: body hash does not match") and again with only a header changed (should return an error "dkim: signature verification failed").

mjl- commented 1 year ago

I can get a passing signature by changing header canonicalization from the default ("simple") to "relaxed" and removing the ed25519 signature. If I leave the ed25519 signature in, they claim the rsa signature is invalid. So by signing the message with both ed25519 and rsa, then removing the ed25519 dkim-signature header, you get a green checkmark from them. I think those signature headers should be independent, I don't know why they influence each other in their validator.

The header canonicalization setting determines how whitespace is handled in headers. I'm assuming mxtoolbox works for some people at least. So I suspect mox is creating headers with certain whitespace in a way other mail servers are not generating them. And that this is tripping up mxtoolbox. I created test messages that just signed From, Subject and Date. Those messages have no special whitespace an implementation could break on. The DKIM-Signature header itself is also used in verification and handled specially. I suspect they do something differently there. I sent test messages to gmail.com, outlook.com, proton.me with mox, and they can all validate the rsa dkim-signature header (and proton can verify the ed25519 dkim-signature too). That leads me to believe mox is creating correct signatures.

If mxtoolbox is using commonly used software to validate dkim signatures, it could be worth trying to create dkim-signature headers that don't trip them up.

I'm also open to other analyses. (:

maskimfr commented 1 year ago

Thank you for analyzing this so quickly. DKIM signature is also valid when sent to a mailu server (https://github.com/Mailu/).

Another weird thing. On https://appmaildev.com/en/dkim, the mail sent above to is valid. But a mail sent to a mailu server doesn't have a valid signature according this website (but it's valid according mailu...). The only difference that I can see, is that one is sent through IPv6, the other is sent through IPv4.

Mail-fail-appmaildev.txt

It's maybe just an issue with these tools and it will never be an issue with real servers.

mjl- commented 1 year ago

I'm also getting "bad signature" errors with that message, both at that website and with "mox dkim verify". But messages directly from mox are verified correctly by appmaildev.com.

The DKIM-Signature headers in that message look different than what mox would generate. The leading tab has been replaced with a space. And the "b=" tag starts on a new line. If you put it back on the previous line you'll see it fills the whole line again. Still doesn't make the message valid. Could you compare the message you sent to mailu with the message as you get it out of it? Would be interesting if it is modifying that header...

I can imagine tools hoping that the "b=" tag is on a separate line. The dkim signature that is verified (and signed), is over data including the signed headers, plus the DKIM-Signature header with the value of the "b=" tag removed (because that's the cryptographic signature, i.e. what you are calculating). To remove the "b=" value during verification correctly, you need a proper parser, you cannot (always) just strip off the last lines of the dkim-signature header. See the signature parsing code at https://github.com/mjl-/mox/blob/ba077dadd0202ca1cc7c691066cbab9a960a0053/dkim/sig.go#L254.

0xc1f commented 1 year ago

I have exactly the same issue with mox as it seems to be altering the messages somehow. Surprisingly, messages sent using Thunderbird pass the DKIM verification.