Dovecot - mail_crypt - lmtp-server - no password to decrypt the key

Baljeet Bhinder contact at baljeetbhinder.ca
Sun Jan 8 16:55:06 UTC 2023


I have been using postfix+dovecot successfully for a while now until I 
tried mail crypt plugin lately. I tried what is describe here 
https://doc.dovecot.org/configuration_manual/mail_crypt_plugin/ and I 
went for global-keys as described here: 
https://doc.dovecot.org/configuration_manual/mail_crypt_plugin/#global-keys
/"A good solution for environments where no user folder sharing is 
needed is to generate per-user EC key pair and encrypt that with 
something derived from user’s password."/

I am setting mail_crypt_global_private_key, 
mail_crypt_global_public_key, mail_crypt_save_version from user_query 
and userdb_mail_crypt_global_private_key_password from password_query. 
mail_crypt seems to work fine in imap (I saved a message as draft and it 
is stored encrypted on the disk), but lmtp complains about 
"mail_crypt_global_private_key_password unset, no password to decrypt 
the key" As you can see below in logs that it was able to set all other 
mail_crypt_ configurations successfully from user_query. However, the 
password is provided via password_query and I assume lmtp does not read 
password_query. How else can I provide a password in lmtp? Is my 
approach correct to begin with?

-- Dovecot Configurations --
# using doveconf -n
# 2.3.19.1 (9b53102964): /etc/dovecot/dovecot.conf
# Pigeonhole version 0.5.19 (4eae2f79)
# OS: Linux 5.15.0-57-generic x86_64 Ubuntu 20.04.5 LTS
# Hostname: mailserver-dovecot-7c9ff7b94b-8ldrr
auth_mechanisms = plain login
auth_verbose = yes
auth_verbose_passwords = yes
debug_log_path = /dev/stdout
haproxy_trusted_networks = 192.168.0.0/16 10.10.10.0/24 10.10.30.0/24 
172.17.0.1/16
hostname = imap.mailserver.k8s.local pop.mailserver.k8s.local
info_log_path = /dev/stdout
listen = *
log_path = /dev/stdout
mail_debug = yes
mail_gid = 1000
mail_home = /var/vmail/mailboxes/%d/%n
mail_location = maildir:~/:LAYOUT=fs
mail_plugins = quota mail_crypt
mail_privileged_group = mail
mail_uid = 1000
managesieve_notify_capability = mailto
managesieve_sieve_capability = fileinto reject envelope 
encoded-character vacation subaddress comparator-i;ascii-numeric 
relational regex imap4flags copy include variables body enotify 
environment mailbox date index ihave duplicate mime foreverypart 
extracttext imapsieve vnd.dovecot.imapsieve
namespace inbox {
   inbox = yes
   location =
   mailbox Drafts {
     auto = subscribe
     special_use = \Drafts
   }
   mailbox Sent {
     auto = subscribe
     special_use = \Sent
   }
   mailbox "Sent Messages" {
     special_use = \Sent
   }
   mailbox Spam {
     auto = subscribe
     autoexpunge = 30 days
     special_use = \Junk
   }
   mailbox Trash {
     auto = subscribe
     autoexpunge = 30 days
     special_use = \Trash
   }
   prefix =
}
passdb {
   args = /etc/dovecot/dovecot-sql.conf.ext
   driver = sql
}
plugin {
   imapsieve_mailbox1_before = file:/var/vmail/sieve/global/learn-spam.sieve
   imapsieve_mailbox1_causes = COPY APPEND FLAG
   imapsieve_mailbox1_name = Spam
   imapsieve_mailbox2_before = file:/var/vmail/sieve/global/learn-ham.sieve
   imapsieve_mailbox2_causes = COPY APPEND FLAG
   imapsieve_mailbox2_from = Spam
   imapsieve_mailbox2_name = *
   mail_crypt_save_version = 0
   quota = maildir:User quota
   quota_exceeded_message = User %u has exhausted allowed storage space.
   quota_rule = Junk:ignore
   quota_rule2 = Trash:storage=+100M
   quota_warning = storage=90%% quota-warning 90 %u %d
   quota_warning2 = storage=80%% quota-warning 80 %u %d
   sieve = file:~/sieve;active=~/.dovecot.sieve
   sieve_before = /var/vmail/sieve/global/spam-global.sieve
   sieve_global = /var/vmail/sieve/global/
   sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.debug
   sieve_pipe_bin_dir = /var/vmail/sieve/global
   sieve_plugins = sieve_imapsieve sieve_extprograms
}
protocols = " imap lmtp sieve pop3"
service auth {
   inet_listener {
     port = 25252
   }
}
service imap-login {
   inet_listener imap {
     haproxy = yes
   }
   inet_listener imaps {
     haproxy = yes
     ssl = yes
   }
}
service lmtp {
   executable = lmtp -L
   inet_listener lmtp {
     address = 0.0.0.0
     port = 24
   }
}
service managesieve-login {
   inet_listener sieve {
     port = 4190
   }
}
service pop3-login {
   inet_listener pop3 {
     haproxy = yes
   }
   inet_listener pop3s {
     haproxy = yes
   }
}
ssl = required
ssl_cert = </etc/dovecot/certs/tls.crt
ssl_client_ca_dir = /etc/ssl/certs
ssl_key = # hidden, use -P to show it
ssl_prefer_server_ciphers = yes
userdb {
   args = /etc/dovecot/dovecot-sql.conf.ext
   driver = sql
}
protocol lmtp {
   info_log_path = /dev/stdout
   log_path = /dev/stdout
   mail_plugins = quota mail_crypt sieve
   postmaster_address = <hidden>
}
protocol imap {
   mail_plugins = quota mail_crypt quota imap_quota imap_sieve
}
-- Dovecot Configurations Ends --

-- Password Query --
password_query = \
     SELECT username, domain, password, \
     '%{sha256:password}' AS userdb_mail_crypt_global_private_key_password \
     FROM mailbox \
     WHERE username='%u';
-- Password Query Ends--

-- User Query --
user_query = SELECT CONCAT('*:bytes=', 1024) as quota_rule, \
     private_key AS mail_crypt_global_private_key, \
     public_key AS mail_crypt_global_public_key, \
     mail_crypt_save_version AS mail_crypt_save_version \
     FROM mailbox \
     WHERE username='%u';
-- User Query Ends --

-- Debug Logs --
--- Load Inbox ---
imap-login: Info: Login: user=<someone at example.com>, method=PLAIN, 
rip=192.168.49.1, lip=192.168.49.2, mpid=241, TLS, 
session=<oaoI9sLxVKXAqDEB>
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: Loading modules 
from directory: /usr/lib/dovecot/modules
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: Module loaded: 
/usr/lib/dovecot/modules/lib10_mail_crypt_plugin.so
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: Module loaded: 
/usr/lib/dovecot/modules/lib10_quota_plugin.so
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: Module loaded: 
/usr/lib/dovecot/modules/lib11_imap_quota_plugin.so
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: Module loaded: 
/usr/lib/dovecot/modules/lib95_imap_sieve_plugin.so
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: Added userdb 
setting: plugin/mail_crypt_global_private_key=LS0tLS1CRUd.....LS0tLS0K
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: Added userdb 
setting: plugin/mail_crypt_global_private_key_password=<hidden>
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: Added userdb 
setting: plugin/mail_crypt_global_public_key=LS0tLS1CRUd.....LS0tCg==
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: Added userdb 
setting: plugin/mail_crypt_save_version=2
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: Added userdb 
setting: plugin/quota_rule=*:bytes=1024000000
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: Effective 
uid=1000, gid=1000, home=/var/vmail/mailboxes/example.com/someone
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: 
mail_crypt_plugin: mail_crypt_curve setting missing - generating EC keys 
disabled
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: Quota root: 
name=User quota backend=maildir args=
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: Quota rule: 
root=User quota mailbox=* bytes=1024000000 messages=0
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: Quota rule: 
root=User quota mailbox=Trash bytes=+104857600 messages=0
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: Quota warning: 
bytes=921600000 (90%) messages=0 reverse=no command=quota-warning 90 
someone at example.com example.com
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: Quota warning: 
bytes=819200000 (80%) messages=0 reverse=no command=quota-warning 80 
someone at example.com example.com
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: Quota grace: 
root=User quota bytes=102400000 (10%)
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: 
open(/proc/self/io) failed: Permission denied
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: Namespace 
inbox: type=private, prefix=, sep=, inbox=yes, hidden=no, list=yes, 
subscriptions=yes location=maildir:~/:LAYOUT=fs
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: fs: 
root=/var/vmail/mailboxes/example.com/someone, index=, indexpvt=, 
control=, inbox=/var/vmail/mailboxes/example.com/someone, alt=
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: quota: 
quota_over_flag check: quota_over_script unset - skipping
imap(someone at example.com)<241><oaoI9sLxVKXAqDEB>: Debug: Mailbox INBOX: 
Mailbox opened
--- Load Inbox Ends ---
--- Lmtp ---
lmtp(248): Info: Connect from 172.17.0.1
lmtp(someone at example.com)<248><e2dcD6TuumP4AAAALzF/Qw>: Debug: 
auth-master: userdb lookup(someone at example.com): Started userdb lookup
lmtp(someone at example.com)<248><e2dcD6TuumP4AAAALzF/Qw>: Debug: 
auth-master: conn unix:/var/run/dovecot/auth-userdb: Connecting
lmtp(someone at example.com)<248><e2dcD6TuumP4AAAALzF/Qw>: Debug: 
auth-master: conn unix:/var/run/dovecot/auth-userdb (pid=143,uid=0): 
Client connected (fd=18)
imap(someone at example.com)<247><WlggG8PxEOvAqDEB>: Debug: Mailbox Sent: 
Purging (new file_seq=1673195172): creating cache
imap(someone at example.com)<247><WlggG8PxEOvAqDEB>: Debug: Mailbox Sent: 
Purging finished, file_seq changed 0 -> 1673195172, size=0 -> 388, max_uid=0
lmtp(someone at example.com)<248><e2dcD6TuumP4AAAALzF/Qw>: Debug: 
auth-master: userdb lookup(someone at example.com): auth USER input: 
someone at example.com quota_rule=*:bytes=1024000000 
mail_crypt_global_private_key=LS0tLS1CRUd.....LS0tLS0K 
mail_crypt_global_public_key=LS0tLS1CRUd.....LS0tCg== 
mail_crypt_save_version=2
lmtp(someone at example.com)<248><e2dcD6TuumP4AAAALzF/Qw>: Debug: 
auth-master: userdb lookup(someone at example.com): Finished userdb lookup 
(username=someone at example.com quota_rule=*:bytes=1024000000 
mail_crypt_global_private_key=LS0tLS1CRUd.....LS0tLS0K 
mail_crypt_global_public_key=LS0tLS1CRUd.....LS0tCg== 
mail_crypt_save_version=2)
lmtp(someone at example.com)<248><e2dcD6TuumP4AAAALzF/Qw>: Debug: 
lmtp-server: conn 172.17.0.1:6376 [1]: rcpt someone at example.com: Added 
userdb setting: 
plugin/mail_crypt_global_private_key=LS0tLS1CRUd.....LS0tLS0K
imap(someone at example.com)<247><WlggG8PxEOvAqDEB>: Debug: duplicate db: 
Initialize
lmtp(someone at example.com)<248><e2dcD6TuumP4AAAALzF/Qw>: Debug: 
lmtp-server: conn 172.17.0.1:6376 [1]: rcpt someone at example.com: Added 
userdb setting: plugin/mail_crypt_global_public_key=LS0tLS1CRUd.....LS0tCg==
imap(someone at example.com)<247><WlggG8PxEOvAqDEB>: Debug: sieve: 
Pigeonhole version 0.5.19 (4eae2f79) initializing
lmtp(someone at example.com)<248><e2dcD6TuumP4AAAALzF/Qw>: Debug: 
lmtp-server: conn 172.17.0.1:6376 [1]: rcpt someone at example.com: Added 
userdb setting: plugin/mail_crypt_save_version=2
lmtp(someone at example.com)<248><e2dcD6TuumP4AAAALzF/Qw>: Debug: 
lmtp-server: conn 172.17.0.1:6376 [1]: rcpt someone at example.com: Added 
userdb setting: plugin/quota_rule=*:bytes=1024000000
lmtp(someone at example.com)<248><e2dcD6TuumP4AAAALzF/Qw>: Debug: 
lmtp-server: conn 172.17.0.1:6376 [1]: rcpt someone at example.com: 
Effective uid=1000, gid=1000, home=/var/vmail/mailboxes/example.com/someone
lmtp(someone at example.com)<248><e2dcD6TuumP4AAAALzF/Qw>: Debug: 
lmtp-server: conn 172.17.0.1:6376 [1]: rcpt someone at example.com: 
mail_crypt_plugin: mail_crypt_curve setting missing - generating EC keys 
disabled
lmtp(someone at example.com)<248><e2dcD6TuumP4AAAALzF/Qw>: Debug: 
lmtp-server: conn 172.17.0.1:6376 [1]: rcpt someone at example.com: Quota 
root: name=User quota backend=maildir args=
lmtp(someone at example.com)<248><e2dcD6TuumP4AAAALzF/Qw>: Debug: 
lmtp-server: conn 172.17.0.1:6376 [1]: rcpt someone at example.com: Quota 
rule: root=User quota mailbox=* bytes=1024000000 messages=0
lmtp(someone at example.com)<248><e2dcD6TuumP4AAAALzF/Qw>: Debug: 
lmtp-server: conn 172.17.0.1:6376 [1]: rcpt someone at example.com: Quota 
rule: root=User quota mailbox=Trash bytes=+104857600 messages=0
lmtp(someone at example.com)<248><e2dcD6TuumP4AAAALzF/Qw>: Debug: 
lmtp-server: conn 172.17.0.1:6376 [1]: rcpt someone at example.com: Quota 
warning: bytes=921600000 (90%) messages=0 reverse=no 
command=quota-warning 90 someone at example.com example.com
lmtp(someone at example.com)<248><e2dcD6TuumP4AAAALzF/Qw>: Debug: 
lmtp-server: conn 172.17.0.1:6376 [1]: rcpt someone at example.com: Quota 
warning: bytes=819200000 (80%) messages=0 reverse=no 
command=quota-warning 80 someone at example.com example.com
lmtp(someone at example.com)<248><e2dcD6TuumP4AAAALzF/Qw>: Debug: 
lmtp-server: conn 172.17.0.1:6376 [1]: rcpt someone at example.com: Quota 
grace: root=User quota bytes=102400000 (10%)
lmtp(248): Error: lmtp-server: conn 172.17.0.1:6376 [1]: rcpt 
someone at example.com: Failed to initialize user: mail_crypt_plugin: 
mail_crypt_global_private_key: mail_crypt_global_private_key_password 
unset, no password to decrypt the key
lmtp(248): Info: Disconnect from 172.17.0.1: Logged out (state=READY)
--- Lmtp Ends ---
-- Debug Logs Ends --

Thanks
Baljeet Bhinder
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://dovecot.org/pipermail/dovecot/attachments/20230108/181ad028/attachment-0001.htm>


More information about the dovecot mailing list