php imap_open cannot make a secure connection to a virtualmin dovecot server on port 143 with tls

I have a virtual server running on virtualmin with dovecot as IMAP and the only port open is 143. I have let’s encrypt certificate and everything has been running fine on this server for email with Dovecot and Postfix

root@web:~# postconf mail_version
mail_version = 3.4.23

root@web:~# dovecot --version
2.3.4.1 (f79e8e7e4)

Debian Linux 10
Webmin version  2.111
Virtualmin version  7.10.0

I am using PHP 8.2 with brew on a macbook. I use the following start of script to connect to the server

$imap = imap_open('{domain.ca:143/tls}INBOX', 'username', 'password');

var_dump(imap_last_error());exit;

I keep getting a SSL negotiation failed regardless of /tls, /ssl or ssl/novalidate-cert. I have tried every combination and setting from the php manual. I have tried every solution on stack or online without any success.

It will only work if I do imap_open('{domain.ca:143/notls}INBOX', 'username', 'password'); Making this an unsecure connection. I would really like to know how I can make this a secure connection. What could I be doing wrong?

I also tried directly by the public IP. Postfix and dovecot are on domain.ca, not imap.domain.ca is that matters.

Warning: imap_open(): Couldn't open stream {domain.ca:143/tls}INBOX in /usr/local/var/www/index.php on line 5
string(58) "TLS/SSL failure for domain.ca: SSL negotiation failed"
Notice: PHP Request Shutdown: TLS/SSL failure for domain.ca: SSL negotiation failed (errflg=2) in Unknown on line 0

server journalctl says

ay 10 11:34:57 web.domain.ca dovecot[828]: imap-login: Disconnected (no auth attempts in 0 secs): user=<>, rip=x.x.x.x, lip=x.x.x.x, session=<qg0rRxsY/IVGNc6I>

so from what this log says, am I using this wrong? Should have have the auth. inside the ‘{domain.ca:143/notls}’ string? Or is this php extension configured not to check secure connect on 143?

Any help would be appriciated.

Thank you

  • You’re trying to connect to Dovecot with IMAP over SSL/TLS (port 143) using PHP 8.2’s imap_open function.
  • You’ve enabled Let’s Encrypt on your server, but attempts to connect securely keep failing with an “SSL negotiation failed” error.

Troubleshooting Steps:

  1. Verify Let’s Encrypt Certificate:
  • Ensure Let’s Encrypt is installed and configured correctly on your server.
  • Double-check that the generated certificate covers the domain name you’re using in the imap_open call (domain.ca ).
  • You can use tools like openssl s_client to test the certificate from your Macbook (replace domain.ca with your actual domain):Bashopenssl s_client -connect domain.ca:443

Use code with caution.

  • Look for a successful handshake and check if the certificate chain validates.
  1. PHP Configuration for SSL Verification:
  • Open your PHP configuration file (e.g., php.ini on most systems).
  • Locate the following settings and ensure they’re enabled:allow_url_fopen = On ; Allow opening URLs (needed for Let's Encrypt) openssl.verify_peer = On ; Enable SSL peer verification openssl.verify_depth = 2 ; Allow verification chain depth up to 2 levels
  • Restart your PHP service after making changes.
  1. Dovecot TLS Configuration:
  • Check Dovecot’s configuration file (e.g., /etc/dovecot/dovecot.conf on Debian) for parameters related to SSL/TLS.
  • Make sure the TLS certificate and key paths are set correctly. You might need parameters like ssl_cert and ssl_key .
  • Consult your distribution’s documentation or Dovecot’s documentation for specific settings related to your version.
  1. Client-Side Configuration (Macbook):
  • In rare cases, outdated system certificates on your Macbook might interfere. You can update your system’s trust store using tools provided by your operating system (e.g., Security & Privacy settings on macOS).
  1. Temporary Workaround for Testing (Not Recommended for Production):
  • If you need to establish a connection temporarily for testing purposes, you can disable SSL verification by using imap_open('{domain.ca:143/novalidate-cert}INBOX'...) in your PHP script. Warning: This should only be used for testing as it bypasses security checks.

Additional Tips:

  • Consider using a dedicated library like phpseclib for more granular control over secure connections in PHP.
  • Double-check your PHP error logs for more detailed error messages.
  • If you’re still encountering issues, provide more details about your Let’s Encrypt setup, specific Dovecot settings, and any relevant error logs from both the server and client sides for further assistance.

By following these steps and carefully reviewing your server and client-side configurations, you should be able to resolve the SSL negotiation failure and establish a secure connection to your Dovecot server using PHP 8.2.