Categories
Linux Server Administration

Dovecot and Argon2 doesn’t work? This may be why.

Sorry, title is too long. Again. Nevertheless, ignore this and continue on…

I run my own mailserver. I love doing this, don’t ask me why. Anyway, I was recently migrating a few password hashes to Argon2. I confirmed manually that everything was working, I checked that Dovecot was able to generate and verify Argon2 hashes, that my backend storage was doing everything correctly and so on.

Then I changed a bunch of passwords to migrate them over to Argon2 (I was previously using bcrypt, but I started to like Argon2 more because of it’s resistance to many optimization attacks). Just after I had those new Argon2 hashes in the database, I could no longer login using these users. I think it worked like once and then never again.

Well, damn. I spend hours researching what may be wrong. Dovecot was simply spitting out it’s usual “dovecot: auth-worker(pid): Password mismatch” message. Nothing I could get any information from. To summarize what I found in the ‘net: Nothing of use.

So well, why am I writing this post then? Well because I finally figured out what’s wrong. The Dovecot documentation states this:

ARGON2 can require quite a hefty amount of virtual memory, so we recommend that you set service auth { vsz_limit = 2G } at least, or more.

https://doc.dovecot.org/configuration_manual/authentication/password_schemes/

Well, I obviously already did that – I do read the documentation from time to time, at least when I’m trying to solve a critical problem. But you know what’s strange? The docs also state that the actual login isn’t handled by the auth service, instead it’s usually done by a service called auth-worker 1[at least if you’re using a database like I do] (that’s also the thing that’s producing the “Password mismatch” log messages).

To make a long story short, what happened was that Dovecot stopped the auth-worker process as it was trying to hash the Argon2 password. This simply triggered a generic “Password mismatch” message instead of something useful like “out of memory”, so yeah…

Lesson Learned: If you’re using Argon2, increase the memory limit of auth-worker, not the auth service like the docs tell you to.

This was the solution. I simply added a few config lines to Dovecot:

service auth-worker {
   # Needed for argon2. THIS IS THE IMPORTANT SETTING!
   vsz_limit = 0 # Means unlimited, other values like 2G or more also also valid
   # Other custom settings for your auth-workers here...
}

And login was working again. I never found anyone mentioning that you need to set this value for auth-worker instead of auth, which is why I wrote this little post.

  1. This varies from passdb and/or userdb type. Some types may use the auth service directly, others use an auth worker. Check what your setup is using before taking my words for granted.

6 replies on “Dovecot and Argon2 doesn’t work? This may be why.”

Hi,
Well done for figuring this out.
Thanks for sharing. Great stuff.

On what linux are you using Argon with Dovecote?

As I have been trying to find a way to enable Argon2 for Dovecote on Ubuntu 18.04 somehow, I can’t find any info about it online.

So I am really curious to know how I get there to apply the fix you figured out above, as I haven’t got Argon2 option, but what is even worse, even just “BLF-CRYPT” isn’t listed as one of the available pass. schemes either, by doing “doveadm pw -l”.
PBKDF2 seems to be the most secure for passwords, from the list of available schemes:
MD5 MD5-CRYPT SHA SHA1 SHA256 SHA512 SMD5 SSHA SSHA256 SSHA512 PLAIN CLEAR CLEARTEXT PLAIN-TRUNC CRAM-MD5 SCRAM-SHA-1 HMAC-MD5 DIGEST-MD5 PLAIN-MD4 PLAIN-MD5 LDAP-MD5 LANMAN NTLM OTP SKEY RPA PBKDF2 CRYPT SHA256-CRYPT SHA512-CRYPT

Thanks again for the great post,
Andras

The entire system is currently running on Debian 10 (Buster). I’m running the latest Dovecot version via the Dovecot repository @ https://repo.dovecot.org/

The docs say that argon2 is available “if libsodium is new enough” (+ Dovecot itself is recent). Debian currently ships libsodium23-1.0.17-1 which apparently satifies this requirement.

The same applies for Blowfish/Bcrypt, which is probably why you do not have that either. I believe your libsodium + dovecot either does both, or none.

My doveadm pw -l shows:

SHA1 SSHA512 SCRAM-SHA-256 BLF-CRYPT PLAIN HMAC-MD5 OTP SHA512 SHA DES-CRYPT CRYPT SSHA MD5-CRYPT PLAIN-MD4 PLAIN-MD5 SCRAM-SHA-1 SHA512-CRYPT CLEAR CLEARTEXT ARGON2I ARGON2ID SSHA256 MD5 PBKDF2 SHA256 CRAM-MD5 PLAIN-TRUNC SHA256-CRYPT SMD5 DIGEST-MD5 LDAP-MD5

You could try installing the Dovecot version from their repository (see my link above) on a test machine and see if that gives you more features. It may just be the old Dovecot shipped with your Ubuntu that’s the problem. Otherwise you could have a look on how to compile/get a more recent libsodium.

This involves first setting the new hash algorithm (Argon2ID) as the default for new/changed passwords in whatever app that generates your hashes & writes them to your database.

Old password hashes (in the old format/algorithm) will usually still work, because the schema *should* be stored together with the hash. For example an Argon2ID password generated with dovecot pw looks like this:

{ARGON2ID}$argon2id$v=19$m=65536,t=3,p=1$aPGIgDo9SjjAwk6JnBl42Q$Gax8bUQUBI0Dn2m/8pzHDPMkrQl/E8PVH52TbFvov1w

While a SHA512 hash looks like this:

{SHA512}3a81oZNherrMQXNJriBBMRLm+k6JqX6iCp7u5ktV05ohkpkqJ0/BqDa6PCOj/uu9RU1EI2Q86A4qmslPpUyknw==

So upon verifying the stored hash with a user-supplied password on login, dovecot will automatically detect the used algorithm based on the prefix – independent of what algorithm is currently set as the default. Therefore you can have a mix of different password hash formats in your database.

In order to migrate a hash to the new format, you will need to ask the user to change their password. We (usually) can’t reverse the hash (that’s the whole point of hashing passwords), so that’s the only option. Upon changing their password, your system should hash the new password using the new algorithm and write it to your database.

Thanks for taking the time to answer.

In my case stored password begin with $6$ which is indeed SHA512, so will import actual records to the new server and give it a try.

Thanks again 🙂

Thank you. Could not get my head wrapped around this issue and this solved the log-in issue I was facing.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.