Some questions about mail_crypt setups

deano-dovecot at areyes.com deano-dovecot at areyes.com
Mon Feb 22 00:20:59 EET 2021


 

Some questions about mail_crypt setups 

I have global mail enecryption working nicely, and replication works
nicely between two systems. The main problem is that the private and
public keys are *right there* on the server in /etc/dovecot/private ...
Fine for a completely controlled system, but not so fine when on a
rented VPS etc. 

When are the keys read in by dovecot ? Are they ever read in again while
dovecot is running, or does it cache them in ram until dovecot is
restarted ? 

Would it be possible for dovecot to read the keys as output from a
script ? I'm thinking of a small script that would reach out to an
authentication service like Authy or Okta or similar. Admin gets an
alert on their phone, taps OK, UNLOCK and the two keys are returned to
the script, which then hands them back to dovecot and away it goes. 

The mail_crypt config normally contains 

> mail_crypt_global_private_key = </etc/dovecot/private/dovecot_crypt_privkey
> mail_crypt_global_public_key = </etc/dovecot/private/dovecot_crypt_pubkey

Perhaps add another variable like 

> mail_crypt_global_script = </etc/dovecot/private/dovecot_crypt_script

That script would run and feed the two keys back into dovecot (no matter
how it got to them). 

So I started looking into per-user/per-folder encryption to see how that
would work, and I have that setup nicely too. The config looks like this


> # /etc/dovecot/conf.d/99-mailcrypt.conf
> #--------------------------------------
> mail_attribute_dict = file:%h/Maildir/dovecot-attributes
> plugin {
> mail_crypt_require_encrypted_user_key = yes
> mail_crypt_save_version = 2
> mail_crypt_curve = secp521r1
> } 
> 
> # /etc/dovecot/dovecot-sql.conf.ext
> #----------------------------------
> # CREATE TABLE IF NOT EXISTS `users` (
> # `username` varchar(64) character set utf8 collate utf8_bin NOT NULL COMMENT 'localpart of email-address',
> # `domain` varchar(64) character set utf8 collate utf8_bin NOT NULL COMMENT 'domain-part of email-address',
> # `name` varchar(64) character set utf8 collate utf8_bin NOT NULL COMMENT 'Full name of user',
> # `password` varchar(128) character set utf8 collate utf8_bin NOT NULL COMMENT 'base64-encoded SHA512 hash of password',
> # PRIMARY KEY (`username`,`domain`)
> # ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='users'; 
> 
> driver = mysql
> connect = host=/var/run/mysqld/mysqld.sock dbname=emailers user=dovecot password=RandomPassword
> default_pass_scheme = SHA512-CRYPT 
> 
> password_query = SELECT username, password, '%w' AS userdb_mail_crypt_private_password, '/var/mail/%d/%n' AS userdb_home, 'vmail' AS userdb_uid, 'vmail' AS userdb_gid FROM users WHERE username = '%n' AND domain = '%d' 
> 
> # For LDA:
> user_query = SELECT '/var/mail/%d/%n' AS home, 'vmail' AS uid, 'vmail' AS gid FROM users WHERE username = '%n' AND domain = '%d' 
> 
> # For using doveadm -A:
> iterate_query = SELECT username, domain FROM users

Except that replication doesn't work due to the user password not being
available. Actually, indexing fails too for the same reason. 

> Feb 21 14:02:13 indexer-worker(testuser at example.com)<120846><l8W9BzWuMmAK2AEAqNyxgw:MyoJDDWuMmAO2AEAqNyxgw>: Error: Mailbox INBOX: UID=1: read() failed: read(/var/mail/example.com/testuser/Maildir/INBOX/new/1613934133.M132059P120842.dove1,S=2568,W=2624) failed: Private key not available: Cannot decrypt key f64e7c12a60b3df12ebf865a70bec57fedd3e9b4fd98df93205f1096db14fda7: Cannot decrypt key eca099273f525ca46b2f5640253770ad19e0578543244d8cd34bde183e996bd5: Password not available (read reason=fts indexing) 
> 
> Feb 21 14:02:13 indexer-worker(testuser at example.com)<120846><l8W9BzWuMmAK2AEAqNyxgw:MyoJDDWuMmAO2AEAqNyxgw>: Error: Failed to read mailbox INBOX mail UID=1 stream: Mailbox INBOX: UID=1: read() failed: read(/var/mail/example.com/testuser/Maildir/INBOX/new/1613934133.M132059P120842.dove1,S=2568,W=2624) failed: Private key not available: Cannot decrypt key f64e7c12a60b3df12ebf865a70bec57fedd3e9b4fd98df93205f1096db14fda7: Cannot decrypt key eca099273f525ca46b2f5640253770ad19e0578543244d8cd34bde183e996bd5: Password not available (read reason=fts indexing) 
> 
> Feb 21 14:02:13 indexer-worker(testuser at example.com)<120846><l8W9BzWuMmAK2AEAqNyxgw:MyoJDDWuMmAO2AEAqNyxgw>: Error: Mailbox INBOX: Mail search failed: Internal error occurred. Refer to server log for more information. [2021-02-21 14:02:13] 
> 
> Feb 21 14:02:13 indexer-worker(testuser at example.com)<120846><l8W9BzWuMmAK2AEAqNyxgw:MyoJDDWuMmAO2AEAqNyxgw>: Error: Mailbox INBOX: Transaction commit failed: FTS transaction commit failed: transaction context (attempted to index 1 messages (UIDs 1..1)) 
> 
> Feb 21 14:02:13 dsync-local(testuser at example.com)<TGxiDTWuMmAN2AEAqNyxgw>: Error: Mailbox INBOX: UID=1: read() failed: read(/var/mail/example.com/testuser/Maildir/INBOX/new/1613934133.M132059P120842.dove1,S=2568,W=2624) failed: Private key not available: Cannot decrypt key f64e7c12a60b3df12ebf865a70bec57fedd3e9b4fd98df93205f1096db14fda7: Cannot decrypt key eca099273f525ca46b2f5640253770ad19e0578543244d8cd34bde183e996bd5: Password not available (read reason=prefetch)

What are the options here for providing the decryption password or key ?
The user password is already stored in the mysql database as a
SHA512-CRYPT so we don't want to store it unencrypted ... I saw the
mail_crypt docs
(https://doc.dovecot.org/configuration_manual/mail_crypt_plugin/)
mention 

> mail_crypt_private_key - Private key to decrypt user's master key, can be base64 encoded

I'm assuming that can just be a key generated with 

> openssl ecparam -name secp521r1 -genkey | openssl pkey

but that leaves the situation almost the same as with a global key -
they key is local on the system, though a bit better in that it's not
just visible there as a simple file, it can be buried in the database.
One could retrieve it with 

> password_query = SELECT username, password, privkey AS userdb_mail_crypt_private_key, '/var/mail/%d/%n' AS userdb_home, 'vmail' AS userdb_uid, 'vmail' AS userdb_gid FROM users WHERE username = '%n' AND domain = '%d'

How are other people handling mail store encryption ? 

-- 
Dean Carpenter
deano is at areyes dot com
203 six oh four 6644
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://dovecot.org/pipermail/dovecot/attachments/20210221/27cc463b/attachment-0001.html>


More information about the dovecot mailing list