user cron, mail DKIM issues

RoRoo

Verified User
Joined
Dec 16, 2004
Messages
112
Goodday! I've got an irritating issue at hand.
I've got a user: user that has several domains configured under it's account.

in the account he has several cronjobs that does some action and sends messages to users gmail address.
Since a few weeks now the user hasn't been receiving these mail messages anymore and the logs indicate Google blocks them due to DMARC policy.

I've fixed the system (server.domain.com) DKIM key so system messages get signed correctly. And the users domains have their own DKIM settings configured as well.
Now the cron runs the script (/usr/local/bin/php -f /home/user/domains/domainB.com/public_html/testscript.php) that is being run as the user "user".
in that php script there's a setting to send an email from: [email protected]
But somehow the message is getting signed with the key for "server.domain.com" and not the key for domainB.com

I get that cron has a system mail addres, but why is the phpscript (being run as the user that does not control server.domain.com) signing it like that?
The message is being sent using: mail($to, $subject, $body, $headers);

$headers contains the From: [email protected]

I know something obvious is wrong, but I can't seem to find it :(
 
Google blocks them due to DMARC policy.
I highly doubt this, as DMARC is not a requirement for Google/Gmail, however SPF is.

It's normal that mails from php scripts will be send via and signed with the key of server.domain.com that is normal. DKIM key of the user will be used when SMTP is used.

Most important is the exact notice Gmail is giving you, can you post this here, and mask your ip and domain or users domain as far as needed.

Then check if you have a seperate hostname entry in your DNS administration, like server.domain.com but not like a server entry in domain.com but a seperate server.domain.com entry.
 
You can doubt it, but the error message is quite clear:
SMTP error from remote mail server after end of data: 550-5.7.26 Unauthenticated email from domainb.com is not accepted\n550-5.7.26 due to domain's DMARC policy

I didn't post it the error, because there's is nothing wrong with the error. It's what we want, otherwise we wouldn't have set the DMARC to reject.
The issue is, mail being sent from a php script ran as a user owning domaina.com, domainb.com and not server.domain.com still sending the DKIM key of server.domain.com (yes this is verified in the headers).

Other scripts ran through PHP via the site are being sent correctly. Only cron based show this behaviour.
Maybe it isn't possible, like you say: "It's normal that mails from php scripts ..." I will instruct the user to use phpmailer instead of the "mail" command.
But I find it strange that a process started by a normal user is able to "access" the DKIM signing of a systemonly based hostname.domain.
 
Is the email being sent by the PHP script or by cron? There's a difference.

If the email is being sent by the PHP script, how is the mail being sent? Is it using PHP's mail() function? Are you specifying a specific envelope-sender using the fifth parameter of the mail() function?


For sendmail (which exim clones) this would be a [email protected]

mail("[email protected]", "subject", "message", "From: [email protected]\r\n", "[email protected]");

If the message is being sent by cron, then the message is always going to have an envelope-sender of %serveraccount%@%servername% There is no way around that (that I know of or at least one that I'd want to apply to a shared hosting environment).

As for DMARC policy, it does appear that Google requires a DMARC record - at least some times. But you can set an utterly stupid non consequential DMARC record:

_dmarc 3600 IN TXT "v=DMARC1; p=none"

Which basically tells mail servers: "Here's a DMARC record... don't do anything"

You would need to add the DMARC record to the DNS zone for %servername% if the message is being sent by cron. Or in domainb.com if the message is being sent by PHP with a properly formatted mail() function with a defined envelope-sender.
 
You can doubt it, but the error message is quite clear:
So that is not Gmail's dmarc issue as I thought.... it's the way the user setup DMARC.
The user did not allow the server to also send email.
Have him include the server in the SPF record or remove the DMARC entry and all will be fine.

it does appear that Google requires a DMARC record - at least some times
I never seen that, it's not in Google's docs and also in this case, it's not a Google requirement.
 
But somehow the message is getting signed with the key for "server.domain.com" and not the key for domainB.com

I bet the exim logs show that the email was sent from the envelope sender of "[email protected]" where username is their DirectAdmin username, and of course server.domain.com is the server's hostname. This is why I don't like people using half baked software to send email. A raw and not obsessively built implementation around PHP's mail() is precisely the kind of "half baked" thing I refer to.

Better to have the scripts authenticate over SMTP and actually send the mail properly, else you'll need to make sure the scripts are configured to add all of the required email headers (I'm looking at you, Message ID) and that it properly sets the envelope sender address, not just the From header. You'd be surprised how many things are fully baked into very popular and respected pieces of software that don't do that.
 
Last edited:
A raw and not obsessively built implementation around PHP's mail() is precisely the kind of "half baked" thing I refer to.
Well, PHP's mail() function does provide a way to set all of this. It's just that most people are too busy to take the time to learn about these parameters and how mail works and what these values should be set to.

Most people don't understand the difference between envelope-sender and From header, and therefore have no idea what these should be set to and how to set them. Or how anti-spoofing authenticators should be configured based on these values.
 
Is the email being sent by the PHP script or by cron? There's a difference.

If the email is being sent by the PHP script, how is the mail being sent? Is it using PHP's mail() function? Are you specifying a specific envelope-sender using the fifth parameter of the mail() function?


For sendmail (which exim clones) this would be a [email protected]

mail("[email protected]", "subject", "message", "From: [email protected]\r\n", "[email protected]");

If the message is being sent by cron, then the message is always going to have an envelope-sender of %serveraccount%@%servername% There is no way around that (that I know of or at least one that I'd want to apply to a shared hosting environment).

As for DMARC policy, it does appear that Google requires a DMARC record - at least some times. But you can set an utterly stupid non consequential DMARC record:

_dmarc 3600 IN TXT "v=DMARC1; p=none"

Which basically tells mail servers: "Here's a DMARC record... don't do anything"

You would need to add the DMARC record to the DNS zone for %servername% if the message is being sent by cron. Or in domainb.com if the message is being sent by PHP with a properly formatted mail() function with a defined envelope-sender.
Cron is calling a php script. Within it, php is calling mail()
DMARC is explicitly set to reject, so cannot change that as it's a workaround.
I was trying to understand what was happening, because on one hand things seem logically but on the other hand it worked with other cronjobs.

I'll have them code things better and see what happens. Otherwise, no = no and ask them to do things differently.

Will update
Update: adding the -f worked like a charm!
 
Last edited:
if your customer don't know how to coding, tell them to look at codeignite3, it has good "mail()" usage and filtering.
 
Back
Top