mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-02-07 17:10:07 +08:00
fix: 修复 pure-ftpd 上传缓慢问题 (#6994)
* fix: 修复 pure-ftpd 上传缓慢问题 * fix: 修复 pure-ftpd 修改密码用户名的判断依据 --------- Co-authored-by: BH1XAQ <tanxiao@16iot.cn>
This commit is contained in:
parent
49c072b40d
commit
ee947b6468
@ -1,8 +1,10 @@
|
|||||||
package toolbox
|
package toolbox
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
"os"
|
"os"
|
||||||
"os/user"
|
"os/user"
|
||||||
"path"
|
"path"
|
||||||
@ -21,6 +23,21 @@ type Ftp struct {
|
|||||||
DefaultGroup string
|
DefaultGroup string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FtpList struct {
|
||||||
|
User string
|
||||||
|
Path string
|
||||||
|
Status string
|
||||||
|
}
|
||||||
|
|
||||||
|
type FtpLog struct {
|
||||||
|
IP string `json:"ip"`
|
||||||
|
User string `json:"user"`
|
||||||
|
Time string `json:"time"`
|
||||||
|
Operation string `json:"operation"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Size string `json:"size"`
|
||||||
|
}
|
||||||
|
|
||||||
type FtpClient interface {
|
type FtpClient interface {
|
||||||
Status() (bool, bool)
|
Status() (bool, bool)
|
||||||
Operate(operate string) error
|
Operate(operate string) error
|
||||||
@ -88,9 +105,19 @@ func (f *Ftp) Operate(operate string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *Ftp) UserAdd(username, passwd, path string) error {
|
func (f *Ftp) UserAdd(username, passwd, path string) error {
|
||||||
std, err := cmd.Execf("pure-pw useradd %s -u %s -d %s <<EOF \n%s\n%s\nEOF", username, f.DefaultUser, path, passwd, passwd)
|
entry, err := generatePureFtpEntrySimple(username, passwd, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New(std)
|
return err
|
||||||
|
}
|
||||||
|
pwdFile, err := os.OpenFile("/etc/pure-ftpd/pureftpd.passwd", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer pwdFile.Close()
|
||||||
|
|
||||||
|
_, err = pwdFile.WriteString("\n" + entry + "\n")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
_ = f.Reload()
|
_ = f.Reload()
|
||||||
std2, err := cmd.Execf("chown -R %s:%s %s", f.DefaultUser, f.DefaultGroup, path)
|
std2, err := cmd.Execf("chown -R %s:%s %s", f.DefaultUser, f.DefaultGroup, path)
|
||||||
@ -110,10 +137,54 @@ func (f *Ftp) UserDel(username string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *Ftp) SetPasswd(username, passwd string) error {
|
func (f *Ftp) SetPasswd(username, passwd string) error {
|
||||||
std, err := cmd.Execf("pure-pw passwd %s <<EOF \n%s\n%s\nEOF", username, passwd, passwd)
|
hashedPassword, err := hashPassword(passwd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New(std)
|
return err
|
||||||
}
|
}
|
||||||
|
// read now
|
||||||
|
pwdFile, err := os.Open("/etc/pure-ftpd/pureftpd.passwd")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer pwdFile.Close()
|
||||||
|
|
||||||
|
var entrys []string
|
||||||
|
scanner := bufio.NewScanner(pwdFile)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
if line == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
userEntry := strings.Split(line, ":")
|
||||||
|
if len(userEntry) < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if userEntry[0] == username {
|
||||||
|
userEntry[1] = string(hashedPassword)
|
||||||
|
line = strings.Join(userEntry, ":")
|
||||||
|
}
|
||||||
|
entrys = append(entrys, line)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pwdFile.Close()
|
||||||
|
|
||||||
|
// write new
|
||||||
|
pwdFile, err = os.Create("/etc/pure-ftpd/pureftpd.passwd")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer pwdFile.Close()
|
||||||
|
|
||||||
|
for _, entry := range entrys {
|
||||||
|
_, err := pwdFile.WriteString(entry + "\n")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,12 +239,6 @@ func (f *Ftp) LoadList() ([]FtpList, error) {
|
|||||||
return lists, nil
|
return lists, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type FtpList struct {
|
|
||||||
User string
|
|
||||||
Path string
|
|
||||||
Status string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *Ftp) Reload() error {
|
func (f *Ftp) Reload() error {
|
||||||
std, err := cmd.Exec("pure-pw mkdb")
|
std, err := cmd.Exec("pure-pw mkdb")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -262,11 +327,51 @@ func loadLogsByFiles(fileList []string, user, operation string) []FtpLog {
|
|||||||
return logs
|
return logs
|
||||||
}
|
}
|
||||||
|
|
||||||
type FtpLog struct {
|
func hashPassword(password string) ([]byte, error) {
|
||||||
IP string `json:"ip"`
|
// Hash the password using bcrypt with a cost of 10
|
||||||
User string `json:"user"`
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||||
Time string `json:"time"`
|
if err != nil {
|
||||||
Operation string `json:"operation"`
|
return nil, err
|
||||||
Status string `json:"status"`
|
}
|
||||||
Size string `json:"size"`
|
return hashedPassword, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func generatePureFtpEntrySimple(username, password, path string) (string, error) {
|
||||||
|
return generatePureFtpEntry(username, password, 1000, 1000, "", path+"/./",
|
||||||
|
"", "", "", "", "",
|
||||||
|
"", "", "", "", "", "", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func generatePureFtpEntry(username, password string, uid, gid int, gecos, homedir,
|
||||||
|
uploadBandwidth, downloadBandwidth, uploadRatio, downloadRatio, maxConnections, filesQuota, sizeQuota,
|
||||||
|
authorizedLocalIPs, refusedLocalIPs, authorizedClientIPs, refusedClientIPs, timeRestrictions string) (string, error) {
|
||||||
|
|
||||||
|
hashedPassword, err := hashPassword(password)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format the entry
|
||||||
|
entry := fmt.Sprintf("%s:%s:%d:%d:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s",
|
||||||
|
username,
|
||||||
|
hashedPassword,
|
||||||
|
uid,
|
||||||
|
gid,
|
||||||
|
gecos,
|
||||||
|
homedir,
|
||||||
|
uploadBandwidth,
|
||||||
|
downloadBandwidth,
|
||||||
|
uploadRatio,
|
||||||
|
downloadRatio,
|
||||||
|
maxConnections,
|
||||||
|
filesQuota,
|
||||||
|
sizeQuota,
|
||||||
|
authorizedLocalIPs,
|
||||||
|
refusedLocalIPs,
|
||||||
|
authorizedClientIPs,
|
||||||
|
refusedClientIPs,
|
||||||
|
timeRestrictions,
|
||||||
|
)
|
||||||
|
|
||||||
|
return entry, nil
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user