Pure-ftpd with MySQL - Crypt() 沒有使用散列密碼登錄
我正在使用純 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.c
Pure-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。