海运的博客

sftpgo为ftp/webdav添加支持软链接symlink目录和文件patch

发布时间:April 5, 2022 // 分类: // No Comments

之前有写为sftpgo添加匿名访问支持,还有个问题不能访问链接文件,基于sftpgo2.2.2修改制作了个patch以支持软链接,linux下测试通过,windows未测试。

diff -urN -x .git sftpgo/common/connection.go sftpgo3/common/connection.go
--- sftpgo/common/connection.go 2022-04-04 15:06:39.542187282 +0800
+++ sftpgo3/common/connection.go        2022-04-04 14:57:31.027102136 +0800
@@ -242,6 +242,27 @@
                c.Log(logger.LevelDebug, "error listing directory: %+v", err)
                return nil, c.GetFsError(fs, err)
        }
+       if c.protocol == ProtocolWebDAV || c.protocol == ProtocolFTP {
+               for k, file := range files {
+                       if file.Mode()&os.ModeSymlink != 0 {
+                               dst, err := os.Readlink(fsPath + "/" + file.Name())
+                               if err != nil {
+                                       c.Log(logger.LevelError, "error readlink: %#v error: %+v", fsPath+"/"+file.Name(), err)
+                                       continue
+                               }
+                               dstinfo, err := os.Stat(dst)
+                               if err != nil {
+                                       c.Log(logger.LevelError, "error stat: %#v error: %+v", dst, err)
+                                       continue
+                               }
+                               if dstinfo.IsDir() {
+                                       files[k] = vfs.NewFileInfo(file.Name(), true, 0, dstinfo.ModTime(), false)
+                               } else {
+                                       files[k] = vfs.NewFileInfo(file.Name(), false, dstinfo.Size(), dstinfo.ModTime(), false)
+                               }
+                       }
+               }
+       }
        return c.User.AddVirtualDirs(files, virtualPath), nil
 }
 
diff -urN -x .git sftpgo/ftpd/handler.go sftpgo3/ftpd/handler.go
--- sftpgo/ftpd/handler.go      2022-04-04 15:06:39.550187152 +0800
+++ sftpgo3/ftpd/handler.go     2022-04-04 14:55:41.368885080 +0800
@@ -14,7 +14,7 @@
        "github.com/drakkan/sftpgo/v2/common"
        "github.com/drakkan/sftpgo/v2/dataprovider"
        "github.com/drakkan/sftpgo/v2/logger"
-       "github.com/drakkan/sftpgo/v2/util"
+       //"github.com/drakkan/sftpgo/v2/util"
        "github.com/drakkan/sftpgo/v2/vfs"
 )
 
@@ -288,10 +288,12 @@
        if err != nil {
                return files, err
        }
-       if name != "/" {
-               files = util.PrependFileInfo(files, vfs.NewFileInfo("..", true, 0, time.Now(), false))
-       }
-       files = util.PrependFileInfo(files, vfs.NewFileInfo(".", true, 0, time.Now(), false))
+       /*
+               if name != "/" {
+                       files = util.PrependFileInfo(files, vfs.NewFileInfo("..", true, 0, time.Now(), false))
+               }
+               files = util.PrependFileInfo(files, vfs.NewFileInfo(".", true, 0, time.Now(), false))
+       */
        return files, nil
 }
 
diff -urN -x .git sftpgo/vfs/osfs.go sftpgo3/vfs/osfs.go
--- sftpgo/vfs/osfs.go  2022-04-04 15:06:39.574186762 +0800
+++ sftpgo3/vfs/osfs.go 2022-04-04 14:59:06.413551648 +0800
@@ -291,6 +291,7 @@
                virtualPath = strings.TrimPrefix(virtualPath, fs.mountPath)
        }
        r := filepath.Clean(filepath.Join(fs.rootDir, virtualPath))
+       return r, nil
        p, err := filepath.EvalSymlinks(r)
        if err != nil && !os.IsNotExist(err) {
                return "", err

1.修改vfs/osfs.go文件取消对链接目标的校验是否在家目录内,这时部分客户端已正常,因为sftpgo返回链接目录属性为l而非d,导致有的客户端将链接目录识别为文件。
2.修改common/connection.go文件是修改返回的链接目录/文件的属性为标准目录和文件。
参考:
https://github.com/drakkan/sftpgo/issues/336

sftpgo为ftp/webdav/sftp添加匿名anonymous访问

发布时间:April 5, 2022 // 分类: // No Comments

仅通过check_password_hook验证用户,用户信息使用web配置,将以下脚本保存为文件添加到sftpgo.json配置文件内check_password_hook参数。

#!/bin/bash -eu
#if [[ "${SFTPGO_AUTHD_USERNAME}" = "guest" ]] && [[ "${SFTPGO_AUTHD_PASSWORD}" = "pass" ]]; then
if [[ "${SFTPGO_AUTHD_USERNAME}" = "anonymous" ]] || [[ "${SFTPGO_AUTHD_USERNAME}" = "guest" ]]; then
cat <<EOF
{
  "status": 1
}
EOF
exit 0
fi

使用external_auth_hook外部验证用户并直接返回虚拟目录权限等信息:

#!/bin/bash -eu
if [[ "${SFTPGO_AUTHD_USERNAME}" = "anonymous" ]] || [[ "${SFTPGO_AUTHD_USERNAME}" = "guest" ]]; then
cat <<EOF
{
  "status": 1,
  "username": "${SFTPGO_AUTHD_USERNAME}",
  "home_dir": "/data/ftp",
  "permissions": {
    "/": ["list", "download"]
  },
  "virtual_folders": [
    {
      "name": "dir1",
      "mapped_path": "/data/dir1",
      "virtual_path": "/dir1"
    }, 
    {
      "name": "dir2",
      "mapped_path": "/data/dir2",
      "virtual_path": "/dir2"
    } 
  ]
}
EOF
fi

ftp/webdav匿名访问允许空密码patch:

diff -urN -x .git sftpgo2/ftpd/server.go sftpgo/ftpd/server.go
--- sftpgo2/ftpd/server.go      2022-04-05 18:55:25.959456839 +0800
+++ sftpgo/ftpd/server.go       2022-04-05 19:01:32.841334341 +0800
@@ -9,6 +9,7 @@
        "os"
        "path/filepath"
        "sync"
+        "strings"
 
        ftpserver "github.com/fclairamb/ftpserverlib"
 
@@ -182,6 +183,9 @@
 
 // AuthUser authenticates the user and selects an handling driver
 func (s *Server) AuthUser(cc ftpserver.ClientContext, username, password string) (ftpserver.ClientDriver, error) {
+       if len(strings.TrimSpace(password)) == 0 {
+               password = "guest"
+       }
        loginMethod := dataprovider.LoginMethodPassword
        if s.isTLSConnVerified(cc.ID()) {
                loginMethod = dataprovider.LoginMethodTLSCertificateAndPwd

diff -urN -x .git sftpgo2/webdavd/server.go sftpgo/webdavd/server.go
--- sftpgo2/webdavd/server.go   2022-04-05 18:55:25.995456233 +0800
+++ sftpgo/webdavd/server.go    2022-04-05 19:01:44.537140407 +0800
@@ -13,6 +13,7 @@
        "path/filepath"
        "runtime/debug"
        "time"
+        "strings"
 
        "github.com/go-chi/chi/v5/middleware"
        "github.com/rs/cors"
@@ -232,6 +233,9 @@
        var tlsCert *x509.Certificate
        loginMethod := dataprovider.LoginMethodPassword
        username, password, ok := r.BasicAuth()
+       if len(strings.TrimSpace(password)) == 0 {
+               password = "guest"
+       }
        if s.binding.isMutualTLSEnabled() && r.TLS != nil {
                if len(r.TLS.PeerCertificates) > 0 {
                        tlsCert = r.TLS.PeerCertificates[0]

参考:
https://github.com/drakkan/sftpgo/issues/373
https://github.com/drakkan/sftpgo/blob/main/docs/check-password-hook.md
https://github.com/drakkan/sftpgo/blob/main/docs/external-auth.md

sftpgo使用及占用内存较大解决

发布时间:December 9, 2020 // 分类: // No Comments

编译windows下版本,数据库使用bolt,禁用sql。

git clone https://github.com/drakkan/sftpgo.git
cd sftpgo
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -tags nogcs,nos3,noazblob,nomysql,nosqlite,nopgsql,noportable,novaultkms,noawskms,nogcpkms -ldflags "-s -w"
go build -tags nogcs,nos3,noazblob,nomysql,nobolt,nopgsql,noportable,novaultkms,noawskms,nogcpkms -trimpath -ldflags "-s -w -X github.com/drakkan/sftpgo/v2/version.commit=`git describe --always --dirty` -X github.com/drakkan/sftpgo/v2/version.date=`date -Is`" -o sftpgo

使用vbs脚本启动隐藏cmd窗口并重定向日志到nul:

set ws=createobject("wscript.shell")
ws.CurrentDirectory="d:\Program Files\sftpgo\"
ws.run """d:\Program Files\sftpgo\sftpgo.exe"" serve -v=0 -l """" 2> nul",0
wscript.quit

sftpgo默认认证用户密码使用argon2id,当连接数较多时会占用大量内存,通过web新建用户时密码可直接输入sha512crypt密码密文,后续认证时则使用sha512crypt认证,大幅减小内存占用,密码生成:

echo 123456|openssl passwd -6 -in -

sftpgo默认为根目录和子目录添加.和..,添加后会有一些莫名其妙的问题,不添加客户端也可处理与上级目录的关系:

--- ftpd/handler.go     2022-03-11 15:24:52.147555506 +0800
+++ ftpd/handler.go.bak 2022-03-11 15:17:43.300412122 +0800
@@ -14,7 +14,7 @@
        "github.com/drakkan/sftpgo/v2/common"
        "github.com/drakkan/sftpgo/v2/dataprovider"
        "github.com/drakkan/sftpgo/v2/logger"
-       //"github.com/drakkan/sftpgo/v2/util"
+       "github.com/drakkan/sftpgo/v2/util"
        "github.com/drakkan/sftpgo/v2/vfs"
 )
 
@@ -288,10 +288,10 @@
        if err != nil {
                return files, err
        }
-       //if name != "/" {
-       //      files = util.PrependFileInfo(files, vfs.NewFileInfo("..", true, 0, time.Now(), false))
-       //}
-       //files = util.PrependFileInfo(files, vfs.NewFileInfo(".", true, 0, time.Now(), false))
+       if name != "/" {
+               files = util.PrependFileInfo(files, vfs.NewFileInfo("..", true, 0, time.Now(), false))
+       }
+       files = util.PrependFileInfo(files, vfs.NewFileInfo(".", true, 0, time.Now(), false))
        return files, nil
 }

注意:当sftpgo以普通用户运行时db所在目录sftpgo运行用户要有写入权限,否则就算db文件可写sftpgo也提示db只读。
参考:
https://github.com/drakkan/sftpgo/blob/master/docs/account.md

Vsftpd配置SSL加密FTP数据传输

发布时间:August 17, 2012 // 分类:备份存储,OpenSSL // No Comments

FTP是互联网上广泛使用的文件传输协议,缺点是数据明文传输,在数据经过的节点上进行监听可轻易获取用户和密码,给安装带来诸多隐患,可使用SSL加密FTP连接。
先测试明文传输下用Tcpdump监听ftp用户名和密码:

tcpdump port 21 -nA
20:03:43.077038 IP 192.168.1.1.34453 > 192.168.1.4.21: Flags [P.], seq 21:34, ack 134, win 2920, length 13
E..5."@.@..J............k..3..(kP..hC...USER onovps
20:03:43.077506 IP 192.168.1.4.21 > 192.168.1.1.34453: Flags [P.], seq 134:168, ack 34, win 365, length 34
E..J.g@.@.................(kk..@P..m#...331 Please specify the password.
20:03:43.081218 IP 192.168.1.1.34453 > 192.168.1.4.21: Flags [P.], seq 34:47, ack 168, win 2920, length 13
E..5.#@.@..I............k..@..(.P..h:...PASS onovps
20:03:43.102350 IP 192.168.1.4.21 > 192.168.1.1.34453: Flags [P.], seq 168:191, ack 47, win 365, length 23
E..?.h@.@.................(.k..MP..m.8..230 Login successful.
20:03:43.103626 IP 192.168.1.1.34453 > 192.168.1.4.21: Flags [P.], seq 47:52, ack 191, win 2920, length 5
E..-.$@.@..P............k..M..(.P..h.L..PWD
20:03:43.104025 IP 192.168.1.4.21 > 192.168.1.1.34453: Flags [P.], seq 191:211, ack 52, win 365, length 20
E..<.i@.@.................(.k..RP..mt...257 "/home/onovps"

查看Vsftpd是否支持SSL:

#https://www.haiyun.me
ldd `which vsftpd`|grep ssl
libssl.so.0.9.8 => /usr/lib/libssl.so.0.9.8 (0x00007f18f8c0a000)

生成SSL证书:

openssl req -new -x509 -nodes -out vsftpd.pem -keyout vsftpd.pem
chmod 400 vsftpd.pem
cp vsftpd.pem /etc/ssl/certs/

Vsftpd配置SSL支持:

ssl_enable=YES
allow_anon_ssl=YES
force_local_data_ssl=YES
force_local_logins_ssl=YES
force_anon_logins_ssl=YES
force_anon_data_ssl=YES
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
rsa_cert_file=/etc/ssl/certs/vsftpd.pem

重启vsftp使用支持ssl的ftp客户端连接,本例使用FlashFXP连接:
flashFXP新建连接使用SSL加密FTP.png
flashfxp登录信息ssl.png

Windows/Linux下用Curl上传下载FTP文件

发布时间:April 27, 2012 // 分类:常用软件 // No Comments

Curl是一款强大的命令行多协议访问工具,多操作系统支持,本文就简单介绍下Curl的FTP上传、下载功能。
列出FTP目录:

curl -u user:passwd ftp://www.haiyun.me

下载文件:

curl -u user:passwd ftp://www.haiyun.me/file.rar -o file.rar

上传文件:

curl -u user:passwd -T file.rar ftp://www.haiyun.me
分类
最新文章
最近回复
  • koldjf: 不能过滤
  • 杰迪武士: 此文甚好甚强巨,依照此文在树莓派2 + Rasbian上部署成功 感谢博主美文共赏
  • 海运: ups不知有没选项可设置此参数,不过你可以在另外一台电脑上安装nut客户端自动关机。
  • kgami: 想请教一下,设置了的电脑自动关机之后,几秒后UPS怎么也跟着关机了,导致另外一台电脑没关机就断...
  • 海运: 写的很详细了啊,/etc/nut/hosts.conf用以nut-cgi连接nut服务器参数,...
  • ryan: 请问下nginx配置好了,怎么和这个nut链接呢?最后可视化管理这块能给个详细一点的教程么?谢谢。
  • 1: /etc/config/fstab配置文件 https://openwrt.org/zh/do...
  • 听雨看雪: 找了好久,终于找到UP主,给出的正确解决方案,太感谢了,困扰大半年的问题,重装了N道PVE系统...
  • zr: 大佬,这个bash-completion是从哪个源搞到的
  • 姚生: 要要下载