Connecting to Gmail via PHP
I have just spent several hours tracking down a ton of loose ends to figure out just why my PHP application (in my case, phpBB 3.2.5) wouldn’t connect to a Gmail account.
In the end, it likely has to do with something on Google’s end, like:
- Enabling “Letting Less Secure Apps access your account“
- Using the correct Gmail IMAP/SMTP settings
- Or a combination of “Turning on 2-Step Verification“, so that you can then generate and “Sign in using App Passwords“
My approach to solving the issue took into account all of these on the way to the final solution:
- An /etc/hosts entry for smtp.gmail.com
# This is just 1 of 2 IPv4 servers for the domain 22.214.171.124 smtp.gmail.com
In phpBB’s “Admin Control Panel,” there is an Errors page that would constantly spit out a “timeout” error no matter what settings I used.
Email error » EMAIL/SMTP /phorums/memberlist.php Could not connect to smtp host : 110 : Connection timed out Errno 2: stream_socket_client(): unable to connect to smtp.gmail.com:465 (Connection timed out) at [ROOT]/includes/functions_messenger.php line 1188
The email settings I have in place are related to a couple things:
- I own several domains, the one for this purpose is: the-spot.net
- I am grandfathered into the original Google Apps Suite, and I have that attached to the domain.
- All email addresses are routed to a catch-all address with an long-random-alphanumeric account name, so when I need to send from a specific account, I have to create a new User in Google Apps Admin Console.
- As the Admin User, I also had to:
- Enable users to set up 2-Step Verification
- Enable users to set their own “Less Secure Apps” access setting
- Then as the Newly Created User, I had to:
- Log into the account for the first time, and create a[nother] password
- Turn on “Less Secure Apps” access
- Set up 2-Step Verification (I used my Google Voice number, as I have with all my Google Accounts)
- Generate an App Password.
Once I had followed all those account-configuration steps, I then referenced the IMAP/SMTP Settings documentation, and started entering the values into the fields, as shown.
Obviously, the settings in the image above did not work. They continually provided the same “Connection Timeout” error mentioned earlier.
In research and trying to test whether or not my settings were correct, I saw some mention that…
…the “Send a test email” button doesn’t work, and you have to send either an email from the User’s Profile, or a Private Message.Some random reply on one of the many support threads
A little foreshadowing here… that is not true. The button works fine.
If you do have command-line access, and/or can make changes to the /etc/hosts file that will stick – i.e. you have CLI root access, or you have a cPanel interface to set your own local dns entries, then you’re in luck.
To see what is going on, get to your web server, and run the following command. You’ll see what IP is initially connected to when trying to telnet into the email server at the tls port:
root@web:/home/web# telnet smtp.gmail.com 587 Trying 2607:f8b0:400d:c0a::6d...
It’s an IPv6. That’s unexpected…but I recall Google announcing they are making as many of their services prefer IPv6 where supported. (The link is the best I could find…the original announcement is gone.)
So there’s the problem… the PHP socket stuff is having a hard time with the IPv6 connection.
Now, if you run the following command from the web server’s terminal, you’ll see all the things that are related to the smtp.gmail.com domain:
root@web:/home/web# dig +short smtp.gmail.com gmail-smtp-msa.l.google.com. 126.96.36.199 188.8.131.52
Two of those are IP addresses. One of them is a domain, and is of little use to us: we already have the smtp.gmail.com domain, and we can’t put a domain into the left-side of the hosts file.
Take either of the IP addresses, and insert them into your /etc/hosts file…
root@web:/home/web# sudo vi /etc/hosts ### 184.108.40.206 smtp.gmail.com :wq
Save the file, go back to the phpBB interface and make sure:
- Use STMP server for email: yes
- Your password is an App Password
- Your username, from, reply-to, and other email addresses are the Google Account for the App Password
- The domain is: ssl://smtp.gmail.com (you might be able to use tls://)
- The port is: 465 (you might be able to use 587 for TLS)
- Verify SSL Cert: yes
- Verify SMTP Peer: yes
Then hit the “Send a test email” button in the top section. Once you do, you should get: a fairly quick green success message page, no errors in the log, and an email that arrives to the user account you are currently logged into.
I haven’t tried some of these alternatives, because I was able to get it working via the method above. However, if you can’t make changes to the /etc/hosts file, perhaps try some of the following:
- Create a DNS entry that points a subdomain you can control to the IP (or if possible, both IPs) for the smtp.gmail.com server.
- Create an email account via the webhost/cpanel interface, or maybe even the domain registrar, and go the self-hosted route. At least it’ll be fully under your control, and you can IMAP the account into another Gmail account, and tag those messages via Filters, if you need to receive them.
- This is the solution I originally used, until I moved my domain over to Google Apps, causing this problem in the first place.
- Or as a last resort, change the code making the request to use a PHP library that will support making calls directly to the original domain. There are many support threads about this problem that end with simply changing the properties sent to the mailer class.
Let me know in the comments if you have found a different solution, or see problems with my approach (other than the obvious and expected “Unexpected IP Changes” or “Single IP, no redundancy”).