Skip to content

feat(smb-server): smb server support#8250

Closed
KirCute wants to merge 2 commits intoAlistGo:mainfrom
KirCute:feat/smb-server
Closed

feat(smb-server): smb server support#8250
KirCute wants to merge 2 commits intoAlistGo:mainfrom
KirCute:feat/smb-server

Conversation

@KirCute
Copy link
Copy Markdown
Contributor

@KirCute KirCute commented Mar 28, 2025

macos-fuse-t/go-smb2的基础上改了一些实现的 SMB 挂载。

已使用以下客户端进行测试,由于 SMB 协议非常贴近底层,适配起来问题比较多,希望有意者可以再多用几种客户端进行测试,分享一下测试结果。

  • AList SMB 驱动:通过。
  • smbclient:删除文件失败,文件表现为循环以 O_RDONLY 方式打开(Open)和关闭(Close)待删除的文件,删除文件夹通过,客户端不支持复制,其它通过。
  • mount.cifs:偶遇Unable to apply new capability set.,拼尽全力无法战胜。
  • Windows 添加网络位置:
    使用命令:
    net use A: \\127.0.0.1\AList <16位密码> /USER:admin /TCPPORT:5445
    上传、复制、下载可能会报“0x8007003A: 指定的服务器无法运行请求的操作”错误,但如果操作的是小文件一般实际上会成功,如果操作大文件,上传、复制的结果可能会被截断,下载的结果一般与源文件等大小(应该只是预分配了这么大)但也无法正常读取,其它操作通过。
    这是最主要的使用场景但效果不尽人意,后面再优化一下吧。

暂时没有测试游客访问。

除此之外登录验证部分还存在一些问题,SMB 比较基础的验证方式 NTLMv2 大概是这么一个原理:

  1. 服务器生成一个随机数字发送给客户端
  2. 客户端使用这个数字、密码、全大写用户名和域名进行一些不可逆计算得到一个哈希值,把这个哈希值发送给服务器
  3. 服务器进行同样的运算,如果运算结果相同,则验证成功

显然这样的验证方式需要服务器知道密码的原文(退而求其次也必须知道密码的 MD4 哈希),然而服务器中只有用户的加盐 SHA256 哈希,所以验证这一块我暂时不知道怎么搞,想听听大伙怎么想。

目前访问 SMB 服务使用的密码是用户密码的加盐 SHA256 哈希的前 16 位。

Front-end part: AlistGo/alist-web#266

@KirCute KirCute marked this pull request as draft March 28, 2025 10:01
@petercat-assistant
Copy link
Copy Markdown

Walkthrough

该PR引入了对SMB服务器的支持,基于macos-fuse-t/go-smb2进行了一些实现上的修改。由于SMB协议较为底层,可能存在较多bug,建议暂时不要使用。当前实现使用用户密码的加盐SHA256哈希的前16位进行SMB服务访问。

Changes

文件 摘要
cmd/server.go 添加了SMB服务器的启动和关闭逻辑。
go.mod, go.sum 添加了github.com/KirCute/go-smb2-alist依赖。
internal/conf/config.go 新增了SMB配置结构体及其默认值。
internal/model/user.go 增加了用户SMB访问和管理权限的判断方法。
server/smb.go 实现了SMB服务器的初始化及用户文件系统获取逻辑。
server/smb/fsmanage.go 实现了SMB文件系统的目录创建、删除和重命名功能。
server/smb/fsread.go 实现了SMB文件系统的文件读取和目录列出功能。
server/smb/fsup.go 实现了SMB文件系统的文件上传功能。
server/smb/vfs.go 实现了SMB虚拟文件系统的基本操作接口。

Comment thread server/smb.go
if u.IsGuest() || !u.CanSMBAccess() {
return "", false
}
return u.PwdHash[:16], true
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

使用用户密码的加盐SHA256哈希的前16位作为SMB服务的访问密码可能存在安全隐患,因为这可能会导致密码的安全性降低。建议考虑更安全的密码存储和验证方式。

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces preliminary SMB server support based on modifications to the go-smb2-alist implementation and adds new VFS methods for SMB file operations. Key changes include:

  • The implementation of a new VFS interface (readingFile/writingFile) for SMB operations.
  • Enhancements for user permission checks and file upload/download flows.
  • Configuration updates and integration into the main server startup.

Reviewed Changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
server/smb/vfs.go Implements the VFS interface and file handle operations.
server/smb/fsup.go Adds file upload support with temporary file handling.
server/smb/fsread.go Implements readingFile and download initialization methods.
server/smb/fsmanage.go Introduces directory management functions (mkdir, rename).
server/smb.go Configures the SMB server and integrates user authentication.
internal/model/user.go Adds permission bits for SMB access and management.
internal/conf/config.go Updates configuration structure with SMB settings.
cmd/server.go Integrates SMB server startup into the main server routine.
Files not reviewed (1)
  • go.mod: Language not supported
Comments suppressed due to low confidence (1)

server/smb.go:62

  • In GetUserFileSystem, if the user does not have SMB access, return an explicit permission denied error rather than returning the unresolved err value.
if !userObj.CanSMBAccess() { return nil, err }

Comment thread server/smb/fsmanage.go Outdated
if err = fs.MakeDir(ctx, reqPath); err != nil {
return nil, err
}
return fs.Get(ctx, path, &fs.GetArgs{})
Copy link

Copilot AI Mar 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Mkdir, consider using the resolved reqPath (obtained from user.JoinPath) instead of the original path when calling fs.Get for consistent path handling.

Suggested change
return fs.Get(ctx, path, &fs.GetArgs{})
return fs.Get(ctx, reqPath, &fs.GetArgs{})

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已修改,这个有点吓人,但不知道为什么好像对实际使用影响没那么大

@KirCute
Copy link
Copy Markdown
Contributor Author

KirCute commented Mar 28, 2025

  • In GetUserFileSystem, if the user does not have SMB access, return an explicit permission denied error rather than returning the unresolved err value.
if !userObj.CanSMBAccess() { return nil, err }

已修改

@KirCute KirCute marked this pull request as ready for review March 28, 2025 17:09
@KirCute
Copy link
Copy Markdown
Contributor Author

KirCute commented Mar 31, 2025

最近调试遇到了一些困难,一时半会没办法改进windows挂载的体验,还是先不要合并这个pr了

@KirCute KirCute marked this pull request as draft March 31, 2025 08:08
@KirCute KirCute closed this Jun 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants