Pure-ftpd与MySQL – Crypt()没有login我的哈希密码

我正在使用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) 

当我插入一个明文密码的用户,我可以login和密码都很好。 当我插入散列与'lol'如SHA512或BCrypt散列。 它不允许我用pwd'lol'login。

 BCrypt $2a$06$JrvxpMAvi6MnRSIvZQMMxOffIDLtEP7lrKNe0k0CTsK51v4zujfpS SHA512 3DD28C5A23F780659D83DD99981E2DCB82BD4C4BDC8D97A7DA50AE84C7A7229A6DC0AE8AE4748640A4CC07CCC2D55DBDC023A99B3EF72BC6CE49E30B84253DAE 

但是,如果我粘贴在散列,它成功login,因为我认为它作为一个纯文本值。

我试图改变mysql.conf

 MYSQLCrypt crypt 

但这完全打破了。 有很多网站说,使用地穴,但在我的configuration文件列表crypt()作为其中一个选项的意见。

我已经阅读了许多post和论坛,但是我发现最接近的是这个,根本不起作用。

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

这是纯粹的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 

所以基本上它不使用地穴或我没有正确使用它。 我虽然它可以处理与MySQL原生SHA512,但事实并非如此。 其他的东西,我能想到的是,我需要configuration代码,但我不明白为什么它会需要任何东西。

— BEGIN tl; dr —

假设你的Pure-FTPd运行在一台装有glibc 2.7+的Linux主机上:

  • 使用MySQLCrypt crypt没有括号
  • 在运行Pure-FTPd的同一个系统上单独运行这个Python 3:

     python3 -c 'import sys, crypt, getpass; print(crypt.crypt(getpass.getpass("Password: "), crypt.METHOD_SHA512))' 
  • input所需的密码。

  • 复制粘贴密码(从$6$ )并粘贴到数据库中。

— END tl; dr —

非纯文本MySQLCrypt背后的想法是完全禁用明文密码。 括号内的MySQLCrypt crypt()仍然接受散列作为纯文本密码,这表明Pure-FTPd将stringcrypt()视为一个未知的crypt方法,并完全忽略该指令,而是使用默认的明文crypt方法。 未加括号的MySQLCrypt crypt “打破”明文login实际上是朝着正确的方向迈出的一步:它禁用明文login,并开始将数据库中的密码视为crypt-ed。

现在,问题是如何正确地散列一个可接受的forms的密码。 根据Pure-FTPd的src/mysql.cMySQLCrypt crypt会导致它使用crypt()函数,它的可接受forms取决于实现 。 例如,如果在glibc 2.7或更高版本的Linux机器上运行Pure-FTPd,则接受4种forms:

  • 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/ 

为了使用相同的crypt()实现,必须在运行Pure-FTPd的同一主机上运行此命令。

$6$开头的长行是密码密码。 $6$前缀本身将密码标记为使用SHA-512散列的密码。 如果系统crypt()不支持SHA-512,输出将不会启动$6$ ; 在这种情况下,应该使用另一种algorithm。 例如,在macOS上,可能的输出是$6UCLzI8sPv16 。 请注意,它过于短暂,并且在$6之后也缺less美元符号:这是因为crypt()的macOS实现不支持SHA-512。