π 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
[email protected]
MAIL_PASSWORD=<password>
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="[email protected]"
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. π