Best mail encryption solution for per-user

Aki Tuomi aki.tuomi at dovecot.fi
Sun May 20 15:43:53 EEST 2018


> On 19 May 2018 at 16:40 mail at sjemm.net wrote:
> 
> 
> May 18, 2018 10:01 PM, "Aki Tuomi" <aki.tuomi at dovecot.fi> wrote:
> >> On 18 May 2018 at 21:44 mail at sjemm.net wrote:
> >> 
> >> May 18, 2018 4:43 PM, "Aki Tuomi" <aki.tuomi at dovecot.fi> wrote:
> >> On 18 May 2018 at 17:38 mail at sjemm.net wrote:
> >> 
> >> May 18, 2018 4:05 PM, "Aki Tuomi" <aki.tuomi at dovecot.fi> wrote:
> >> On 18 May 2018 at 16:43 mail at sjemm.net wrote:
> >> 
> >> Hi Tai74 and Aki,
> >> I followed your conversation with interest on how to setup per user encryption in dovecot.
> >> I have setup my dovecot with the following in a conf file:
> >> 
> >> ==============
> >> 
> >> mail_attribute_dict = file:%h/Maildir/dovecot-attributes
> >> mail_plugins = $mail_plugins mail_crypt
> >> plugin {
> >> 
> >> mail_crypt_curve = secp521r1
> >> 
> >> mail_crypt_save_version = 2
> >> 
> >> }
> >> 
> >> ==============
> >> 
> >> This works nice, all emails are being encrypted and every user/folder has keys.
> >> But as I understood from your conversation these keys are not protected. And I want them to be
> >> protected by the users password used by imap.
> >> 
> >> Those passwords are stored in a mysql DB file. ( I used a guide from workaround [dot] org to set up
> >> the DB and postfix/dovecot)
> >> 
> >> but how would i set it so, that the users password from the DB is used to encrypt the keys?
> >> 
> >> should i use mail_crypt_private_password = ?
> >> how do i point it to the mysql db then?
> >> im unsure about this
> >> 
> >> Do you have any hints on this?
> >> 
> >> Kind regards,
> >> Zjemm
> >> 
> >> The passwords in your MySQL database are, hopefully, not in plaintext. If you want to secure your
> >> user's keys using user's login password, you must have a TOOL that manages this.
> >> 
> >> You can use mail_crypt_private_password = %w in (mysql) passdb fields to provide the user's login
> >> password as private password. You might want to run it thru some hash, so %{sha1:password} might be
> >> a good option.
> >> 
> >> You can change the key password using 'doveadm mailbox cryptokey', this needs to be done every time
> >> user changes his password.
> >> 
> >> Also note that if you go down this road, and the user forgets his password, you will not be able to
> >> recover the emails without backup copy of the private key.
> >> 
> >> Aki
> >> 
> >> Hi Aki
> >> 
> >> I used the following command:
> >> dovecot pw -s SHA256-CRYPT
> >> 
> >> the output on the chosen password looks like: {SHA256-CRYPT}$5$Rokc06a7In4SF3bO$OQpGQWqg........
> >> 
> >> This output is used to store in the password fields in the database. So no plain text passwords no
> >> :)
> >> 
> >> You can use mail_crypt_private_password = %w in (mysql) passdb fields to provide the user's login
> >> password as private password.
> >> 
> >> can you explain this a bit more for me?
> >> 
> >> for now i have in the 10-auth.conf file the following:
> >> ==============
> >> passdb {
> >> driver = sql
> >> 
> >> # Path for SQL configuration file, see example-config/dovecot-sql.conf.ext
> >> args = /etc/dovecot/dovecot-sql.conf.ext
> >> }
> >> 
> >> and:
> >> 
> >> userdb {
> >> driver = static
> >> args = uid=vmail gid=vmail home=/var/vmail/%d/%n
> >> }
> >> ==============
> >> 
> >> then i have in dovecot-sql.conf.ext
> >> ==============
> >> driver = mysql
> >> connect = host=x.x.x.x dbname=mailserver user=mailuser password=mailpasswordexample
> >> default_pass_scheme = SHA256-CRYPT
> >> password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';
> >> ==============
> >> Where do i need to set : mail_crypt_private_password = %w ?
> >> 
> >> password as private password. You might want to run it thru some hash, so %{sha1:password} might be
> >> a good option.
> >> 
> >> the passwords are allready hashed in the DB using: dovecot pw -s SHA256-CRYPT to genereate the has.
> >> so this step isnt nesesary anymore am i right?
> >> 
> >> Thank you for your quick response, very helpfull
> >> 
> >> Zjemm
> >> 
> >> You misunderstood a bit. The idea is to use the *plaintext* password as the password for the
> >> private key. Otherwise anyone could just decrypt it by looking at your database where the hashed
> >> password is..
> >> 
> >> So:
> >> 
> >> password_query = SELECT email as user, password, '%w' AS userdb_mail_crypt_private_password FROM
> >> virtual_users WHERE email='%u'
> >> 
> >> Aki
> >> 
> >> Hi Aki,
> >> 
> >> Thank you very much for your help, i realy appreciate that.
> >> 
> >> Ok so if i understand it correctly i'll have to use:
> >> 
> >> password_query = SELECT email as user, password, '%w' AS userdb_mail_crypt_private_password FROM
> >> virtual_users WHERE email='%u'
> >> 
> >> in my dovecot-sql.conf.ext file
> >> 
> >> This query selects the user, the password, and %w
> >> 
> >> if i run a little query myself:
> >> MariaDB [mailserver]> SELECT email as user, password, '%w' AS userdb_mail_crypt_private_password
> >> FROM virtual_users;
> >> +------------------+----------------------------------+------------------------------------+
> >> | user | password | userdb_mail_crypt_private_password |
> >> +------------------+----------------------------------+------------------------------------+
> >> | john at example.org | {SHA256-CRYPT}$5$M/GWzmtjsLroRWI | %w |
> >> +------------------+----------------------------------+------------------------------------+
> >> 
> >> %w is a dovecot variable, and stands for the plaintext password, but the password is not stored as
> >> plaintext in the DB, %w get filled with the actual plaintext password by dovecot upon the user that
> >> is typing in the password when authenticating.
> >> 
> >> is this correct?
> > 
> > yes.
> > 
> >> so then i have the username the hashed password en the plaintext password as a result of the query.
> > 
> > yes
> > 
> >> now userdb_mail_crypt_private_password = the plaintext password
> >> do i need to reference it somewhere? or is userdb_mail_crypt_private_password autmatically used by
> >> the dovecot mail_crypt plugin to encrypt the keys? or should it be mail_crypt_private_password?
> > 
> > It gets injected into the mail process as 'mail_crypt_private_password', as if it was set in plugin
> > {} section.
> > 
> >> if i have this setup working i'm going to write a blog post on this topic to share this knowledge
> >> 
> >> Thanks again and have a great weekend.
> >> 
> >> Zjemm
> > 
> > Aki
> 
> Hi Aki,
> 
> Cool i'm testing it right now.
> I have set up a new mailserver (life is great with lxc containers :) )
> 
> postfix and dovecot are working like normal
> 
> next i enable mail_crypt
> 
> i did create a file: /etc/dovecot/conf.d/10-mailcrypt.conf
> ==========================
> mail_attribute_dict = file:%h/Maildir/dovecot-attributes
> 
> mail_plugins = $mail_plugins mail_crypt
> 
> plugin {
>     mail_crypt_curve = secp521r1
>     mail_crypt_save_version = 2
> }
> ==========================
> 
> and then i changed the file: /etc/dovecot/dovecot-sql.conf.ext
> 
> so the query is now the new query:
> password_query = SELECT email as user, password, '%w' AS userdb_mail_crypt_private_password FROM virtual_users WHERE email='%u';
> 
> then i restarted dovecot and postfix and send a test email to the one and only testuser that is in there.
> 
> when i open the mailbox with the tool mutt, i can see the new email, and when openening the email the mutt client drops the connection.
> 
> in the log i can see:
> 
> May 19 13:34:48 mailserver1.example.local dovecot[600]: imap-login: Login: user=<john at example.org>, method=PLAIN, rip=::1, lip=::1, mpid=713, TLS, session=<E3PnIY9sNM4AAAAAAAAAAAAAAAAAAAAB>
> May 19 13:34:49 mailserver1.example.local dovecot[600]: imap(john at example.org): Error: read() failed: read(/var/vmail/example.org/john/Maildir/cur/1526736378.M161472P641.mailserver1.example.local,S=559,W=571:2,) failed: Private key not available: Cannot decrypt key bfc5bb25b1bf64290eea6dc14b516c6a0a25b64551b6e4f0f8677ba7274887cb: error:03070068:bignum routines:BN_mpi2bn:encoding error (FETCH BODY[] for mailbox INBOX UID 8)
> 
> 
> i think i missed a step, but witch one?
> 
> the userpassword hasnt been changed (that would be the next step in the testing process)
> 
> should i've use doveadm first to encrypt the key with that userpassword? i thought it would do that on the fly, because the initial keys where only just created when enabling the mail_crypt plugin
> 
> please let me know your thougts
> Zjemm

I noticed you replied directly to me, and not to the list, too... fixed that for you. 

mail_crypt_private_password is used when key is created, but if you have created it before using password, you'll need to encrypt it before turning the setting on.

Aki


More information about the dovecot mailing list