Debugging SMTP Connection Issues on a cPanel Server with CSF Firewall Enabled Print

  • 0

🚀 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. 🎉


Was this answer helpful?

« Back