Re[2]: Can't connect to MySQL without SSL

Adam Miller via dovecot <[email protected]>
Newsgroups gmane.mail.imap.dovecot
Message-ID <0100019fd5b0d565-667da4a0-32cc-46fd-b5a5-37e387a88780-000000@email.amazonses.com>
Here’s a basic configuration for a Dovecot 2.4.0 server. This should 
help you with the MySQL connection. If you are using an older version of 
Dovecot than 2.4.0, I would recommend upgrading. Also note, this is a 
single file configuration!

# 
=============================================================================
# Dovecot 2.4 CE configuration
# Single-file configuration — do not use /etc/dovecot/conf.d/
# 
=============================================================================

# Required in 2.4: declares config syntax version and storage format 
version.
# These MUST be the first settings in the file.
dovecot_config_version = 2.4.0
dovecot_storage_version = 2.4.0

# ——————————————————————————————————————
# Global
# ——————————————————————————————————————
protocols = imap lmtp
listen = *
base_dir = /var/run/dovecot
instance_name = <HOSTNAME>
hostname = <HOSTNAME>
login_greeting = Welcome
postmaster_address = <POSTMASTER>
mail_server_admin = mailto:<POSTMASTER>

default_internal_user = vmail
default_internal_group = vmail

# ——————————————————————————————————————
# Logging
# ——————————————————————————————————————
log_path = /var/log/dovecot/general.log
info_log_path = /var/log/dovecot/info.log
debug_log_path = /var/log/dovecot/debug.log

log_debug = category=auth OR category=mail OR category=sieve
auth_verbose_passwords = no

# ——————————————————————————————————————
# SSL / TLS
# ——————————————————————————————————————
ssl = required
ssl_server_cert_file = /etc/letsencrypt/live/<HOSTNAME>/fullchain.pem
ssl_server_key_file  = /etc/letsencrypt/live/<HOSTNAME>/privkey.pem
ssl_server_dh_file   = /usr/share/dovecot/dh.pem
ssl_client_ca_dir    = /etc/ssl/certs
ssl_min_protocol     = TLSv1.2
ssl_server_prefer_ciphers = server

# ——————————————————————————————————————
# Mail storage
# ——————————————————————————————————————
mail_driver = maildir
mail_path   = ~/
mail_home   = %{user | domain}/%{user | username}

maildir_stat_dirs = yes

mail_max_userip_connections = 250

# ——————————————————————————————————————
# Namespaces
# ——————————————————————————————————————
namespace inbox {
   inbox = yes
   separator = /
   prefix =

   mailbox Archive {
     auto = subscribe
     special_use = \Archive
   }
   mailbox Drafts {
     auto = subscribe
     special_use = \Drafts
   }
   mailbox Junk {
     auto = subscribe
     special_use = \Junk
     autoexpunge = 90d
   }
   mailbox Sent {
     auto = subscribe
     special_use = \Sent
   }
   mailbox Trash {
     auto = subscribe
     special_use = \Trash
     autoexpunge = 30d
   }
}

# ——————————————————————————————————————
# Auth: mechanisms and behavior
# ——————————————————————————————————————
auth_mechanisms = plain login
auth_username_format = %{user | lower}
auth_username_chars = 
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_@

auth_cache_size = 64M
auth_cache_ttl = 10mins
auth_cache_negative_ttl = 1mins


# ——————————————————————————————————————
# MySQL connection (used by passdb, userdb, and quota_clone dict)
# ——————————————————————————————————————
mysql mail-db {
   host     = <DB_HOSTNAME>
   user     = <DB_USERNAME>
   password = <DB_PASSWORD>
   dbname   = <DB_DATABASE>
}

sql_driver = mysql

# ——————————————————————————————————————
# passdb: SQL-backed password lookup
# ——————————————————————————————————————
passdb sql {
   default_password_scheme = BLF-CRYPT

   query = SELECT `Mailbox`.`email` AS `user`, `Mailbox`.`password` FROM 
`mailbox` `Mailbox` WHERE `Mailbox`.`email` = '%{user | lower}' AND 
`Mailbox`.`isActive` = 1 AND `Mailbox`.`domainUuid` IN (SELECT 
`Domain`.`uuid` FROM `domain` `Domain` WHERE `Domain`.`isActive` = 1)
}

# ——————————————————————————————————————
# userdb: SQL-backed user lookup
# ——————————————————————————————————————
userdb sql {
   query = SELECT `Mailbox`.`maildir` AS `home`, 5000 AS `uid`, 5000 AS 
`gid`, CASE WHEN `Mailbox`.`quotaSize` IS NOT NULL AND 
`Mailbox`.`quotaMessages` IS NOT NULL THEN CONCAT('*:bytes=', 
`Mailbox`.`quotaSize`, ':messages=', `Mailbox`.`quotaMessages`) ELSE 
NULL END AS `quota_rule` FROM `mailbox` `Mailbox` WHERE 
`Mailbox`.`email` = '%{user | lower}' AND `Mailbox`.`isActive` = 1 AND 
`Mailbox`.`domainUuid` IN (SELECT `Domain`.`uuid` FROM `domain` `Domain` 
WHERE `Domain`.`isActive` = 1)
   iterate_query = SELECT `Mailbox`.`email` AS `username` FROM `mailbox` 
`Mailbox` WHERE `Mailbox`.`isActive` = 1 AND `Mailbox`.`domainUuid` IN 
(SELECT `Domain`.`uuid` FROM `domain` `Domain` WHERE `Domain`.`isActive` 
= 1) ORDER BY `Mailbox`.`domainName` ASC, `Mailbox`.`email` ASC
}

# ——————————————————————————————————————
# Plugins (loaded globally)
# ——————————————————————————————————————
mail_plugins {
   quota = yes
   quota_clone = yes
}

# ——————————————————————————————————————
# Quota: count driver (authoritative, no enforcement)
# ——————————————————————————————————————
quota user {
   driver = count
}

# ——————————————————————————————————————
# Quota clone: mirror live usage into MariaDB mailboxQuota table
# ——————————————————————————————————————
dict_server {
   dict quotaclone {
     driver = sql
     sql_driver = mysql

     dict_map priv/quota/storage {
       sql_table = mailboxQuota
       username_field = email
       value_field size {
       }
     }

     dict_map priv/quota/messages {
       sql_table = mailboxQuota
       username_field = email
       value_field messages {
       }
     }
   }
}

quota_clone {
   dict proxy {
     name = quotaclone
   }
}

# ——————————————————————————————————————
# Service: auth (SMTP AUTH for Postfix, plus auth-userdb socket)
# ——————————————————————————————————————
service auth {
   user  = vmail
   group = vmail

   unix_listener /var/spool/postfix/private/auth {
     user  = postfix
     group = postfix
     mode  = 0660
   }

   unix_listener auth-userdb {
     user  = vmail
     group = vmail
     mode  = 0660
   }
}

service auth-worker {
   user  = vmail
   group = vmail
   process_limit = 4
}

# ——————————————————————————————————————
# Service: lmtp (mail delivery from Postfix)
# ——————————————————————————————————————
service lmtp {
   unix_listener /var/spool/postfix/private/dovecot-lmtp {
     user  = postfix
     group = postfix
     mode  = 0660
   }
}

# ——————————————————————————————————————
# Service: imap-login (IMAPS on 993; plain IMAP disabled)
# ——————————————————————————————————————
service imap-login {
   inet_listener imap {
     port = 0
   }

   inet_listener imaps {
     port = 993
     ssl  = yes
   }

   restart_request_count = unlimited
   process_min_avail = 8
}

service imap {
   vsz_limit = 4G
}

# ——————————————————————————————————————
# Service: submission-login (disabled — Postfix handles 587/465)
# ——————————————————————————————————————
service submission-login {
   inet_listener submission {
     port = 0
   }
}

# ——————————————————————————————————————
# Service: pop3-login (disabled)
# ——————————————————————————————————————
service pop3-login {
   inet_listener pop3 {
     port = 0
   }
   inet_listener pop3s {
     port = 0
   }
}

# ——————————————————————————————————————
# Service: quota-status (Postfix recipient-time quota check)
# ——————————————————————————————————————
service quota-status {
   executable = /usr/lib/dovecot/quota-status -p postfix
   unix_listener /var/spool/postfix/private/quota-status {
     user = postfix
   }
}


Adam L Miller

------ Original Message ------
>From "dovecot--- via dovecot" <[email protected]>
To [email protected]
Date 8/5/2026 2:47:30 PM
Subject Re: Can't connect to MySQL without SSL

>@basti require_secure_transport is OFF, I had checked that.
>
>Hi Timo!
>
>Creating the mysql-client.cnf didn't change the behavior, it tries to connect even with this minimal configuration:
>
>/etc/dovecot/dovecot.conf:
>sql_driver = mysql
>
>mysql host.docker.internal {
>   option_file = /etc/dovecot/mysql-client.cnf
>}
>
>/etc/dovecot/mysql-client.cnf:
>[client]
>ssl-mode=DISABLED
>
>Still gets me an error:
>TLS/SSL error: self-signed certificate in certificate chain
>
>In the meantime I will try to make it work using SSL. But the last time I tried it somehow conflicted with the "ssl_server_cert_file" and "ssl_server_key_file" which point to the certbot/letsencrypt certificates while MySQL generates self-signed certificates.
>
>Thanks for your help so far!
>_______________________________________________
>dovecot mailing list -- [email protected]
>To unsubscribe send an email to [email protected]

_______________________________________________
dovecot mailing list -- [email protected]
To unsubscribe send an email to [email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.