DKIM error when sending mail with GSuite using PHP Mailer - php

I am hosted at A2 hosting, but I am using GSuite to handle all my mail.
When I send test message to mail-tester.com from Gmail I get an awesome rating.
However when I sent a message using my PHP script:
$mail = new PHPMailer(true);
ob_start();
//Server settings
$mail->SMTPDebug = SMTP::DEBUG_SERVER; // Enable verbose debug output
$mail->Host = 'smtp.gmail.com'; // Set the SMTP server to send through
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = $pickuploc . '#xxxx.com'; // SMTP username
$mail->Password = 'xxx';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` also accepted
$mail->Port = 587; // TCP port to connect to
//Recipients
$mail->setFrom($pickuploc . '#xxx.com', 'xxx xxxx');
$mail->addAddress($email, $fname . " " . $lname); // Add a recipient
$mail->addBCC($pickuploc . '#xxx.com');
// Content
$mail->isHTML(true); // Set email format to HTML
include 'email-confirmed.html';
$mail->Subject = 'Your Reservation Has Been Confirmed!';
$mail->Body = ob_get_clean();
$mail->AltBody = 'Your reservation has been confirmed.';
$mail->send();
I get an error from mail-tester.com that reads my DKIM is not valid.
I think this is because I am sending form a foreign server (not Google) and my MX records point to Google, but I really need these emails to get though, how should I work this problem?
Is there a way to configure this in PHP Mailer? Thanks.

The reason it's complaining is because you're not signing with DKIM at all!
You can do DKIM signing with PHPMailer, but there's a certain amount of setup required. PHPMailer provides some code to help you do this. Make sure you're using PHPMailer 6.1.1 or later; older versions have bugs affecting DKIM signing.
First of all you need to create your DKIM keys and put them in your DNS.
Now you need to alter your script to sign messages using your private key, as shown in this example; the parts you need to add are:
//This should be the same as the domain of your From address
$mail->DKIM_domain = 'example.com';
//See the DKIM_gen_keys.phps script for making a key pair -
//here we assume you've already done that.
//Path to your private key:
$mail->DKIM_private = 'dkim_private.pem';
//Set this to your own selector
$mail->DKIM_selector = 'phpmailer';
//Put your private key's passphrase in here if it has one
$mail->DKIM_passphrase = '';
//The identity you're signing as - usually your From address
$mail->DKIM_identity = $mail->From;
//Suppress listing signed header fields in signature, defaults to true for debugging purpose
$mail->DKIM_copyHeaderFields = false;
//Optionally you can add extra headers for signing to meet special requirements
$mail->DKIM_extraHeaders = ['List-Unsubscribe', 'List-Help'];

Related

PHPMailer sets the From same as the smtp username

I am using PHPMailer library to send SMTP email for booking enquiry. (Note: The same problem I was facing in PHP Pear Mail library as well).
I set the email from as below
$mail = new PHPMailer;
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.gmail.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true;
$mail->Username = 'gmail.owner#gmail.com'; // SMTP username
$mail->Port = 465; // TCP port to connect to
$mail->isHTML(true);
$mail->Password = 'xxxx';
$mail->setFrom(mark.antony#example.com, Mark Antony);
$mail->replyTo(mark.antony#example.com, Mark Antony);
$mail->addAddress(gmail.owner#gmail.com, Gmail Owner);
$mail->Subject = $whatever subject;
$mail->Body = $whatever html;
The problem is after sending email in the received mailbox I see the From: is the same as To: (Or same as the gmail/smtp username).
I have fixed the problem on reply to by setting replyTo value.
Is there anyway I can fix this? Or is that how it suppose to be?
Google does not allow you to set arbitrary from addresses, because doing so is usually forgery. If you try to, gmail will ignore it and substitute your Username address, which is what you're seeing.
There is one exception to this: you can set up additional aliases in your gmail settings (which you need to verify), and once you've done that you can use those addresses as from addresses.
If you're using this for a contact form (as it sounds like you are), setting to and from to your own address, and the submitter as a reply-to is the correct way to go, as the PHPMailer contact form example demonstrates.

How do I configure phpmailer with dkim and smtp authorization on plesk?

I am running Plesk onyx along with CentOs. The full hostname of the server is server.myHostName.com.
In Plesk, I have enabled DKIM Spam Protection to allow signing outgoing mail, and under Websites and Domains >> Mail Settings I have enabled Use DKIM spam protection system to sign outgoing email messages for myDomain.com.
Under Websites and Domains >> DNS Settings, there are 2 entries for what I think are DKIM:
_domainkey.MyDomain.com. and
default._domainkey.MyDomain.com.
Plesk is using postfix for the smtp mailer.
I have several questions related to getting phpmailer to work with this setup. First, I have the following in a php mail script:
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'vendor/autoload.php';
$mail = new PHPMailer(true);
try {
//Server settings
$mail->SMTPDebug = 2;
$mail->isSMTP();
$mail->Host = 'smtp1.myHostName.com.com;smtp2.myHostName.com.com';
$mail->SMTPAuth = true;
$mail->Username = 'user#example.com';
$mail->Password = 'secret';
$mail->SMTPSecure = 'tls';
$mail->Port = 587;
$mail->DKIM_domain = 'MyDomain.com';
$mail->DKIM_private = '/etc/domainkeys/MyDomain.com/_default';
$mail->DKIM_selector = '';
$mail->DKIM_passphrase = '';
$mail->DKIM_identity = $mail->From;
//Recipients
$mail->setFrom('myname#MyDomain.com', 'My Name');
$mail->addAddress('someone#somedomain.com', 'Some One');
//Content
$mail->isHTML(true);
$mail->Subject = 'Here is the subject';
$mail->Body = 'This is the HTML message body <b>in bold!</b>';
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
$mail->send();
echo 'Message has been sent';
} catch (Exception $e) {
echo 'Message could not be sent. Mailer Error: ', $mail->ErrorInfo;
}
?>
I also have SMTP authorization required under relaying options.
First, I last used phpmailer 15 years ago, and only undated today because I need to user DKIM in outbound emails, and I have more questions and no answers.
1) What do I use for $mail->Host, $mail->Username, and $mail->Password?
I didn't set up an smtp server, but assume that this was done with the Plesk installation. I do not know the smtp server names, nor the username and password. Are the last 2 the username and password from the sending email address (myname#MyDomain.com) or something else, and what should I put in the smtp host field?
2) Regarding DKIM, my emails are getting sent to spam/junk folders by all the big providers... yahoo, outlook, etc. The raw source indicates DKIM is either not signed ( dkim = none (message not signed) ) when sending from phpmailer, or fails ( dkim = fail (signature syntax error) ) and ( dkim = fail (no key for signature) ) when using webmail.myDomain.com.
How should the 5 DKIM fields in the script be set up?
Thanks very much.
==================================
Synchro:
When I disable phpmailer's DKIM and rely on Plesk, the result I get from check-auth#verifier.port25.com is:
DKIM check details:
Result: permerror (key "default._domainkey.aajumpseat.com" doesn't exist)
...
DNS record(s):
default._domainkey.aajumpseat.com. TXT (NXDOMAIN)
Any ideas?
Do I need to generate the key? Put it somewhere? I thought Plesk took care of all that.
Thanks.

phpmailer to send email from any gmail

I used the following code snippet using phpmailer class inorder to send an email using gmail server when a form is submitted in my web application! Though it works for my personel gmail address, it does not send emails when I replace my gmail address and password with my clients gmail address and password!
How can i correct this probem?
require "phpmailer/class.phpmailer.php"; //include phpmailer class
// Instantiate Class
$mail = new PHPMailer();
// Set up SMTP
$mail->IsSMTP(); // Sets up a SMTP connection
$mail->SMTPAuth = true; // Connection with the SMTP does require authorization
$mail->SMTPSecure = "ssl"; // Connect using a TLS connection
$mail->Host = "smtp.gmail.com"; //Gmail SMTP server address
$mail->Port = 465; //Gmail SMTP port
$mail->Encoding = '7bit';
// Authentication
$mail->Username = "sunethperera#gmail.com"; // Your full Gmail address
$mail->Password = "******"; // Your Gmail password
// Compose
$mail->SetFrom($_POST['emailid'], $_POST['fullname']);
$mail->AddReplyTo($_POST['emailid'], $_POST['fullname']);
$mail->Subject = "Pharmacy order confirmaton"; // Subject (which isn't required)
$mail->MsgHTML($message);
// Send To
$mail->AddAddress($_POST["Email"], "Recipient Name"); // Where to send it - Recipient
$result = $mail->Send(); // Send!
$message = $result ? 'Successfully Sent!' : 'Sending Failed!';
unset($mail);
When I send the message from my client's email, I get the error message:
SMTP Error: Could not authenticate.
How can I correct this issue?
Trying using this:
$mail->SMTPSecure = "tls";
Remove the Encoding parameter
And also check you have the correct from address and the password as well.
Update your PHPMailer right now. You are running an old vulnerable version. Read the troubleshooting guide and do what it says. Do not use the submitter's address as the from address - its forgery and will make you fail SPF checks. Gmail does not let you send from arbitrary from addresses. Your auth problem is covered in the guide, but you will need to either enable less secure apps in Gmail, or implement oauth, as described in the docs and examples.
This has all been covered many times on SO - search before you post.

PHPMailer: Dynamic gmail forwarding

I do not know if what I want to do is possible (but finding out that it isn't would be useful in itself).
I cannot use my company's gmail account "real.business#gmail.com" directly with PHPMailer. I can, however, use an intermediary gmail account "fake.12345.account#gmail.com" which can have "less secure apps" enabled, which permits SMTP verification.
However I do not want to have the emails be sent from this fake.12345.account#gmail.com account (wouldn't look particularly professional) - but rather the company's gmail account.
I can send the emails from the intermediary account to real.business#gmail.com; either through the editing of the PHPMailer parameters, or by automatically forwarding emails from fake.12345.account#gmail.com to the company account.
The problem lies in how real.business#gmail.com can then successfully email the email (or at least appear to be the sender), as originally intended.
The code so far
$Mail = new PHPMailer();
$Mail->IsSMTP(); // Use SMTP
$Mail->Host = "smtp.gmail.com"; // Sets SMTP server for gmail
$Mail->SMTPDebug = 0; // 2 to enable SMTP debug information
$Mail->SMTPAuth = TRUE; // enable SMTP authentication
$Mail->SMTPSecure = "tls"; //Secure conection
$Mail->Port = 587; // set the SMTP port to gmail's port
$Mail->Username = 'fake.12345.account#gmail.com'; // gmail account username
$Mail->Password = 'a_password'; // gmail account password
$Mail->Priority = 1; // Highest priority - Email priority (1 = High, 3 = Normal, 5 = low)
$Mail->CharSet = 'UTF-8';
$Mail->Encoding = '8bit';
$Mail->Subject = 'Mail test';
$Mail->ContentType = 'text/html; charset=utf-8\r\n';
$Mail->From = 'testing.num.101#gmail.com'; //Your email adress (Gmail overwrites it anyway)
$Mail->FromName = 'Testing Again';
$Mail->WordWrap = 900; // RFC 2822 Compliant for Max 998 characters per line
$Mail->addAddress($personEmail); // To: the PERSON WE WANT TO EMAIL
$Mail->isHTML( TRUE );
$Mail->Body = ' Good news '.$personName.'! The email sent correctly!';
$Mail->AltBody = 'This is a test mail';
$Mail->Send();
$Mail->SmtpClose();
if(!$Mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $Mail->ErrorInfo;
exit;
}
So the issue is: not having the email sent to $personEmail from fake.12345.account#gmail.com (that's trivial) but rather how to send the email from fake.12345.account#gmail.com to real.business#gmail.com such that real.business#gmail.com forwards the message to $personEmail
What you're describing is really relaying, which is usually configured in the mail server config (not the messages), but you don't have access to anything like that in gmail.
You can set allowed aliases in gmail, but I would guess that these are not allowed to overlap with existing gmail account names as that would be a major security hole. Why not enable "less secure apps" on the main account? It's not as if it is actually any less secure - if anything it's better, because the setup to use OAuth2 is so deeply complex and unpleasant...
That said, rather than trying to do all this forgery, you may be interested in this PR and associated docs. It's fairly likely the xoauth branch will get merged into master and released without any further changes as PHPMailer 5.2.11, and it would very helpful if you could give it a try.
PHPMailer is made for sending.
What you want to do is forward an email. This implies receiving the email and then sending it through.
What you need is some kind of IMAP client in php, that will allow you to read the emails on fake.12345.account#gmail.com (and maybe real.business#gmail.com). Then save their body and title and pass it to PHPMailer. You can then use PHPMailer to send the emails with real.business#gmail.com.

phpMailer: Could not instantiate mail function

I created a form that uses phpMailer to email the results to the website owner. Of course, before I add the owner's email address I use mine to test that the form works. When I use my email the form sends perfectly, however, when I use the owner's address it throws the error "could not instantiate mail function" and won't send the form. The error only occurs with email addresses associated with the owner's domain. Any idea why this could be happening?
If I type this into the command line it works fine:
echo 'test' | mail -s 'test' me#example.com
edit: I wasn't initially using SMTP, but it's now configured as shown below. The error message is now "SMTP Error: The following recipients have failed xxx#somedomain.com" and the end result is still the same. It can e-mail to a number of gmail test addresses but has issue with the owner's email#hisdomain.com. Further, with SMTPDebug it's now producing the error "RCPT TO command failed: 550 No Such User Here" The owner's e-mail, however, works without issue when e-mailed through gmail, outlook, etc.
phpMailer code:
$mail = new PHPMailer();
$mail->IsSMTP();
$mail->SMTPDebug = 1;
$mail->Debugoutput = "error_log";
$mail->Host = "mail.mydomain.com";
$mail->SMTPAuth = true;
$mail->Username = "admin#mydomain.com";
$mail->Password = "XXXXXXXXXXXXXXX";
$mail->CharSet = 'UTF-8';
$mail->AddReplyTo($emailAddress);
$mail->SetFrom("admin#mydomain.com");
$mail->AddAddress($toAddress,$toName);
$mail->Subject = $emailSubject;
$mail->isHTML(true);
$mail->Body = $emailBody;
$mail->AltBody = strip_tags($emailBody);
// Attempt to send the e-mail
if (!$mail->send()) {
//error handling
}
There are couple of things you should try and check with this particular error message:
Make sure you can use regular php mail() function. Create a blank page and use the php mail() to send a test email. If that works, maybe its your SMTP that's having issues with the particular user domain. Setup gmail SMTP or a different SMTP to send emails:
$mail->IsSMTP();
$mail->Host = "smtp.domain.com";
// optional
// used only when SMTP requires authentication
$mail->SMTPAuth = true;
$mail->Username = 'smtp_username';
$mail->Password = 'smtp_password';
Can you share your phpMailer source for us to view?
Set $mail->SMTPDebug = 2; so you can see what the server has to say, and read the troubleshooting guide.
You're using authentication without encryption, which is not a good combination and many servers won't allow that. Add this:
$mail->SMTPSecure = 'tls';
$mail->Port = 587;
You've based your code on an old example, so you're probably using an old version of PHPMailer too; get the latest from github.

Categories