Skip to content

Conversation

@DerLinkman
Copy link
Member

Contribution Guidelines

What does this PR include?

Short Description

This pull request introduces a major overhaul and modernization of the Dovecot configuration for the mail server. The changes include a migration to new-style configuration files, significant improvements to SQL and authentication integration, updated plugin and service management, and enhanced security defaults. The Dockerfile is also updated to use a newer Alpine base image. Below are the most important changes grouped by theme:

Configuration Modernization and Structure:

  • Introduced new modular configuration files in data/conf/dovecot/conf.d/, covering core, mail, SSL, SQL, storage, performance, authentication, userdb, and service definitions for improved clarity and maintainability. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]

Authentication and SQL Integration:

  • Refactored Lua authentication script to use the correct request fields, improved error handling, and added a custom cache key function for better auth caching. [1] [2] [3] [4] [5]
  • Overhauled SQL dict and userdb configuration generation to use Dovecot's new dict_map syntax and variable expansion, improving flexibility and compatibility.

Plugin and Service Management:

  • Updated plugin lists for IMAP, LMTP, and general mail to include new plugins (e.g., quota_clone, mail_compress) and removed deprecated options, with conditional handling based on FTS settings.
  • Added new service definitions for Dovecot components (auth, imap, lmtp, managesieve, quota-warning, etc.) in a dedicated config file.

Security and Protocol Improvements:

  • Set minimum TLS protocol to 1.2 and updated SSL cipher settings, aligning with modern security standards.
  • Replaced deprecated SSL config directives and improved SNI certificate handling for better compatibility.
  • Updated ACL and cleartext authentication handling for more explicit and secure configuration. [1] [2] [3]

Other Notable Changes:

  • Updated Dockerfile to use Alpine 3.22 base for newer package support.
  • Updated FTS configuration file references and removed legacy OpenSSL compatibility hacks. [1] [2]
  • Improved shared namespace configuration for mailbox sharing features.

These changes collectively bring the Dovecot setup up to date with current best practices, improve maintainability, and enhance both security and feature support.

Affected Containers

  • dovecot-mailcow (mainly)

Did you run tests?

What did you tested?

WIP

@Westie
Copy link

Westie commented Aug 29, 2025

Nice!

Can you add data/conf/dovecot/extra.d/*or something else relevant to .gitignore as part of this PR please?

!include_try /etc/dovecot/sni.conf
!include_try /etc/dovecot/sogo_trusted_ip.conf
!include_try /etc/dovecot/shared_namespace.conf
!include_try /etc/dovecot/conf.d/fts.conf
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this line is needed anymore.

driver = mysql
connect = "host=/var/run/mysqld/mysqld.sock dbname=${DBNAME} user=${DBUSER} password=${DBPASS}"
user_query = SELECT CONCAT(JSON_UNQUOTE(JSON_VALUE(attributes, '$.mailbox_format')), mailbox_path_prefix, '%d/%n/${MAILDIR_SUB}:VOLATILEDIR=/var/volatile/%u:INDEX=/var/vmail_index/%u') AS mail, '%s' AS protocol, 5000 AS uid, 5000 AS gid, concat('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%u' AND (active = '1' OR active = '2')
query = SELECT CONCAT(JSON_UNQUOTE(JSON_VALUE(attributes, '$.mailbox_format')), mailbox_path_prefix, '%{user | domain }}/%{user | username }/Maildir:VOLATILEDIR=/var/volatile/%{user}:INDEX=/var/vmail_index/%{user}') AS mail, '%{protocol}' AS protocol, 5000 AS uid, 5000 AS gid, concat('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%{user}' AND (active = '1' OR active = '2')
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You seem to have an accidental double-brace here - see "}}".

function auth_password_verify(request, password)
request.domain = request.auth_user:match("@(.+)") or nil
if request.domain == nil then
return dovecot.auth.PASSDB_RESULT_USER_UNKNOWN, "No such user"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this return value, as well as the other return values, will return an error like Error: lua: passdb-lua: db-lua: auth_password_verify invalid return value (expected nil or table, got string). Instead, I think you should just return dovecot.auth.PASSDB_RESULT_USER_UNKNOWN without the string.

driver = mysql
connect = "host=/var/run/mysqld/mysqld.sock dbname=${DBNAME} user=${DBUSER} password=${DBPASS}"
user_query = SELECT CONCAT(JSON_UNQUOTE(JSON_VALUE(attributes, '$.mailbox_format')), mailbox_path_prefix, '%d/%n/${MAILDIR_SUB}:VOLATILEDIR=/var/volatile/%u:INDEX=/var/vmail_index/%u') AS mail, '%s' AS protocol, 5000 AS uid, 5000 AS gid, concat('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%u' AND (active = '1' OR active = '2')
query = SELECT CONCAT(JSON_UNQUOTE(JSON_VALUE(attributes, '$.mailbox_format')), mailbox_path_prefix, '%{user | domain }}/%{user | username }/Maildir:VOLATILEDIR=/var/volatile/%{user}:INDEX=/var/vmail_index/%{user}') AS mail, '%{protocol}' AS protocol, 5000 AS uid, 5000 AS gid, concat('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%{user}' AND (active = '1' OR active = '2')
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, you probably want to keep ${MAILDIR_SUB} instead of hard-coding Maildir for backward compatibility, along with the corresponding change in data/conf/dovecot/conf.d/10-mail.conf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants