0%

使用samba4搭建本地资源共享服务

使用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-serverksmb。一个是内核模组的smb协议支持,一个是应用程序。两者选一个安装即可。

配置

安装完成之后,需要配置服务smb.conf。创建文件/etc/samba/smb.conf即可。以下配置可能需要注意:

  1. 若想更好地支持macOS, 需要在[Global]段中配置如下命令:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ea 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的配置。详见下面的疑难解答。

  2. 默认情况下,对一个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.

来源:Using the xattr tdb VFS Module

将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文件中。处理结束。