Я использую 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 формы:
$6$
)$5$
)$1$
)Есть несколько способов вызвать систему 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.