Назад | Перейти на главную страницу

Pure-ftpd с MySQL - Crypt () не выполняет вход с использованием хешированных паролей

Я использую pure-ftpd с mysql для авторизации пользователей.

Вот мой mysql.conf

MYSQLServer     localhost
MYSQLPort       3306
MYSQLSocket     /var/run/mysqld/mysqld.sock
MYSQLUser       user
MYSQLPassword   pwd
MYSQLDatabase   my_db
MYSQLCrypt      crypt()
MYSQLGetPW      SELECT password FROM ftp_users WHERE login="\L"
MYSQLGetUID     SELECT u_id FROM ftp_users WHERE login="\L"
MYSQLGetGID     SELECT g_id FROM ftp_users WHERE login="\L"
MYSQLGetDir     SELECT dir FROM ftp_users WHERE login="\L"
MySQLGetQTAFS   SELECT quota_files FROM ftp_users WHERE login="\L"
MySQLGetQTASZ  SELECT quota_size FROM ftp_users WHERE login="\L"
MySQLGetRatioUL SELECT ul_ratio FROM ftp_users WHERE login="\L"
MySQLGetRatioDL SELECT dl_ratio FROM ftp_users WHERE login="\L"
MySQLGetBandwidthUL SELECT ul_bandwidth FROM ftp_users WHERE login="\L"
MySQLGetBandwidthDL SELECT dl_bandwidth FROM ftp_users WHERE login="\L"

Затем я попытался перезапустить pure-ftpd-mysql и pure-ftpd

В моей таблице есть поле с pwd как

password    varchar(255)

Когда я вставляю пользователя с открытым текстом pwd, я могу нормально войти с логином и паролем. Когда я вставляю хеш с 'lol', например, SHA512 или BCrypt. Это не позволяет мне войти в систему с pwd 'lol'.

BCrypt $2a$06$JrvxpMAvi6MnRSIvZQMMxOffIDLtEP7lrKNe0k0CTsK51v4zujfpS
SHA512 3DD28C5A23F780659D83DD99981E2DCB82BD4C4BDC8D97A7DA50AE84C7A7229A6DC0AE8AE4748640A4CC07CCC2D55DBDC023A99B3EF72BC6CE49E30B84253DAE

Однако, если я вставляю хэш, он успешно входит в систему, поскольку я предполагаю, что он принимает его как значение открытого текста.

Я попытался изменить mysql.conf на

MYSQLCrypt      crypt

Но это полностью его ломает. Есть много сайтов, которые говорят об использовании crypt, но комментарии в моем файле конфигурации перечисляют crypt () как один из вариантов.

Я прочитал много сообщений и форумов, но самое близкое, что я нашел, это то, что вообще не работает.

https://serverfault.com/a/630806/302696

Вот с чего начинается pure-ftpd

Starting ftp server: Running: /usr/sbin/pure-ftpd-mysql -l mysql:/etc/pure-ftpd/db/mysql.conf -l puredb:/etc/pure-ftpd/pureftpd.pdb -l puredb:/etc/pure-ftpd/pureftpd.pdb -E -F /etc/pure-ftpd/fortunes.txt -j -H -J ALL:!aNULL:!SSLv3 -u 1000 -8 UTF-8 -A -O clf:/var/log/pure-ftpd/transfer.log -B

Так что в основном он не использует крипту, или я использую ее неправильно. Я думал, что он может обрабатывать SHA512 изначально с mysql, но это не так. Еще я могу думать о том, что мне нужен код с конфигурацией, но я не понимаю, зачем ему что-то нужно.

--- НАЧАТЬ tl; dr ---

Предполагая, что ваш Pure-FTPd работает на хосте Linux с glibc 2.7+:

  • Использовать MySQLCrypt crypt - без скобки
  • Запустите этот однострочник Python 3 в той же системе, где работает Pure-FTPd:

    python3 -c 'import sys, crypt, getpass; print(crypt.crypt(getpass.getpass("Password: "), crypt.METHOD_SHA512))'
    
  • Введите желаемый пароль.

  • Скопируйте и вставьте зашифрованный пароль (начиная с $6$) в базу данных.

--- КОНЕЦ tl; dr ---

Идея не открытого текста MySQLCrypt состоит в том, чтобы полностью отключить пароли в виде открытого текста. В скобках MySQLCrypt crypt() все еще принимая хеш как пароль в виде открытого текста, предполагает, что Pure-FTPd обработал строку crypt() как неизвестный метод шифрования и полностью проигнорировал директиву, используя вместо этого метод шифрования по умолчанию для открытого текста. Без скобок MySQLCrypt crypt «Взлом» входа в систему с открытым текстом на самом деле является шагом в правильном направлении: он отключил вход в систему с открытым текстом и начал обрабатывать пароли в базе данных только как зашифрованные.

Теперь вопрос в том, как правильно хэшировать пароль в приемлемой форме. В соответствии с src/mysql.c Pure-FTPd, MySQLCrypt crypt заставит его использовать crypt() функция, допустимые формы которой зависит от реализации. Например, если вы запускаете Pure-FTPd на машине Linux с glibc 2.7 или выше, принимаются 4 формы:

  • SHA-512 (начинается с $6$)
  • SHA-256 (начинается с $5$)
  • MD5 (начинается с $1$)
  • Традиционный DES (начинается с буквенно-цифровой буквы); , вероятно, следует избегать, хотя

Есть несколько способов вызвать систему crypt(); мой предпочтительный метод - встроенный Python 3 crypt модуль. Этот короткий сценарий будет делать наши ставки:

import sys
from crypt import crypt, METHOD_SHA512
from getpass import getpass

print(crypt(getpass("Password: "), METHOD_SHA512))

Или, если вы предпочитаете однострочник с возможностью тройного щелчка и удобного копирования и вставки:

python3 -c 'import sys, crypt, getpass; print(crypt.crypt(getpass.getpass("Password: "), crypt.METHOD_SHA512))'

Пример выполнения:

root@ip-172-16-16-117:~# python3 -c 'import sys, crypt, getpass; print(crypt.crypt(getpass.getpass("Password: "), crypt.METHOD_SHA512))'
Password: 
$6$vTbR62VMHKQNqnEk$TmfeMj/Q6G62RM.hi7liD0IrEvtUp2.jgXbfVRPone/sFTeOwJKftTrrW9j8Hd8.kJsF36OKwP4xHrnURGZTo/

Крайне важно, чтобы эта команда выполнялась на том же хосте, на котором работает Pure-FTPd, чтобы использовать тот же crypt() реализация.

Длинная строка, начинающаяся с $6$ это зашифрованный пароль. В $6$ сам префикс помечает пароль как хешированный с использованием SHA-512. Если система crypt() не поддерживает SHA-512, вывод не начнется $6$; в этом случае следует использовать другой алгоритм. Например, в macOS возможный вывод: $6UCLzI8sPv16. Обратите внимание, что он слишком короткий, а также без знака доллара после $6: Это потому, что реализация macOS crypt() не поддерживает SHA-512.