Mysql

Pure-ftpd with MySQL - Crypt() 沒有使用散列密碼登錄

  • March 20, 2017

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

我的表有一個欄位,密碼為

password    varchar(255)

當我使用明文密碼插入使用者時,我可以使用登錄名和密碼登錄。當我插入帶有“lol”的雜湊時,例如 SHA512 或 BCrypt 雜湊。它不允許我使用密碼“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

所以基本上它沒有使用 crypt 或者我沒有正確使用它。我雖然它可以用 mysql 本機處理 SHA512,但它不能。我能想到的其他事情是我需要帶有配置的程式碼,但我不明白為什麼它需要任何東西。

—開始tl;博士—

假設您的 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))'
  • 輸入所需的密碼。
  • 將加密後的密碼(以 開頭$6$)複製並粘貼到數據庫中。

— 結束 tl; 博士 —

非明文背後的想法MySQLCrypt是完全禁用明文密碼。括號中的MySQLCrypt crypt()仍然接受雜湊作為明文密碼表明 Pure-FTPd 將字元串crypt()視為未知的 crypt 方法並完全忽略該指令,而是使用預設的明文 crypt 方法。未加括號的MySQLCrypt crypt“破壞”明文登錄實際上是朝著正確方向邁出的一步:它禁用了明文登錄,並開始將數據庫中的密碼視為僅加密。

現在,問題是如何正確地將密碼散列成可接受的形式。根據src/mysql.cPure-FTPd 的說法,MySQLCrypt crypt會使其使用crypt()功能,其可接受的形式取決於實現。例如,如果您在具有 glibc 2.7 或更高版本的 Linux 機器上執行 Pure-FTPd,則接受 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。

引用自:https://serverfault.com/questions/837744