No matter what I’m doing, whatever site I’m building or managing, on whatever server, it’s always automated emailing that has given me the most hassle over the years. Here’s a cautionary tale about using PHP and WordPress to send mail on a server where the DNS zone and mail server are located elsewhere.
WordPress and Mail
WordPress sends emails automatically for many reasons. It can send emails when there is a new comment or trackback, it sends an email when a user account is created, form plugins send emails when their forms are submitted, etc etc.
WordPress sends email using its own wp_mail() function. By default this function is simply a wrapper for PHP’s own mail() function, which normally uses the server’s Sendmail application.
Sometimes, WordPress’s attempts to send email fail. This is normally for one of two reasons. Either the server is running Windows and is misconfigured (this happens more often than you might think), or the server is not controlling the DNS zone for the site, but attempts to send mail to the same domain internally rather than querying the remote DNS for an MX record (this also happens more often than you might think).
A Note About Split DNS
Sometimes, a domain’s nameservers may point to server A, where the DNS zone records are located. However, the domain’s website might be on server B, halfway around the world, and this is achieved by setting one of the domain’s DNS zone records to point to server B. A problem arises when the site on server B tries to send email to an address on the same domain, and server B thinks that the mail account must be local, because the website is. The mail gets lost, and this is the DNS problem I referred to above. It can sometimes be solved by switching off mail services for the domain on server B, but not always – it depends on other aspects of the server’s configuration as well.
When WordPress fails to send mail, the quickest solution is to use SMTP. This uses the credentials of an email account to send mail via that account’s server.
The easiest thing to do is set up a Gmail account specifically for the purpose of relaying automatic emails sent from WordPress, and there are several WordPress plugins which force the wp_mail() function to use SMTP and let you specify the email account and server to use (it doesn’t have to be Gmail).
The following two plugins are ones that I’ve used, and they do their job well:
In the settings, you specify the gmail (or other server) SMTP address and port, and the username and password, and each time WordPress sends a mail, the plugin logs into the SMTP server with the credentials you’ve supplied, and sends the mail via that account.
What About Non-WordPress Sites?
Bear with me, this is a necessary part of the story.
I have a custom web application that I developed using PHP and MySQL, and it too sends automated emails triggered by various events. It just so happens that it runs on a domain where the DNS is on a different server from the website, just like the situation described above, and – guess what – getting it to actually send emails has been an uphill struggle.
When I realised that PHP’s mail() function was failing, I added the PHPMailer utility to the application, and set it to use SMTP. I created an email account on a spare domain and used that as a relay. For a while, that worked.
Then the server that hosts the spare domain had its email policies changed and this technique suddenly stopped working.
I then set up a Gmail account, switched the SMTP details to use it, and all the automatic emails started arriving again. For a while.
Recently, it stopped working. I tried all kinds of things – different ports, different security settings, then I looked at the logs. When PHPMailer was trying to log in to Gmail via SMTP, it was getting an error that included this statement:
534-5.7.9 Please log in with your web browser and then try again.
After doing a bit of reading, it seemed that Gmail had flagged this SMTP use by the website as suspicious behaviour, and wanted the account owner to log in properly from the same IP address to verify that they were using the account. The trouble was, I couldn’t log in with a browser on my server IP address, since I don’t have remote access to it apart from FTP.
Then I suddenly remembered that some servers need a POP3 login before they would permit an SMTP connection from the same IP. I had never understood this point of this setting until now, because I had never had to use it. But would it solve the problem with Gmail?
I amended my code to log in to the Gmail account via POP3 just before sending a mail via SMTP, and bingo – it worked. Suddenly, my application’s automated emails were flying around Europe with gay abandon. Mahoosive relief.
Eureka, But Now What About WordPress
Recently I’ve been having the same problem on two WordPress sites that also have their DNS zone on a remote server, and so I figure I need to apply the same solution.
However, none of the WordPress plugins that force WordPress to use SMTP offer a setting for pre-authorising with POP3 before sending with SMTP. None that I can find anyway…
So I’m going to have to write my own. It shouldn’t be too hard. Watch this site for a new plugin announcement soon.