使用samba4-server在使用OpenWrt固件的树莓派4B上搭建SMB文件共享服务。
服务端:OpenWrt v21.02.2
客户端:macOS Monterey 12.3
为什么选用SMB协议?
除了SMB协议,其他可选的协议有FTP/SFTP/NFS/WebDAV/AFPD等。
我希望搭建一个支持在不同平台上串流视频的文件共享服务。考虑到大部分客户端软件都能支持SMB协议,最终我选择了SMB协议。
服务器只负责储存文件,串流/解码由客户端软件负责。
软件 | 支持平台 | 用途 | 注释 |
---|---|---|---|
infuse | mac, iPhone, iPad, AppleTV | 视频串流/管理软件,支持下载元数据,多平台同步。 | 高级功能需要收费 |
文件管理器 | macOS/Windows | 访问文件 | 系统自带文件管理原生支持SMB协议 |
Kodi | Android | 视频串流/管理软件,支持下载元数据,添加插件。 |
搭建步骤
安装依赖
提前将samba4-server编译到OpenWrt固件中,或使用opkg安装。
如果选择编译自定义固件的形式,注意区分samba4-server
与ksmb
。一个是内核模组的smb协议支持,一个是应用程序。两者选一个安装即可。
配置
安装完成之后,需要配置服务smb.conf。创建文件/etc/samba/smb.conf
即可。以下配置可能需要注意:
若想更好地支持macOS, 需要在[Global]段中配置如下命令:
1
2
3
4
5
6
7
8
9
10
11
12ea support = yes
vfs objects = fruit streams_xattr
#vfs objects = fruit streams_xattr xattr_tdb
fruit:encoding = native
fruit:resource = file
fruit:metadata = stream
fruit:posix_rename = yes
fruit:veto_appledouble = no
fruit:wipe_intentionally_left_blank_rfork = yes
fruit:delete_empty_adfiles = yes
fruit:zero_file_id = yes
fruit:nfs_aces = no如果你的存储设备上的文件系统不支持xattr,选择
xattr_tdb
这条vfs objects的配置。详见下面的疑难解答。默认情况下,对一个Share无权限读(Read)的用户仍然可以看到此Share的名字,只是无法访问其中的内容。若要对无权限访问的用户隐藏Shares, 在[Global]段中配置
access based share enum = yes
。
注意事项
- 提前将需要支持的文件系统内核模组
kmod-fs-*
编译到你的openwrt固件中。 You can’t install a filesystem support into a live system. - 如果需要将资源共享服务以别人分享,请仔细研究权限部分。
- 不要将samba服务暴露到公网。samba服务不是为了公网分享而设计。可能存在安全问题。
疑难解答
[macOS]无法从Finder中直接拖拽文件,将文件上传到SMB服务器
问题描述
直接在文件管理器(Finder)中拖拽文件,将文件从客户端复制到服务器,部分文件无法被上传到samba share中,会报错,最终只能复制一个0KB的同名文件。直接在Finder中拖拽文件夹到samba share,可能可以成功上传。
使用mv
命令将文件从客户端上传到服务器同样会报错,但文件能被成功上传。
在服务器端使用logread可以在系统日志中看到类似的报错:
1 | fruit_pwrite_meta_stream: On-demand create [$filename:AFP_AfpInfo] in write failed: No such file or directory |
原因分析
这是因为samba server所挂载的文件系统不支持文件的xattr属性,例如exFAT。
解决方法
最直接的解决方法是使用支持xattr的文件系统搭建samba服务。如果你的硬盘只接在OpenWRT上,推荐将硬盘格式化为ext4。最开始的时候我将硬盘格式化成了exFAT,希望能同时支持macOS/Windows读写。但其实通过samba协议也能做到这一点,而且exFAT是非日志文件系统,断电/拔插错误可能会损失数据。
另一种方法可以使用VFS module xattr_tdb
.
The
xattr_tdb
Virtual File System (VFS) module stores extended attributes in a Trivial Database (TDB) file. This enables you to use extended attributes on operating systems or file systems that do not support extended attributes.
将xattr_tdb添加到smb.conf中[Global]段的vfs objects的末尾,此时你的文件的vfs objects应该会像这样:
vfs objects = fruit streams_xattr xattr_tdb
vfs module是stackable的,上面的文件配置表示:
- 使用fruit虚拟文件系统模组处理文件,接着将xattr属性传到下一个模组streams_xattr。
- 如果文件系统支持xattr,streams_xattr模组可以处理。此时处理结束。
- 若文件系统不支持xattr,streams_xattr将xattr属性传到下一个模组xattr_tdb。此时xattr_tdb将xattr存储到TDB文件中。处理结束。