postfixadmin / postfixadmin

PostfixAdmin - web based virtual user administration interface for Postfix mail servers
https://postfixadmin.github.io/postfixadmin
Other
1.05k stars 287 forks source link

Postfixadmin and Dovecot php_crypt hash confusion? #736

Closed frzqwerty closed 1 year ago

frzqwerty commented 1 year ago

Greetings.

I'm trying to use php_crypt support for my Dovecot mail server setup (due to doveadm permission issues on a very strict OS: OpenBSD, and so on)

In my Postfixadmin config file, I have:

$CONF['encrypt'] = 'php_crypt:SHA256::{SHA256}';

And in dovecot configuration: default_pass_scheme = SHA256, I created a test e-mail user on PostfixAdmin, couldn't login to my e-mail account.

I wondered why is that, and checked the sql structure, the password hash generated by Postfixadmin was;

{SHA256}$5$ONzsDiUoLJtjHJpG$32tZcoCFI/1taXfdGpWR/l2tenUgpBxgyTFz68LumTB

Seemed a bit different to me, doveadm pw -s sha256 generated the same password like the following format; {SHA256}7NcYcNGWMxapfjrDQIyYNa2M8PPBvHA1J8MCZVNPda4=

I then, manually replaced the password created by Postfixadmin in sql structure, with the one I created using doveadm in terminal, and I could login successfully.

I wonder where's the mistake I make? Some base64 encoding problems maybe? How can I set Postfixadmin to generate SHA256 passwords in format like; {SHA256}7NcYcNGWMxapfjrDQIyYNa2M8PPBvHA1J8MCZVNPda4=?

Many thanks, Regards.

DavidGoodwin commented 1 year ago

try php_crypt:SHA256-CRYPT.B64 ? or dovecot:SHA256-CRYPT.B64 ?

(Sorry I don't have time right now to test if either of those work, one might not ...)

frzqwerty commented 1 year ago

Hi David,

Thank you very much for your reply.

Tried: $CONF['encrypt'] = 'php_crypt:SHA256-CRYPT.B64';

Got this error message on my Postfixadmin homepage;

Fatal error: Uncaught Exception: unknown hash type: 'SHA256-CRYPT.B64' in /pfixadm/functions.inc.php:1230 Stack trace: #0 /pfixadm/functions.inc.php(1144): _php_crypt_generate_crypt_salt() #1 /pfixadm/functions.inc.php(1285): _pacrypt_php_crypt() #2 /pfixadm/model/PFAHandler.php(563): pacrypt() #3 /pfixadm/public/edit.php(169): PFAHandler->save() #4 {main} thrown in /pfixadm/functions.inc.php on line 1230

Will try the other one, now.

frzqwerty commented 1 year ago

And using dovecot:SHA256-CRYPT.B64 created a worse result, I couldn't log into Postfixadmin, tried to re-Setup, and the error messages below are from the Setup page, think it cannot reach to doveadm binary (actually that's why I try to set php_crypt)

dovecot:SHA256-CRYPT.B64:

Password Hashing - attempted to use configured encrypt backend (dovecot:SHA256-CRYPT.B64) triggered an error: /usr/local/bin/doveadm pw -s SHA256 failed, see error log for details. You will have problems logging into PostfixAdmin. Check out our Dovecot documentation at: https://github.com/postfixadmin/postfixadmin/blob/master/DOCUMENTS/DOVECOT.txt, specifically around '3. Permissions'.

Notice: fwrite(): Write of 10 bytes failed with errno=32 Broken pipe in /pfixadm/functions.inc.php on line 1056

Fatal error: Uncaught Exception: /usr/local/bin/doveadm pw -s SHA256 failed, see error log for details in /pfixadm/functions.inc.php:1066 Stack trace: #0 /pfixadm/functions.inc.php(1281): _pacrypt_dovecot() #1 /pfixadm/model/PFAHandler.php(563): pacrypt() #2 /pfixadm/public/setup.php(543): PFAHandler->save() #3 /pfixadm/public/setup.php(389): create_admin() #4 {main} thrown in /pfixadm/functions.inc.php on line 1066

frzqwerty commented 1 year ago

And by the way, the documentation page DOCUMENTS/HASHING.md states that; Dovecot pass scheme: SHA256 - PostfixAdmin $CONF['encrypt'] setting: SHA256.

And I tried this one, however PFA reported an error;

Fatal error: Uncaught Exception: unknown/invalid $CONF["encrypt"] setting: SHA256 in /pfixadm/functions.inc.php:1288 Stack trace: #0 /pfixadm/model/PFAHandler.php(563): pacrypt() #1 /pfixadm/public/edit.php(169): PFAHandler->save() #2 {main} thrown in /pfixadm/functions.inc.php on line 1288

The exact line is: $CONF['encrypt'] = 'SHA256';

veitw commented 1 year ago

try php_crypt:SHA256-CRYPT.B64 ? or dovecot:SHA256-CRYPT.B64 ?

(Sorry I don't have time right now to test if either of those work, one might not ...)

@DavidGoodwin I think the main issue here is that PFA's php_crypt SHA256 scheme does not generate SHA256 but SHA256-CRYPT, so it is simply mislabeled here.

But renaming might break running configurations.

Also I am not sure whether something named php_crypt should actually generate anything that is not a crypt() compatible hash at all (such as the requested unsalted single-round SHA256 hash here). So maybe it would better to have a new thing called e.g. php_hash to put non-crypt() schemes like SHA256 into.

frzqwerty commented 1 year ago

Since midday, since almost 7 hours I've tried almost everything, failed..

Then @veitw helped me to move from SHA256 stuff to Blowfish/BLF-CRYPT, his suggestion has worked like a charm! (Compatible for all together; PFA + Dovecot + Roundcube's Password-change plugin)

Thank you @veitw

DavidGoodwin commented 1 year ago

@veitw yes, the legacy mistakes we have to support ....

DavidGoodwin commented 1 year ago

(what you need is going to change from version 3.3 to 'master' ..... as 'master' includes a few changes to try and remove the dovecot dependency problem ( #379 )).

If you think what's in DOCUMENTS/HASHING.md can be improved, please make suggestions (ideally as a pull request, but I can cope with someone saying "Add this ..... remove that ... change this ...").

thanks

frzqwerty commented 1 year ago

And by the way, I have PFA 3.3.13 however the footer says 3.3.11.

Just in case..

DavidGoodwin commented 1 year ago

yes, the version thing has been mentioned a few times .... ;-) (Sorry! I should really just automate everything through github actions)

frzqwerty commented 1 year ago

(what you need is going to change from version 3.3 to 'master' ..... as 'master' includes a few changes to try and remove the dovecot dependency problem ( #379 )).

Thank you. Is there any stable release coming soon, just to wait for it?

Many thanks,

Best.

DavidGoodwin commented 1 year ago

@frzqwerty I don't know .... I suppose one must be due eventually ;-)

frzqwerty commented 1 year ago

I see.. We'll just wait then :) Thank you!

A quick question, when I set my domain "Active: NO", like here: https://i.ibb.co/ccR1fJz/ben.png

I still can login into my e-mail accounts. (Tried with Roundcube Webmail)

Any idea on this?

DavidGoodwin commented 1 year ago

Er, basically you'd need to modify the SQL query you're using in dovecot and/or postfix.

Dovecot's user_query could go to something a bit like :

SELECT CONCAT('/var/mail/vmail/', m.maildir) AS home, 1001 AS uid, 1001 AS gid, CONCAT('*:bytes=', m.quota) AS quota_rule 
FROM mailbox m 
INNER JOIN domain d ON  m.domain = d.domain
WHERE m.username = '%u' AND m.active='1' AND d.active = '1' 

which would probably do what you need.

The main problem is probably going to be that dovecot isn't going to helpfully communicate back to the end user WHY their mailbox isn't accessible - it's just going to say something like "invalid username".

frzqwerty commented 1 year ago

Thanks for your reply, David.

I think you mean about my dovecot/dovecot-sql.conf.ext file, which is;

password_query = SELECT password FROM mailbox WHERE username = '%Lu' AND active = '1' user_query = SELECT CONCAT('/var/vmailboxes/', maildir) as home, 111 AS uid, 111 AS gid FROM mailbox WHERE username = '%Lu' AND active = '1'

How could the new query be, in my case? Sorry but I'm confused a bit and didn't want to execute sets of SQL command that I don't really get..

My e-mail directory structure is as follows;

/var/vmailboxes/mywebsite.com/info@mywebsite.com/

"$CONF['domain_path'] = 'YES';" and "$CONF['domain_in_mailbox'] = 'YES';" are set.

Thanks a lot!

DavidGoodwin commented 1 year ago

Yes, I'd think something like this would work for dovecot-sql.conf

user_query = \
  SELECT CONCAT('/var/mailboxes/', m.maildir) AS home, 111 AS uid, 111 AS gid, CONCAT('*:bytes=', m.quota) AS quota_rule \
   FROM mailbox m \
   INNER JOIN domain d ON  m.domain = d.domain \
   WHERE m.username = '%u' AND m.active='1' AND d.active = '1' 

(is %Lu a lowercase version of %u ?)

I'm assuming dovecot does a user lookup before trying to do the password_query, but i could be wrong, in which case perhaps you actually need to change password_query to have the join on domain instead

password_query = SELECT m.password as password FROM mailbox m \
    INNER JOIN domain d ON m.domain = d.domain \
    WHERE m.username = '%Lu' AND m.active = '1' and d.active = '1' 
frzqwerty commented 1 year ago

Thank you very much, David, it worked!

And I tried without changing anything on password_query, as above. So it seems it works as it is.

My current setting is:

password_query = SELECT password FROM mailbox WHERE username = '%Lu' AND active = '1'

And yes, %Lu lowercases the capital letters [you know, sometimes people write LIKE@THIS.COM on Roundcube login :)]

So, I assume I shouldn't touch the password_query if it works? Or you might have a better suggestion on it?

Do you think the SQL query for the "password_query" is good enough?

Best wishes!

DavidGoodwin commented 1 year ago

I can't tell which query dovecot calls first - I suspect either will do/suffice.

frzqwerty commented 1 year ago

Many thanks, noted it down.

Lastly, it seems Postfixadmin's main admin login page has an issue that Chrome reports it as error;

"Incorrect use of

Please see the screenshot for deeper details: https://ibb.co/jfcwCbv

Are you aware of that? Just wanted to inform it here.

DavidGoodwin commented 1 year ago

hopefully fixed ... and no, i wasn't aware of it ...

frankofno commented 6 months ago

Since midday, since almost 7 hours I've tried almost everything, failed..

Then @veitw helped me to move from SHA256 stuff to Blowfish/BLF-CRYPT, his suggestion has worked like a charm! (Compatible for all together; PFA + Dovecot + Roundcube's Password-change plugin)

Thank you @veitw

I came across this issue and tried all kind of hashes. BLF-CRYPT SHA512-CRYPT etc. How can I use ARGON2ID instead of

php_crypt:SHA256

php_crypt:SHA512

If i use php_crypt:ARGON2ID

I get: "... unknown type of hash."

What do I need to change, to get ARGON2ID to work as hash algo?

DavidGoodwin commented 6 months ago

it may depend on what version of PostfixAdmin you're running, I think either :

veitw commented 6 months ago

@frankofno: What @DavidGoodwin meant is that you'll need to use master if you want ARGON2ID in plain-PHP mode, as the stable 3.3 branch supports ARGON2 crypt only via doveadm pw binary (dovecot: scheme).

frankofno commented 6 months ago

@frankofno: What @DavidGoodwin meant is that you'll need to use master if you want ARGON2ID in plain-PHP mode, as the stable 3.3 branch supports ARGON2 crypt only via doveadm pw binary (dovecot: scheme).

I've downloaded postfixadmin-3.3.13.tar.gz via wget. I will try master via git, although sudo doveadm pw -l gives me the following options:

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 SSHA256 MD5 PBKDF2 SHA256 CRAM-MD5 PLAIN-TRUNC SHA256-CRYPT SMD5 DIGEST-MD5 LDAP-MD5

So no ARGON2 listed here. Guess that's why ARGON2 is not possible?

My postfixadmin/config.local.php file has 2 lines with encryption:

Not working version:

$CONF['encrypt'] = 'php_crypt:BLF-CRYPT';
$CONF['dovecotpw'] = "/usr/bin/doveadm pw -r 12 -s BLF-CRYPT";

Working version with no errors (but SHA512 - bad choice for pw hashing):

$CONF['encrypt'] = 'php_crypt:SHA512;
$CONF['dovecotpw'] = "/usr/bin/doveadm pw -r 12 ";

Thanks again, for your help and hints :)

veitw commented 6 months ago

@frankofno: Without Argon2 support in dovecot, trying ARGON2ID scheme won't succeed. Also executing doveadm pw will fail in modern or hardened environments due to config file permissions, SELinux and/or hardened PHP. To circumvent file permission issues and stay with the current PFA version, you might use a simple script to replace doveadm pw for calculating Argon2ID hashes, but that still won't help if dovecot is missing Argon2 support.

Be aware that php_crypt:SHA512 does NOT mean simple single-round SHA512 hashing ("SHA512" scheme in dovecot), which is considered weak due to its proneness to rainbow table attacks and low calculation costs, but it refers to crypt()'s "$6$" scheme (which equals dovecot's SHA512-CRYPT scheme), that is not prone to rainbow table attacks due to individual salting, and has a variable calculation costs factor due to configurable iteration rounds (with 5000 rounds by default), which can even be chosen and stored individually per user within the hash and is fine to be updated automatically via post login script when increased calculation speeds indicate a requirement to raise the costs (same as Argon2 hashes allow). $6$ is also the default system passwd shadow hashing algorithm of choice at most current Linux distributions.

What $6$/SHA512-CRYPT still lacks in contrast to $argon2id$/ARGON2ID is configurable and noteworthy memory costs, which allows $6$ to be calculated at high rates on vector processors/shaders/FPGAs, but also reduces the risk of authentication DDoS attacks without additional countermeasures.