deliver fails because of a permission issue with SSL private key file
Hi,
I'm trying to make Postfix hand incoming mail to Dovecot by using Dovecot's deliver. But this fails with a permission error:
Feb 17 15:50:12 debian13-cont postfix/pipe[13133]: 171C17206: to=<recipient@dest.examle.org>, relay=dovecot, delay=0.17, delays=0.1/0/0/0.07, dsn=5.3.0, status=bounced (Command died with status 89: "/usr/lib/dovecot/deliver". Command output: doveconf: Fatal: Error in configuration file /etc/dovecot/certs.conf line 3: key_file: open(/etc/ssl/private/ssl-cert-snakeoil.key) failed: Permission denied )
How can I solve this (short of making the private key file world readable, of course)?
Regards mks
I have this in Postfix' master.cf:
dovecot unix - n n - - pipe flags=DROhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -e -f ${sender} -a ${recipient} -d ${user}@${domain}
LANG=C id vmail
uid=501(vmail) gid=501(vmail) groups=501(vmail),104(ssl-cert)
LANG=C ls -l /etc/ssl/private/
total 4 -rw-r----- 1 root ssl-cert 1704 Feb 4 17:15 ssl-cert-snakeoil.key
doveconf -n
2.4.2-2+debian13 (0962ed2104): /etc/dovecot/dovecot.conf
Pigeonhole version 2.4.2-2+debian13 (767418c3)
OS: Linux 6.19.0-2-MANJARO x86_64 Debian 13.3 btrfs
Hostname: debian13-cont
dovecot_config_version = 2.4.2 dovecot_storage_version = 2.4.2 log_debug = category=sql mail_driver = sdbox mail_gid = vmail mail_home = /var/spool/vmail/home/%{user | domain}/%{user | username} mail_path = /var/spool/vmail/mail/%{user | domain}/%{user | username} mail_plugins { quota = yes } mail_uid = vmail protocols = imap lmtp sieve sql_driver = mysql mysql localhost { dbname = postfixadmin password = # hidden, use -P to show it user = postfixadmin } passdb sql { query = SELECT 'vmail' AS userdb_uid, 'vmail' AS userdb_gid, CONCAT('/var/spool/vmail/home/', maildir) AS userdb_home, CONCAT(quota, 'B') AS userdb_quota_storage_size, username AS user, password FROM mailbox WHERE username = '%{user}' AND active = '1'; } userdb prefetch { } userdb sql { iterate_query = SELECT username AS user FROM mailbox WHERE active = '1'; query = SELECT 'vmail' AS uid, 'vmail' AS gid, CONCAT('/var/spool/vmail/home/', maildir) AS home, CONCAT(quota, 'B') AS quota_storage_size, username AS user, password FROM mailbox WHERE username = '%{user}' AND active = '1'; } namespace inbox { inbox = yes separator = / mailbox Drafts { special_use = "\\Drafts" } mailbox Entwürfe { special_use = "\\Drafts" } mailbox Junk { special_use = "\\Junk" } mailbox Trash { special_use = "\\Trash" } mailbox "Gelöschte Objekte" { special_use = "\\Trash" } mailbox Sent { special_use = "\\Sent" } mailbox "Gesendete Objekte" { special_use = "\\Sent" } } service auth { inet_listener tcp_auth { port = 12345 } unix_listener /var/spool/postfix/private/auth { group = postfix mode = 0666 user = postfix } } service auth-worker { } ssl_server { cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem key_file = /etc/ssl/private/ssl-cert-snakeoil.key } protocol imap { mail_plugins { imap_quota = yes } } quota "User quota" { } dict_server { dict mysql { driver = sql sql_driver = mysql dict_map priv/quota/messages { sql_table = quota username_field = username dict_map_value_field messages { } } dict_map priv/quota/storage { sql_table = quota username_field = username dict_map_value_field bytes { } } } } quota_clone { dict proxy { name = mysql } }
This looks more like syntax error than permission error.
Aki
On 17/02/2026 17:19 EET Markus Schoenhaber via dovecot
<[1]dovecot@dovecot.org> wrote:
Hi,
I'm trying to make Postfix hand incoming mail to Dovecot by using
Dovecot's deliver. But this fails with a permission error:
Feb 17 15:50:12 debian13-cont postfix/pipe[13133]: 171C17206:
to=<[2]recipient@dest.examle.org>, relay=dovecot, delay=0.17,
delays=0.1/0/0/0.07, dsn=5.3.0, status=bounced (Command died with
status 89: "/usr/lib/dovecot/deliver". Command output: doveconf:
Fatal: Error in configuration file /etc/dovecot/certs.conf line 3:
key_file: open(/etc/ssl/private/ssl-cert-snakeoil.key) failed:
Permission denied )
How can I solve this (short of making the private key file world
readable, of course)?
Regards
mks
I have this in Postfix' master.cf:
dovecot unix - n n - - pipe
flags=DROhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -e -f
${sender} -a ${recipient} -d ${user}@${domain}
# LANG=C id vmail
uid=501(vmail) gid=501(vmail) groups=501(vmail),104(ssl-cert)
# LANG=C ls -l /etc/ssl/private/
total 4
-rw-r----- 1 root ssl-cert 1704 Feb 4 17:15 ssl-cert-snakeoil.key
# doveconf -n
# 2.4.2-2+debian13 (0962ed2104): /etc/dovecot/dovecot.conf
# Pigeonhole version 2.4.2-2+debian13 (767418c3)
# OS: Linux 6.19.0-2-MANJARO x86_64 Debian 13.3 btrfs
# Hostname: debian13-cont
dovecot_config_version = 2.4.2
dovecot_storage_version = 2.4.2
log_debug = category=sql
mail_driver = sdbox
mail_gid = vmail
mail_home = /var/spool/vmail/home/%{user | domain}/%{user | username}
mail_path = /var/spool/vmail/mail/%{user | domain}/%{user | username}
mail_plugins {
quota = yes
}
mail_uid = vmail
protocols = imap lmtp sieve
sql_driver = mysql
mysql localhost {
dbname = postfixadmin
password = # hidden, use -P to show it
user = postfixadmin
}
passdb sql {
query = SELECT 'vmail' AS userdb_uid, 'vmail' AS userdb_gid,
CONCAT('/var/spool/vmail/home/', maildir) AS userdb_home, CONCAT(quota,
'B') AS userdb_quota_storage_size, username AS user, password FROM
mailbox WHERE username = '%{user}' AND active = '1';
}
userdb prefetch {
}
userdb sql {
iterate_query = SELECT username AS user FROM mailbox WHERE active = '1';
query = SELECT 'vmail' AS uid, 'vmail' AS gid,
CONCAT('/var/spool/vmail/home/', maildir) AS home, CONCAT(quota, 'B') AS
quota_storage_size, username AS user, password FROM mailbox WHERE
username = '%{user}' AND active = '1';
}
namespace inbox {
inbox = yes
separator = /
mailbox Drafts {
special_use = "\\Drafts"
}
mailbox Entwuerfe {
special_use = "\\Drafts"
}
mailbox Junk {
special_use = "\\Junk"
}
mailbox Trash {
special_use = "\\Trash"
}
mailbox "Geloeschte Objekte" {
special_use = "\\Trash"
}
mailbox Sent {
special_use = "\\Sent"
}
mailbox "Gesendete Objekte" {
special_use = "\\Sent"
}
}
service auth {
inet_listener tcp_auth {
port = 12345
}
unix_listener /var/spool/postfix/private/auth {
group = postfix
mode = 0666
user = postfix
}
}
service auth-worker {
}
ssl_server {
cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
key_file = /etc/ssl/private/ssl-cert-snakeoil.key
}
protocol imap {
mail_plugins {
imap_quota = yes
}
}
quota "User quota" {
}
dict_server {
dict mysql {
driver = sql
sql_driver = mysql
dict_map priv/quota/messages {
sql_table = quota
username_field = username
dict_map_value_field messages {
}
}
dict_map priv/quota/storage {
sql_table = quota
username_field = username
dict_map_value_field bytes {
}
}
}
}
quota_clone {
dict proxy {
name = mysql
}
}
_______________________________________________
dovecot mailing list -- [3]dovecot@dovecot.org
To unsubscribe send an email to [4]dovecot-leave@dovecot.org
References
Visible links
- mailto:dovecot@dovecot.org
- mailto:recipient@dest.examle.org
- mailto:dovecot@dovecot.org
- mailto:dovecot-leave@dovecot.org
17.02.26, 16:26 +0100, Aki Tuomi via dovecot:
This looks more like syntax error than permission error.
Then please tell me: what exactly is wrong syntax-wise?
And why is no syntax error reported but "Permission denied"?
Regards mks
Aki
On 17/02/2026 17:19 EET Markus Schoenhaber via dovecot <[1]dovecot@dovecot.org> wrote: Hi, I'm trying to make Postfix hand incoming mail to Dovecot by using Dovecot's deliver. But this fails with a permission error: Feb 17 15:50:12 debian13-cont postfix/pipe[13133]: 171C17206: to=<[2]recipient@dest.examle.org>, relay=dovecot, delay=0.17, delays=0.1/0/0/0.07, dsn=5.3.0, status=bounced (Command died with status 89: "/usr/lib/dovecot/deliver". Command output: doveconf: Fatal: Error in configuration file /etc/dovecot/certs.conf line 3: key_file: open(/etc/ssl/private/ssl-cert-snakeoil.key) failed: Permission denied ) How can I solve this (short of making the private key file world readable, of course)? Regards mks I have this in Postfix' master.cf: dovecot unix - n n - - pipe flags=DROhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -e -f ${sender} -a ${recipient} -d ${user}@${domain} # LANG=C id vmail uid=501(vmail) gid=501(vmail) groups=501(vmail),104(ssl-cert) # LANG=C ls -l /etc/ssl/private/ total 4 -rw-r----- 1 root ssl-cert 1704 Feb 4 17:15 ssl-cert-snakeoil.key # doveconf -n # 2.4.2-2+debian13 (0962ed2104): /etc/dovecot/dovecot.conf # Pigeonhole version 2.4.2-2+debian13 (767418c3) # OS: Linux 6.19.0-2-MANJARO x86_64 Debian 13.3 btrfs # Hostname: debian13-cont dovecot_config_version = 2.4.2 dovecot_storage_version = 2.4.2 log_debug = category=sql mail_driver = sdbox mail_gid = vmail mail_home = /var/spool/vmail/home/%{user | domain}/%{user | username} mail_path = /var/spool/vmail/mail/%{user | domain}/%{user | username} mail_plugins { quota = yes } mail_uid = vmail protocols = imap lmtp sieve sql_driver = mysql mysql localhost { dbname = postfixadmin password = # hidden, use -P to show it user = postfixadmin } passdb sql { query = SELECT 'vmail' AS userdb_uid, 'vmail' AS userdb_gid, CONCAT('/var/spool/vmail/home/', maildir) AS userdb_home, CONCAT(quota, 'B') AS userdb_quota_storage_size, username AS user, password FROM mailbox WHERE username = '%{user}' AND active = '1'; } userdb prefetch { } userdb sql { iterate_query = SELECT username AS user FROM mailbox WHERE active = '1'; query = SELECT 'vmail' AS uid, 'vmail' AS gid, CONCAT('/var/spool/vmail/home/', maildir) AS home, CONCAT(quota, 'B') AS quota_storage_size, username AS user, password FROM mailbox WHERE username = '%{user}' AND active = '1'; } namespace inbox { inbox = yes separator = / mailbox Drafts { special_use = "\\Drafts" } mailbox Entwuerfe { special_use = "\\Drafts" } mailbox Junk { special_use = "\\Junk" } mailbox Trash { special_use = "\\Trash" } mailbox "Geloeschte Objekte" { special_use = "\\Trash" } mailbox Sent { special_use = "\\Sent" } mailbox "Gesendete Objekte" { special_use = "\\Sent" } } service auth { inet_listener tcp_auth { port = 12345 } unix_listener /var/spool/postfix/private/auth { group = postfix mode = 0666 user = postfix } } service auth-worker { } ssl_server { cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem key_file = /etc/ssl/private/ssl-cert-snakeoil.key } protocol imap { mail_plugins { imap_quota = yes } } quota "User quota" { } dict_server { dict mysql { driver = sql sql_driver = mysql dict_map priv/quota/messages { sql_table = quota username_field = username dict_map_value_field messages { } } dict_map priv/quota/storage { sql_table = quota username_field = username dict_map_value_field bytes { } } } } quota_clone { dict proxy { name = mysql } } _______________________________________________ dovecot mailing list -- [3]dovecot@dovecot.org To unsubscribe send an email to [4]dovecot-leave@dovecot.orgReferences
Visible links
- mailto:dovecot@dovecot.org
- mailto:recipient@dest.examle.org
- mailto:dovecot@dovecot.org
- mailto:dovecot-leave@dovecot.org
dovecot mailing list -- dovecot@dovecot.org To unsubscribe send an email to dovecot-leave@dovecot.org
Am 17.02.26 um 16:38 schrieb Markus Schönhaber via dovecot:
17.02.26, 16:26 +0100, Aki Tuomi via dovecot:
This looks more like syntax error than permission error.
Then please tell me: what exactly is wrong syntax-wise?
And why is no syntax error reported but "Permission denied"?
And is the syntax error expected to go away, if I make the private key file world readable? Because if I do, delivery works fine.
Regards mks
Aki
On 17/02/2026 17:19 EET Markus Schoenhaber via dovecot <[1]dovecot@dovecot.org> wrote: Hi, I'm trying to make Postfix hand incoming mail to Dovecot by using Dovecot's deliver. But this fails with a permission error: Feb 17 15:50:12 debian13-cont postfix/pipe[13133]: 171C17206: to=<[2]recipient@dest.examle.org>, relay=dovecot, delay=0.17, delays=0.1/0/0/0.07, dsn=5.3.0, status=bounced (Command died with status 89: "/usr/lib/dovecot/deliver". Command output: doveconf: Fatal: Error in configuration file /etc/dovecot/certs.conf line 3: key_file: open(/etc/ssl/private/ssl-cert-snakeoil.key) failed: Permission denied ) How can I solve this (short of making the private key file world readable, of course)? Regards mks I have this in Postfix' master.cf: dovecot unix - n n - - pipe flags=DROhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -e -f ${sender} -a ${recipient} -d ${user}@${domain} # LANG=C id vmail uid=501(vmail) gid=501(vmail) groups=501(vmail),104(ssl-cert) # LANG=C ls -l /etc/ssl/private/ total 4 -rw-r----- 1 root ssl-cert 1704 Feb 4 17:15 ssl-cert-snakeoil.key # doveconf -n # 2.4.2-2+debian13 (0962ed2104): /etc/dovecot/dovecot.conf # Pigeonhole version 2.4.2-2+debian13 (767418c3) # OS: Linux 6.19.0-2-MANJARO x86_64 Debian 13.3 btrfs # Hostname: debian13-cont dovecot_config_version = 2.4.2 dovecot_storage_version = 2.4.2 log_debug = category=sql mail_driver = sdbox mail_gid = vmail mail_home = /var/spool/vmail/home/%{user | domain}/%{user | username} mail_path = /var/spool/vmail/mail/%{user | domain}/%{user | username} mail_plugins { quota = yes } mail_uid = vmail protocols = imap lmtp sieve sql_driver = mysql mysql localhost { dbname = postfixadmin password = # hidden, use -P to show it user = postfixadmin } passdb sql { query = SELECT 'vmail' AS userdb_uid, 'vmail' AS userdb_gid, CONCAT('/var/spool/vmail/home/', maildir) AS userdb_home, CONCAT(quota, 'B') AS userdb_quota_storage_size, username AS user, password FROM mailbox WHERE username = '%{user}' AND active = '1'; } userdb prefetch { } userdb sql { iterate_query = SELECT username AS user FROM mailbox WHERE active = '1'; query = SELECT 'vmail' AS uid, 'vmail' AS gid, CONCAT('/var/spool/vmail/home/', maildir) AS home, CONCAT(quota, 'B') AS quota_storage_size, username AS user, password FROM mailbox WHERE username = '%{user}' AND active = '1'; } namespace inbox { inbox = yes separator = / mailbox Drafts { special_use = "\\Drafts" } mailbox Entwuerfe { special_use = "\\Drafts" } mailbox Junk { special_use = "\\Junk" } mailbox Trash { special_use = "\\Trash" } mailbox "Geloeschte Objekte" { special_use = "\\Trash" } mailbox Sent { special_use = "\\Sent" } mailbox "Gesendete Objekte" { special_use = "\\Sent" } } service auth { inet_listener tcp_auth { port = 12345 } unix_listener /var/spool/postfix/private/auth { group = postfix mode = 0666 user = postfix } } service auth-worker { } ssl_server { cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem key_file = /etc/ssl/private/ssl-cert-snakeoil.key } protocol imap { mail_plugins { imap_quota = yes } } quota "User quota" { } dict_server { dict mysql { driver = sql sql_driver = mysql dict_map priv/quota/messages { sql_table = quota username_field = username dict_map_value_field messages { } } dict_map priv/quota/storage { sql_table = quota username_field = username dict_map_value_field bytes { } } } } quota_clone { dict proxy { name = mysql } } _______________________________________________ dovecot mailing list -- [3]dovecot@dovecot.org To unsubscribe send an email to [4]dovecot-leave@dovecot.orgReferences
Visible links
- mailto:dovecot@dovecot.org
- mailto:recipient@dest.examle.org
- mailto:dovecot@dovecot.org
- mailto:dovecot-leave@dovecot.org
dovecot mailing list -- dovecot@dovecot.org To unsubscribe send an email to dovecot-leave@dovecot.org
dovecot mailing list -- dovecot@dovecot.org To unsubscribe send an email to dovecot-leave@dovecot.org
Markus Schönhaber via dovecot skrev den 2026-02-17 16:53:
Because if I do, delivery works fine.
i have ssl pem files to be root only, dovecot loads ssl certs as root user, before it drops privelges, all servives below port 1024 do this always, your issue is where dovecot pem files is located, when parrent dir denied access to the pem files
if world can read private keys, then is sooks :)
dont make that mistake
17.02.26, 17:11 +0100, Benny Pedersen via dovecot:
Markus Schönhaber via dovecot skrev den 2026-02-17 16:53:
if world can read private keys, then is sooks :)
I know that.
I simply wanted to know whether what "looks more like syntax error than permission error" goes away if I change the permission. And it does.
-- Regards mks
On 17/02/2026 18:19 EET Markus Schoenhaber via dovecot
<[1]dovecot@dovecot.org> wrote:
17.02.26, 17:11 +0100, Benny Pedersen via dovecot:
Markus Schoenhaber via dovecot skrev den 2026-02-17 16:53:
if world can read private keys, then is sooks :)
I know that.
I simply wanted to know whether what "looks more like syntax error than
permission error" goes away if I change the permission.
And it does.
--
Regards
mks
_______________________________________________
dovecot mailing list -- [2]dovecot@dovecot.org
To unsubscribe send an email to [3]dovecot-leave@dovecot.org
Looks like my mail client showed your email wrong. Apologies.
You can workaround this issue with
ssl = no !try_include /etc/dovecot/ssl.conf
and put
ssl = yes ssl_server { ... }
in ssl.conf and chmod 0640 root:root.
Aki
References
Visible links
- mailto:dovecot@dovecot.org
- mailto:dovecot@dovecot.org
- mailto:dovecot-leave@dovecot.org
17.02.26, 17:36 +0100, Aki Tuomi via dovecot:
Looks like my mail client showed your email wrong. Apologies.
You can workaround this issue with
ssl = no !try_include /etc/dovecot/ssl.conf
and put
ssl = yes ssl_server { ... }
in ssl.conf and chmod 0640 root:root.
Aki
That works.
Thank you very much for the quick help, Aki!
-- Regards mks
Thanks, Aki!
I was about to post essentially the same problem (except in my case fetchmail executes deliver). What you sent makes it work for me.
I'd like to understand a bit more, if you've got time to explain or point to relevant doc sections.
Is this expected behavior in 2.4, or is it considered a bug?
If it's expected behavior, why does this workaround work?
Thanks again,
-Martin
On 2/17/26 8:36 AM, Aki Tuomi via dovecot wrote:
On 17/02/2026 18:19 EET Markus Schoenhaber via dovecot <[1]dovecot@dovecot.org> wrote: 17.02.26, 17:11 +0100, Benny Pedersen via dovecot: Markus Schoenhaber via dovecot skrev den 2026-02-17 16:53: if world can read private keys, then is sooks :) I know that. I simply wanted to know whether what "looks more like syntax error than permission error" goes away if I change the permission. And it does. -- Regards mks _______________________________________________ dovecot mailing list -- [2]dovecot@dovecot.org To unsubscribe send an email to [3]dovecot-leave@dovecot.org Looks like my mail client showed your email wrong. Apologies. You can workaround this issue with ssl = no !try_include /etc/dovecot/ssl.conf and put ssl = yes ssl_server { ... } in ssl.conf and chmod 0640 root:root. AkiReferences
Visible links 1. mailto:dovecot@dovecot.org 2. mailto:dovecot@dovecot.org 3. mailto:dovecot-leave@dovecot.org
dovecot mailing list -- dovecot@dovecot.org To unsubscribe send an email to dovecot-leave@dovecot.org
- Martin McClure via dovecot:
Is this expected behavior in 2.4, or is it considered a bug?
I'm not Aki, but since I ran into the same issue a while back: I'd like to repeat that I do consider this to be a bug. It also affects doveadm use, for example.
The problem occurs when a non-root process triggers evaluation of the Dovecot config and is unable to read the TLS key files. Protecting these files is of course important, and some random user invoking doveadm in their command shell should have no reason to access sensitive files. IMO, Dovecot should not even attempt to read TLS related files in this case. They are not needed at this time.
If it's expected behavior, why does this workaround work?
The "!include_try foo.conf" succeeds when run as root, e.g. during Dovecot startup, but fails silently for non-root owned processes. That's why it works as a workaround.
-Ralph
Thanks, Ralph.
OK, that makes sense. Dovecot reads the config file (not a bug) and if it sees the name of the ssl key_file it tries to read /that/ file (yeah, that sounds very much like a bug) and when it can't it bails. It should only try to read the cert/key files if it is going to need to use them.
And wrapping the cert/key filenames in a config file that is itself unreadable is evil and clever and, well, useful in this case.
Regards,
-Martin
On 2/17/26 6:33 PM, Ralph Seichter via dovecot wrote:
- Martin McClure via dovecot:
Is this expected behavior in 2.4, or is it considered a bug? I'm not Aki, but since I ran into the same issue a while back: I'd like to repeat that I do consider this to be a bug. It also affects doveadm use, for example.
The problem occurs when a non-root process triggers evaluation of the Dovecot config and is unable to read the TLS key files. Protecting these files is of course important, and some random user invoking doveadm in their command shell should have no reason to access sensitive files. IMO, Dovecot should not even attempt to read TLS related files in this case. They are not needed at this time.
If it's expected behavior, why does this workaround work? The "!include_try foo.conf" succeeds when run as root, e.g. during Dovecot startup, but fails silently for non-root owned processes. That's why it works as a workaround.
-Ralph
dovecot mailing list --dovecot@dovecot.org To unsubscribe send an email todovecot-leave@dovecot.org
Thanks, Ralph.
OK, that makes sense. Dovecot reads the config file (not a bug) and if it sees the name of the ssl key_file it tries to read that file (yeah, that sounds very much like a bug) and when it can't it bails. It should only try to read the cert/key files if it is going to need to use them.
And wrapping the cert/key filenames in a config file that is itself unreadable is evil and clever and, well, useful in this case.
Regards,
-Martin
On 2/17/26 6:33 PM, Ralph Seichter via dovecot wrote:
* Martin McClure via dovecot:
Is this expected behavior in 2.4, or is it considered a bug?
I'm not Aki, but since I ran into the same issue a while back: I'd like to repeat that I do consider this to be a bug. It also affects doveadm use, for example.
The problem occurs when a non-root process triggers evaluation of the Dovecot config and is unable to read the TLS key files. Protecting these files is of course important, and some random user invoking doveadm in their command shell should have no reason to access sensitive files. IMO, Dovecot should not even attempt to read TLS related files in this case. They are not needed at this time.
If it's expected behavior, why does this workaround work?
The "!include_try foo.conf" succeeds when run as root, e.g. during Dovecot startup, but fails silently for non-root owned processes. That's why it works as a workaround.
-Ralph
dovecot mailing list -- [1]dovecot@dovecot.org To unsubscribe send an email to [2]dovecot-leave@dovecot.org
References
Visible links
- mailto:dovecot@dovecot.org
- mailto:dovecot-leave@dovecot.org
On February 18, 2026 8:05:58 AM GMT+02:00, Martin McClure via dovecot <dovecot@dovecot.org> wrote:
Thanks, Ralph.
OK, that makes sense. Dovecot reads the config file (not a bug) and if it sees the name of the ssl key_file it tries to read /that/ file (yeah, that sounds very much like a bug) and when it can't it bails. It should only try to read the cert/key files if it is going to need to use them.
And wrapping the cert/key filenames in a config file that is itself unreadable is evil and clever and, well, useful in this case.
Regards,
-Martin
On 2/17/26 6:33 PM, Ralph Seichter via dovecot wrote:
- Martin McClure via dovecot:
Is this expected behavior in 2.4, or is it considered a bug? I'm not Aki, but since I ran into the same issue a while back: I'd like to repeat that I do consider this to be a bug. It also affects doveadm use, for example.
The problem occurs when a non-root process triggers evaluation of the Dovecot config and is unable to read the TLS key files. Protecting these files is of course important, and some random user invoking doveadm in their command shell should have no reason to access sensitive files. IMO, Dovecot should not even attempt to read TLS related files in this case. They are not needed at this time.
If it's expected behavior, why does this workaround work? The "!include_try foo.conf" succeeds when run as root, e.g. during Dovecot startup, but fails silently for non-root owned processes. That's why it works as a workaround.
-Ralph
dovecot mailing list --dovecot@dovecot.org To unsubscribe send an email todovecot-leave@dovecot.org This is indeed a bug. It should get fixed in next release.
Aki
Thank you very much, Aki! After wasting 3+ hrs on this today, I stepped over this thread - just in time. This workaround works perfectly and I appreciate you are going to fix it for good it in the next release.
Just for those who still struggle with it:
Use !include_try ssl.conf (not try_include as posted by Aki). And if you have your ssl_server_key_file already in conf.d/10-ssl.conf, you might already be using include_try in your dovecot.conf as provided by Debian packages:
!include_try conf.d/*.conf
So you just need to make sure only root can read it: $ chmod 640 conf.d/10-ssl.conf And the include_try will silently fail for dovecot-lda (invoked by Postfix and ideally running under user dovecot, or even a more restricted user vmail).
Cheers, Philip
On 18 Feb 2026, at 08:02, Aki Tuomi via dovecot <dovecot@dovecot.org> wrote:
On February 18, 2026 8:05:58 AM GMT+02:00, Martin McClure via dovecot <dovecot@dovecot.org <mailto:dovecot@dovecot.org>> wrote:
Thanks, Ralph.
OK, that makes sense. Dovecot reads the config file (not a bug) and if it sees the name of the ssl key_file it tries to read /that/ file (yeah, that sounds very much like a bug) and when it can't it bails. It should only try to read the cert/key files if it is going to need to use them.
And wrapping the cert/key filenames in a config file that is itself unreadable is evil and clever and, well, useful in this case.
Regards,
-Martin
On 2/17/26 6:33 PM, Ralph Seichter via dovecot wrote:
- Martin McClure via dovecot:
Is this expected behavior in 2.4, or is it considered a bug? I'm not Aki, but since I ran into the same issue a while back: I'd like to repeat that I do consider this to be a bug. It also affects doveadm use, for example.
The problem occurs when a non-root process triggers evaluation of the Dovecot config and is unable to read the TLS key files. Protecting these files is of course important, and some random user invoking doveadm in their command shell should have no reason to access sensitive files. IMO, Dovecot should not even attempt to read TLS related files in this case. They are not needed at this time.
If it's expected behavior, why does this workaround work? The "!include_try foo.conf" succeeds when run as root, e.g. during Dovecot startup, but fails silently for non-root owned processes. That's why it works as a workaround.
-Ralph
dovecot mailing list --dovecot@dovecot.org <mailto:dovecot@dovecot.org> To unsubscribe send an email todovecot-leave@dovecot.org <mailto:todovecot-leave@dovecot.org> This is indeed a bug. It should get fixed in next release.
Aki
dovecot mailing list -- dovecot@dovecot.org <mailto:dovecot@dovecot.org> To unsubscribe send an email to dovecot-leave@dovecot.org <mailto:dovecot-leave@dovecot.org>
Thank you very much, Aki!
After wasting 3+ hrs on this today, I stepped over this thread - just in
time.
This workaround works perfectly and I appreciate you are going to fix it
for good it in the next release.
Just for those who still struggle with it:
Use !include_try ssl.conf (not try_include as posted by Aki). And if
you have your ssl_server_key_file already in conf.d/10-ssl.conf, you might
already be using include_try in your dovecot.conf as provided by Debian
packages:
!include_try conf.d/*.conf
So you just need to make sure only root can read it:
$ chmod 640 conf.d/10-ssl.conf
And the include_try will silently fail for dovecot-lda (invoked by Postfix
and ideally running under user dovecot, or even a more restricted user
vmail).
Cheers,
Philip
On 18 Feb 2026, at 08:02, Aki Tuomi via dovecot <dovecot@dovecot.org>
wrote:
On February 18, 2026 8:05:58 AM GMT+02:00, Martin McClure via dovecot
<[1]dovecot@dovecot.org> wrote:
Thanks, Ralph.
OK, that makes sense. Dovecot reads the config file (not a bug) and if
it sees the name of the ssl key_file it tries to read /that/ file
(yeah, that sounds very much like a bug) and when it can't it bails.
It should only try to read the cert/key files if it is going to need
to use them.
And wrapping the cert/key filenames in a config file that is itself
unreadable is evil and clever and, well, useful in this case.
Regards,
-Martin
On 2/17/26 6:33 PM, Ralph Seichter via dovecot wrote:
* Martin McClure via dovecot:
Is this expected behavior in 2.4, or is it considered a bug?
I'm not Aki, but since I ran into the same issue a while back: I'd
like
to repeat that I do consider this to be a bug. It also affects
doveadm
use, for example.
The problem occurs when a non-root process triggers evaluation of
the
Dovecot config and is unable to read the TLS key files. Protecting
these
files is of course important, and some random user invoking doveadm
in
their command shell should have no reason to access sensitive files.
IMO, Dovecot should not even attempt to read TLS related files in
this
case. They are not needed at this time.
If it's expected behavior, why does this workaround work?
The "!include_try foo.conf" succeeds when run as root, e.g. during
Dovecot startup, but fails silently for non-root owned processes.
That's
why it works as a workaround.
-Ralph
_______________________________________________
dovecot mailing list --[2]dovecot@dovecot.org
To unsubscribe send an email [3]todovecot-leave@dovecot.org
This is indeed a bug. It should get fixed in next release.
Aki
_______________________________________________
dovecot mailing list -- [4]dovecot@dovecot.org
To unsubscribe send an email to [5]dovecot-leave@dovecot.org
References
Visible links
- mailto:dovecot@dovecot.org
- mailto:dovecot@dovecot.org
- mailto:todovecot-leave@dovecot.org
- mailto:dovecot@dovecot.org
- mailto:dovecot-leave@dovecot.org
Markus Schönhaber via dovecot skrev den 2026-02-17 16:19:
I'm trying to make Postfix hand incoming mail to Dovecot by using Dovecot's deliver. But this fails with a permission error:
https://doc.dovecot.org/2.3/configuration_manual/howto/postfix_dovecot_lmtp/
still works on all versions of dovecot / postfix
remember virtual alias should on the postfix side be ending in mailbox, since dovecot cant make the alias expanding, it works here just nicely
participants (6)
-
Aki Tuomi
-
Benny Pedersen
-
Markus Schönhaber
-
Martin McClure
-
Philip Iezzi
-
Ralph Seichter