🚀 Introduction
Many web hosting providers encounter email delivery issues such as the "Connection timed out (110)" error when attempting to connect to external SMTP servers (e.g., smtp.office365.com:587
).
🔎 Common Causes:
-
🌐 System defaults to IPv6, which PHP may mishandle.
-
🔥 Overly restrictive firewall rules can block outgoing SMTP connections.
-
🚫 Allowing unrestricted outbound SMTP traffic can lead to spam abuse.
🎯 Goals of This Guide
✅ Ensure your server can connect to trusted SMTP providers. ✅ Limit outbound SMTP traffic only to those providers via CSF’s whitelist. ✅ Resolve PHP connectivity issues by forcing IPv4. ✅ Adjust application settings (e.g., Laravel’s .env
) to align with these changes.
🔍 Identifying the Problem
🔎 Step 1: Testing SMTP Connectivity with nc
(netcat)
First, verify that your server can reach the SMTP servers over IPv6 using netcat
:
nc -zv smtp.office365.com 587
🟢 Success: The server successfully connected to Office365 over IPv6.
Similarly, testing Gmail:
nc -zv smtp.gmail.com 587
🟢 Success: Connection to Gmail over IPv6 was also successful.
For SendGrid:
nc -zv smtp-relay.sendgrid.net 587
❌ DNS Resolution Failed: The hostname did not resolve.
🔐 Upgraded SMTP Outbound Control
✅ Whitelist Only Trusted SMTP Providers
🔄 Instead of completely opening all SMTP traffic or manually removing LOGDROPOUT
rules, restrict outbound mail to trusted providers only.
🛠️ How to Implement:
1️⃣ Edit the CSF Allow File:
nano /etc/csf/csf.allow
2️⃣ Add the Following Entries:
tcp|out|d=587|d=smtp.office365.com
tcp|out|d=587|d=smtp.gmail.com
tcp|out|d=587|d=smtp-relay.sendgrid.net
tcp|out|d=587|d=smtp.mailgun.org
tcp|out|d=587|d=smtp.zoho.com
3️⃣ Restart CSF:
csf -r
✅ Result: Now, only these trusted providers are allowed for sending mail, reducing the risk of spam and abuse from compromised hosted domains.
🛠️ Continued Testing and Troubleshooting
🔎 Step 3: Testing from PHP (test_smtp.php
)
Create a simple PHP script to test SMTP connectivity:
<?php
$host = "smtp.office365.com";
$port = 587;
$errno = 0;
$errstr = "";
$connection = fsockopen($host, $port, $errno, $errstr, 10);
if (!$connection) {
echo "❌ Failed to connect: $errstr ($errno)\n";
} else {
echo "✅ PHP successfully connected to SMTP server!\n";
fclose($connection);
}
?>
Run the script:
php test_smtp.php
🔎 Step 4: Checking CSF Firewall Rules
csf -g 587
👀 Look for entries showing your whitelisted providers rather than blanket DROP
or LOGDROPOUT
rules.
🔎 Step 5: Checking If PHP Is Running in a Restricted Environment
Run additional tests (such as using a custom socket connection test) to ensure that PHP isn’t subject to further network restrictions beyond CSF.
⚙️ Step 6: Disabling IPv6 at the System Level
Since the server was defaulting to IPv6 for SMTP connections—which PHP can mishandle—force the system to use IPv4:
sysctl -w net.ipv6.conf.all.disable_ipv6=1
sysctl -w net.ipv6.conf.default.disable_ipv6=1
sysctl -w net.ipv6.conf.lo.disable_ipv6=1
📌 To make this permanent, add to /etc/sysctl.conf
:
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
🔄 Reload the configuration:
sysctl -p
✅ Result: After rebooting, PHP should now default to IPv4.
🎛️ Step 7: Modifying Laravel .env
to Force IPv4 and Disable SSL Verification
For Laravel applications, update your .env
file:
MAIL_MAILER=smtp
MAIL_HOST=smtp.office365.com
MAIL_PORT=587
MAIL_USERNAME=no_reply@yourdomain.com
MAIL_PASSWORD=<password>
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="no_reply@yourdomain.com"
MAIL_FROM_NAME="Your App Name"
MAIL_EHLO_DOMAIN=yourdomain.com
MAIL_STREAM_OPTIONS='{"ssl": {"crypto_method": STREAM_CRYPTO_METHOD_TLS_CLIENT, "verify_peer": false, "verify_peer_name": false}}'
🚀 Then clear Laravel’s caches:
php artisan config:clear
php artisan cache:clear
php artisan queue:restart
✅ Result: Laravel emails should now work correctly.
🎯 Conclusion
💡 Root Causes:
-
🌍 The system defaulted to IPv6 for SMTP connections, while PHP struggled with IPv6 routing.
-
🔥 Opening outbound SMTP traffic broadly increases the risk of spam abuse.
🏆 Final Fixes:
✔️ Whitelist Only Trusted SMTP Providers: Outbound SMTP traffic is restricted only to trusted SMTP providers. ✔️ Disabled IPv6: Forced the server to use IPv4 for better compatibility. ✔️ Updated Application Configuration: Adjusted Laravel’s settings to work with the new network setup.
🚀 With these changes, SMTP emails now work reliably on your server while minimizing the risk of spam abuse. 🎉