Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Public DKIM available but not valid for SpamAssassin #2131

Open
luckk93 opened this issue Sep 7, 2020 · 20 comments
Open

Public DKIM available but not valid for SpamAssassin #2131

luckk93 opened this issue Sep 7, 2020 · 20 comments

Comments

@luckk93
Copy link

luckk93 commented Sep 7, 2020

Hi,
I'm trying to configure on a website a script to send automatic reply email using a gmail account.
I was able to generate the private DKIM keys using the PHPMailer script and to put the public key on the DNS successfully.

The problem is that when i try to send email with DKIM signature to Spam score check services they can access the public DKIM keys but they say it's invalid. In some services like ISnotSPAM, which perform multiple tests, the DKIM check pass, but in the SpamAssassin check the DKIM is considered invalid.

The sending page is in STMP debug mode and there are no error or fail during the sending process.
Am I doing something wrong, or is simply not possible in my case to configure the DKIM signature?

Below you can find the script I 'm using to send emails to Spam check services (clearly without personal data).

DKIM_question.txt

I'm sorry if this is not the correct place for this issue. If more information are required to debug the problem let's me know.

@XL-2000
Copy link

XL-2000 commented Sep 7, 2020

$mail->DKIM_private = 'phpmailer_dkim_private.pem'; contains no absolute path, check that the file is properly referenced and loaded. Up the debug level of PHPMailer, so you can see in the debug output if loading is correct

@luckk93
Copy link
Author

luckk93 commented Sep 7, 2020

$mail->DKIM_private = 'phpmailer_dkim_private.pem'; contains no absolute path, check that the file is properly referenced and loaded. Up the debug level of PHPMailer, so you can see in the debug output if loading is correct

I changed $mail->SMTPDebug = SMTP::DEBUG_SERVER; to $mail->SMTPDebug = SMTP::DEBUG_LOWLEVEL ;
and set the private_key to the absolute path, with no visible changes, in the DKIM result.

I don't see error loading the file but neither see it loading it.

Below a "copy" of the debug text.

debug_text.txt

@XL-2000
Copy link

XL-2000 commented Sep 7, 2020

SERVER: DKIM-Signature: v=1; d=mydomain.com; s=phpmailer;
There is no signature loaded there

@XL-2000
Copy link

XL-2000 commented Sep 7, 2020

It should read something like:

DKIM-Signature: v=1; d=XXX.YYY; s=ZZZ; a=rsa-sha256; q=dns/txt; t=1599482644; c=relaxed/simple; h=Date:To:From:Reply-To:Subject:Message-ID:X-Mailer:MIME-Version:Content-Type; i=AAA@BBB.CCC; bh=60R39+LJP2HyUwWgf8yWLf9HBdbJuknvEXSLSHSw4IE=; b=tadExRCoo5zVLbbQP8kX6YWqiqpMu3o5CZgVzsPQ8QJxkKn6uQvtVsYkZYyy0CXCMmXhPeqpo fwDLWxQlPFk7RVJuqGzwM52IX4e57bXNTR1xhIYb1sQHGbov43Mh5Y99mRo6xLKO3Hp2YPPu0 PadiXF6klbkyjjGuFG4+vbYwsTG4K4JkojUJLKSn1aoEjttLbHQ+g/BDyf05FI4bQU4QTFoMC rrWswbAZBrFsejH/2EzG89VUSnltfZa+bggk0bzls2kBgPbi8K4Jz48ryUtyo+t4bg4ikA//q 7AlQufYvSxKo5vBlZTrZWoEg76Hg9/rfAP7hBgRIklSZ4YRt8g==

So: surely the DKIM key is not loaded properly. Debug code there, check if the file is valid, readable, correct etc etc etc

@luckk93
Copy link
Author

luckk93 commented Sep 7, 2020

I tried to echo(file_get_contents()) using the same absolute path of the private key and it's shown in the log, so it's readable.

The file content is like:

-----BEGIN PRIVATE KEY----- MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCh95euw3eGUwrI ..................................................................................................................................................................... ENqrTY9fX5J+6sEg03HHTWYZIur6n4TU1gYXFrHjuz3X+qGXuQx7Qv+GbJOk/PMG dnwmzGdL3K1Ba/h/wP+H+g== -----END PRIVATE KEY-----

I don't know if this is the format it's supposed to have to be included correctly.
How can I know if it's valid/correct?

@Synchro
Copy link
Member

Synchro commented Sep 7, 2020

That debug output does contain a complete DKIM signature, so the signing is definitely happening. There are still some DKIM bugs lurking; can you try without setting an AltBody, and also as a plain text message by not calling isHTML().

It's odd that you're getting different verdicts from different receivers; that really shouldn't happen – but it's partly why I've been working on a PHP DKIM validator!

@luckk93
Copy link
Author

luckk93 commented Sep 7, 2020

I removed the AltBody, replaced msgHTML with plain text in Body, and put isHTML(false) or also no isHTML at all.
Below you can find the new code, new log and the report from ISnotSPAM

page_code.txt
page_log.txt
isnotspam_report.txt

No visible changes so far

@Synchro
Copy link
Member

Synchro commented Sep 7, 2020

That report shows it passing the DKIM check?

@luckk93
Copy link
Author

luckk93 commented Sep 7, 2020

That report shows it passing the DKIM check?

IT pass the DKIM check in the DKIM section but in the spamassasin section it say T_DKIM_INVALID DKIM-Signature header exists but is not valid

@XL-2000
Copy link

XL-2000 commented Sep 9, 2020

Just throwing a bone here....
Your email is singed using a private key, resulting in a signature which should be validated using a DNS public key.
The signature is present, but deemed invalid.
I thing this might be due to either missing or not-corresponding public key in DNS
Can you check this?
-0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain

Should be in your report.
Could you query the DNS record for your DKIM settings?
Using PHP (example) $dkimrecord = dns_get_record($selector.'._domainkey.'.$domain, DNS_TXT);

@luckk93
Copy link
Author

luckk93 commented Sep 12, 2020

Just throwing a bone here....
Your email is singed using a private key, resulting in a signature which should be validated using a DNS public key.
The signature is present, but deemed invalid.
I thing this might be due to either missing or not-corresponding public key in DNS
Can you check this?
-0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain

Should be in your report.

The report have for the DKIM section:

DKIM check details:
----------------------------------------------------------

Result: pass
ID(s) verified: header.From=sendingemail@gmail.com
Selector=20161025
domain=1e100.net
DomainKeys DNS Record=20161025._domainkey.1e100.net

----------------------------------------------------------
DKIM check details:
----------------------------------------------------------

Result: pass
ID(s) verified: header.From=sendingemail@gmail.com
Selector=phpmailer
domain=mydomain.com
DomainKeys DNS Record=phpmailer._domainkey.mydomain.com

and in the spamassissin section:

0.0 DKIM_ADSP_CUSTOM_MED No valid author signature, adsp_override is CUSTOM_MED
0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid
0.0 T_DKIM_INVALID DKIM-Signature header exists but is not valid

Could you query the DNS record for your DKIM settings?
Using PHP (example) $dkimrecord = dns_get_record($selector.'._domainkey.'.$domain, DNS_TXT);

Using:

<?php
$selector = 'phpmailer';
$domain = 'mydomain.com';
$dkimrecord = dns_get_record($selector.'._domainkey.'.$domain, DNS_TXT);
print_r(array_values($dkimrecord));

I get something like:

Array ( [0] => Array ( [host] => phpmailer._domainkey.mydomain.com [class] => IN [ttl] => 3505 [type] => TXT [txt] => v=DKIM1; h=sha256; t=s; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAofeXrsN3hlMKyEgcSpHhyc3vDuuzQYG5mAoJLh5qupapenaVMr+pgCtZqeQUYlpzqQazpqLPOVwJyePQ715ksRc2m0UBmAnipqbI2K2NPtXuxb/HTladTuNWNvT6+woL5St8FuP8UsxVSvmHjOWynVFttFpTRac48XpuDSqInEoZCRfOGncODaIFYnQomsgnxPkA77gMLZjxWYH/AjEgJOGudDTIopWvtQiRpgXvX48Q6cUkPGiVCgqhzzVAU54psNj3EtFMT12HmQHAcTkyqKeNAiupJ8JZowJJ2Wsd2nxPKJWVKMKxKZiUwGbafVrJ6WkC0NWm7COgaXGX71/hhQIDAQAB [entries] => Array ( [0] => v=DKIM1; h=sha256; t=s; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAofeXrsN3hlMKyEgcSpHhyc3vDuu [1] => zQYG5mAoJLh5qupapenaVMr+pgCtZqeQUYlpzqQazpqLPOVwJyePQ715ksRc2m0UBmAnipqbI2K2NPtXuxb/HTladTuNWNvT6+wo [2] => L5St8FuP8UsxVSvmHjOWynVFttFpTRac48XpuDSqInEoZCRfOGncODaIFYnQomsgnxPkA77gMLZjxWYH/AjEgJOGudDTIopWvtQi [3] => RpgXvX48Q6cUkPGiVCgqhzzVAU54psNj3EtFMT12HmQHAcTkyqKeNAiupJ8JZowJJ2Wsd2nxPKJWVKMKxKZiUwGbafVrJ6WkC0NW [4] => m7COgaXGX71/hhQIDAQAB ) ) )

I would say the public DKIM key is available from the DNS

@XL-2000
Copy link

XL-2000 commented Sep 13, 2020

0.0 T_DKIM_INVALID DKIM-Signature header exists but is not valid
Means that the match between public and private key can not be made. So, either the public / private key are not matched or not properly loaded.
Your DNS seems to hold the key indeed, so is it corresponding to the private key?

Things to check also: did you use a passphrase for the private key file and is it correct?

@luckk93
Copy link
Author

luckk93 commented Sep 13, 2020

Your DNS seems to hold the key indeed, so is it corresponding to the private key?

How can I check if the public and private key are corresponding? Using PHP DKIM validator will tell me just invalid DKIM key like spamassasin do.

Things to check also: did you use a passphrase for the private key file and is it correct?

I already have problem without a password, it didn't even cross my mind to put one before it work properly.

@XL-2000
Copy link

XL-2000 commented Sep 13, 2020

So if is says your key file is not valied, the problem is over there!
Also check for whitespaces etc.....

@XL-2000
Copy link

XL-2000 commented Sep 13, 2020

This is my personal proven way to generate/create, store and use pub/priv key. Make sure your vatiables are correct. Please not it will overwrite exisiting keys, so you have to update your DNS as well:

$privatekeyfile = 'SOME ABSOLUTE PATH';
$publickeyfile  = 'SOME ABSOLUTE PATH';
$passphrase     = 'YOUR KEY PASSPHRASE';

// Prepare files
if (file_exists($privatekeyfile)) { unlink($privatekeyfile); }
if (file_exists($publickeyfile))  { unlink($publickeyfile); }
// Generate 2048-bit RSA key with an SHA256 digest
$pk = openssl_pkey_new(
    [
        'digest_alg' => 'sha256',
        'private_key_bits' => 2048,
        'private_key_type' => OPENSSL_KEYTYPE_RSA,
    ]
);
// Export and Save private key
openssl_pkey_export_to_file($pk, $privatekeyfile, $passphrase);
// Save public key
$publickey = openssl_pkey_get_details($pk);
$publickey = $publickey['key'];
file_put_contents($publickeyfile, $publickey);

@luckk93
Copy link
Author

luckk93 commented Sep 13, 2020

How can I check if the public and private key are corresponding? Using PHP DKIM validator will tell me just invalid DKIM key like spamassasin do.

Actually, I told it would have given the same result, because the usage example for the DKIMValidator will just say it's not a valid DKIM signature.

But after modifying the code and recovering the actual error message, it say Agent or user identifier does not match domain: sendingemail@gmail.com.

@luckk93
Copy link
Author

luckk93 commented Sep 13, 2020

If the identifier-domain match check is removed the error become Computed body hash does not match signature body hash but it also say DKIM signature verified successfully!

@Synchro
Copy link
Member

Synchro commented Sep 13, 2020

I've been doing lots of work on DKIM validator - try testing using the dev branch.

The main reason I've been working on that is to give a solid base to use for testing PHPMailer, because otherwise DKIM is really hard to test, and there are no other decent validators.

@luckk93
Copy link
Author

luckk93 commented Sep 13, 2020

The dev branch give the same error messages:

Agent or user identifier does not match domain: sendingemail@gmail.com

Computed body hash does not match signature body hash

The only difference is that second message doesn't give anymore successfully verified signature, and when the body hash check is removed the last error message is :

DKIM signature did not verify

Since the first error is Agent or user identifier does not match domain: sendingemail@gmail.com is it possible to to use a website which is not gmail.com for the DKIM signature of a gmail address???

P.S. @Synchro the usage example of the dev branch doesn't work since you changed the validator class constructor

@Synchro
Copy link
Member

Synchro commented Sep 13, 2020

Yes, I've changed it a lot, docs need to catch up. It's not finished yet but I'm very pleased with the test suite!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants