飞牛 fnOS 深度解析(四):文件服务与用户权限体系
系列文章:
- 第一篇:系统基础与启动流程
- 第二篇:存储架构深挖
- 第三篇:系统目录结构与技术栈
- 第四篇:文件服务与用户权限体系(本文)
- 第五篇:Web 后端架构深度解析
- 第六篇:系统识别方法论与二次开发指南
在前三篇里,我们从系统基础、启动流程、存储底层到目录结构,把 fnOS 的"骨架"摸了一遍。这一篇我们深入到文件服务和用户权限——这是 NAS 最核心的功能,也是用户每天都在用的东西。
飞牛在文件服务上做了大量定制,尤其是 SMB 协议,加了好几个自研的 VFS 模块。用户权限方面,飞牛自研了一套叫 trimacl 的 ACL 机制,能跨 ZFS、ext4 等不同文件系统统一权限。我们一个个来看。
一、SMB/CIFS:飞牛定制最深的协议
SMB(Server Message Block)是 Windows 世界的文件共享协议,也是 NAS 最常用的协议。fnOS 用的是 Samba,但做了深度定制。
1.1 主配置文件
Samba 的主配置在 /etc/samba/smb.conf,我们先看全局配置:
[global]
workgroup = WORKGROUP
server string = %h server (Samba TRIM)
security = user
client min protocol = NT1
server min protocol = NT1
vfs objects = trim_perms full_audit
full_audit:prefix = %u
full_audit:syslog = true
full_audit:success = create_file mkdirat renameat mknodat unlinkat pwrite_recv pwrite_send pread_recv pread_send
server multi channel support = yes
socket options = TCP_NODELAY IPTOS_LOWDELAY
use sendfile = yes
read raw = yes
write raw = yes
min receivefile size = 16384
aio read size = 1
aio write size = 1
max xmit = 65536
large readwrite = yes
fruit:model = TimeCapsule
passdb backend = tdbsam
unix password sync = yes
passwd program = /usr/bin/passwd %u
pam password change = yes
include = /etc/samba/smb.custom.conf
include = /etc/samba/users/%Y.share.conf
include = /etc/samba/users/%Y.timas.conf这里面有几个飞牛特有的标识,也是判断一台设备是不是飞牛系统的重要证据:
标识一:server string = %h server (Samba TRIM)
服务器描述里直接写了 "Samba TRIM"。即使有人把进程名、目录名都改了,这个配置里的 TRIM 也会暴露身份。
标识二:vfs objects = trim_perms full_audit
Samba 的 VFS(Virtual File System,虚拟文件系统)是一个插件机制,可以在文件操作的各个环节插入自定义逻辑。飞牛加了两个自研模块:
trim_perms—— 飞牛自研的权限管理模块,是trimacl在 Samba 层的实现full_audit—— 完整审计模块,记录所有文件操作
在后面的自定义配置里,还会看到第三个 VFS 模块 trim。
标识三:include = /etc/samba/users/%Y.timas.conf
timas 应该是 TRIM Samba 的缩写,这也是飞牛特有的命名。
1.2 完整的文件操作审计
full_audit:prefix = %u
full_audit:syslog = true
full_audit:success = create_file mkdirat renameat mknodat unlinkat pwrite_recv pwrite_send pread_recv pread_send飞牛开启了 full_audit 模块,审计以下操作:
| 操作 | 含义 |
|---|---|
create_file | 创建文件 |
mkdirat | 创建目录 |
renameat | 重命名 |
mknodat | 创建设备文件 |
unlinkat | 删除文件 |
pwrite_recv/pwrite_send | 写入 |
pread_recv/pread_send | 读取 |
所有文件操作都会记录到 syslog 里,带用户名前缀(%u)。这是飞牛的安全审计功能——谁在什么时候对哪个文件做了什么操作,都有日志可查。
1.3 性能优化:飞牛做了大量调优
socket options = TCP_NODELAY IPTOS_LOWDELAY
use sendfile = yes
read raw = yes
write raw = yes
aio read size = 1
aio write size = 1
max xmit = 65536
large readwrite = yes
server multi channel support = yes| 参数 | 作用 |
|---|---|
TCP_NODELAY IPTOS_LOWDELAY | 降低网络延迟,小包立即发送 |
use sendfile | 零拷贝发送,大文件传输不经过用户态 |
aio read/write size = 1 | 所有 IO 都走异步(AIO),提升并发性能 |
server multi channel support = yes | SMB 多通道,多网卡聚合提速 |
large readwrite | 支持大读写块 |
飞牛对 Samba 的性能优化做得很细,几乎把能调的参数都调了。
1.4 苹果支持:Time Machine 备份
fruit:model = TimeCapsulefruit 是 Samba 的苹果兼容模块,这里模拟成 Time Capsule(苹果的时间胶囊路由器),让 Mac 可以直接用 fnOS 做 Time Machine 备份。
1.5 自定义配置:又多了一个 trim VFS 模块
主配置里 include 了 /etc/samba/smb.custom.conf,内容如下:
[global]
workgroup = WORKGROUP
oplocks = yes
durable handles = yes
smb encrypt = auto
max connections = 2000
create mask = 0766
directory mask = 0777
server signing = auto
server multi channel support = yes
min protocol = SMB2_10
wins support = no
veto files = /._*/.DS_Store/
vfs objects = trim_perms full_audit trim
aio read size = 1
aio write size = 32768重大发现:这里的 VFS 模块又多了一个 trim!加上主配置里的 trim_perms 和 full_audit,一共三个飞牛相关的 VFS 模块:
| VFS 模块 | 作用推测 |
|---|---|
trim_perms | 权限管理(trimacl 的 Samba 实现) |
full_audit | 操作审计 |
trim | 飞牛核心 VFS 模块,负责和 trimafs/trimacl 的底层交互 |
另外注意 min protocol = SMB2_10,这覆盖了主配置里的 NT1,说明实际最小协议是 SMB2.1,不是 SMB1。主配置里写 NT1 可能是为了兼容某些老设备,但自定义配置里提升到了 SMB2.1。
还有一个细节:wins support = no 关闭了 WINS。这解释了我们在第一篇里发现的 nmbd 启动慢 1 分 30 秒的问题——nmbd 是 NetBIOS 服务,WINS 关了但 nmbd 可能还在尝试 WINS 相关的网络操作,导致超时等待。
1.6 共享配置:动态生成,按用户分文件
主配置里没有写死任何共享,而是通过 include 动态包含:
include = /etc/samba/users/%Y.share.conf我们看一下这个目录:
$ ls /etc/samba/users/
1000.share.conf 1001.share.conf 1002.share.conf每个用户(按 UID)有独立的共享配置文件。我们看用户 1000(dio)的配置:
[Photos]
path = /vol1/1000/Photos
browseable = yes
available = yes
writeable = yes
hide special files = yes
oplocks = yes
hide unreadable = yes
vfs objects = full_audit shadow_copy2 trim
shadow:format = UTC%z-%Y.%m.%d-%H.%M.%S
shadow:snapdir = /vol1/@snapshot/1000
veto files = /._*/.DS_Store/.@#local/
[share]
path = /vol3/1000/share
...
vfs objects = full_audit shadow_copy2 trim
shadow:snapdir = /vol3/@snapshot/1000
[团队文件-home]
path = /vol2/@team/home
...
hide unreadable = no
vfs objects = trim_perms full_audit shadow_copy2 trim
shadow:snapdir = /vol2/.zfs/snapshot用户 1000 一共有 7 个共享,分布在不同的卷上:
| 共享名 | 路径 | 所在卷 |
|---|---|---|
| Photos | /vol1/1000/Photos | vol1(NVMe SSD) |
| beta | /vol1/1000/beta | vol1(NVMe SSD) |
| video | /vol1/1000/video | vol1(NVMe SSD) |
| share | /vol3/1000/share | vol3(RAID0) |
| 来自:百度网盘 | /vol3/1000/来自:百度网盘 | vol3(RAID0) |
| 测试 | /vol3/1000/测试 | vol3(RAID0) |
| 团队文件-home | /vol2/@team/home | vol2(ZFS) |
重大发现:所有共享都支持 Windows "以前的版本"(VSS 快照)
每个共享的 VFS 模块里都有 shadow_copy2:
vfs objects = full_audit shadow_copy2 trim
shadow:format = UTC%z-%Y.%m.%d-%H.%M.%S
shadow:snapdir = /vol1/@snapshot/1000shadow_copy2 是 Samba 的 VSS(卷影复制服务)模块,让 Windows 用户可以右键文件 → "以前的版本",查看和恢复历史版本。
注意快照目录的差异:
- ZFS 卷(vol2):
/vol2/.zfs/snapshot(ZFS 原生快照目录) - 非 ZFS 卷(vol1、vol3):
/vol1/@snapshot/1000、/vol3/@snapshot/1000
这说明:飞牛在非 ZFS 的卷上也实现了快照功能,快照存在 @snapshot 目录下。不管底层是什么文件系统,都能提供统一的快照和 VSS 功能。这是飞牛存储的一个重要特性。
个人共享 vs 团队共享的差异
| 对比项 | 个人共享 | 团队共享(团队文件-home) |
|---|---|---|
| VFS 模块 | full_audit shadow_copy2 trim | trim_perms full_audit shadow_copy2 trim |
| hide unreadable | yes(隐藏不可读文件) | no(不隐藏) |
团队共享多了一个 trim_perms 模块,说明团队空间需要更复杂的权限管理(多用户权限、部门权限等)。个人空间里用户看不到自己没权限的文件,团队空间里能看到所有文件但打不开没权限的——这是合理的设计,团队空间需要让成员知道有哪些文件存在。
二、NFS:当前未配置共享
NFS(Network File System)是 Unix/Linux 世界的标准文件共享协议。fnOS 的 NFS 配置在 /etc/exports:
$ cat /etc/exports
# /etc/exports: the access control list for filesystems which may be exported
# to NFS clients. See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4 gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check)
#只有注释,没有实际的共享配置。但 NFS 服务在运行(2049 端口在监听),说明是按需启用的——用户在 Web 界面创建 NFS 共享时,系统会动态写入 /etc/exports 并 reload NFS 服务。
NFS 和 SMB 的主要区别:
| 对比项 | SMB/CIFS | NFS |
|---|---|---|
| 起源 | 微软 | Sun/Unix |
| 主要客户端 | Windows | Linux/Unix |
| 认证方式 | 用户密码(tdbsam) | 基于 IP/主机名 + UID 映射 |
| 状态 | 有状态 | 无状态(NFSv4 之前) |
| 端口 | 445 | 2049 |
| 功能丰富度 | 高(权限、锁、打印) | 低(配置简单,性能好) |
三、FTP:用的是 smbftpd,不是 vsftpd
FTP 是最古老的文件传输协议,现在用得少了,但很多老设备和自动化脚本还在用。fnOS 用的不是常见的 vsftpd 或 proftpd,而是 smbftpd。
smbftpd 是一个开源 FTP 服务器(作者 Wang, Chun-Pin),它的特点是支持 SMB 模式——可以复用 Samba 的共享配置和权限。配置文件在 /usr/trim/etc/smbftp.conf。
3.1 关键配置
Port 21
PassiveModePortRange 55536-55899
VirtualUserAuthMethod unix
RequireValidShell No
ChrootSet @ /fs/%U/ftp
SupportUTF8Client Yes
UsingUTF8FileSystem Yes
CharsetEncoding UTF-8
TransferLog /var/log/smbftpd.log
SecurityPolicy both
SSLCertFile /usr/trim/var/trim_connect/ssls/fnOS/1782808384/fnOS.crt
SSLKeyFile /usr/trim/var/trim_connect/ssls/fnOS/1782808384/fnOS.key| 配置 | 说明 |
|---|---|
Port 21 | FTP 控制端口 |
PassiveModePortRange 55536-55899 | 被动模式数据端口范围(NAT 环境需要转发) |
VirtualUserAuthMethod unix | 用 Unix 系统用户认证,不是虚拟用户 |
RequireValidShell No | 不要求有效 shell——nologin 用户也能登录 FTP |
ChrootSet @ /fs/%U/ftp | 所有用户 chroot 到 /fs/用户名/ftp,只能访问自己的 ftp 目录 |
SecurityPolicy both | 同时支持明文和 SSL/TLS |
SSLCertFile/SSLKeyFile | SSL 证书,和飞牛互联(trim_connect)共用 |
3.2 几个值得注意的点
1. 认证和 SMB 统一
VirtualUserAuthMethod unix 表示 FTP 用 Unix 系统用户认证,和 SMB 用的是同一套用户。RequireValidShell No 表示即使是 nologin 用户(不能 SSH 登录的普通用户)也能登录 FTP。
2. chroot 隔离
ChrootSet @ /fs/%U/ftp 表示所有用户登录后都被 chroot 到自己的 ftp 目录,看不到系统其他部分。这是安全设计,防止 FTP 用户浏览系统文件。
3. SSL 证书统一管理
FTP 的 SSL 证书路径是 /usr/trim/var/trim_connect/ssls/fnOS/...,和飞牛互联(trim_connect)共用同一套证书。说明飞牛的证书是统一管理的,不是每个服务各自生成。
4. smbftpd 的 SMB 模式
smbftpd 有一个独特的功能:DefaultMode SMB,可以复用 Samba 的共享配置和权限。但当前配置里这个选项被注释了,默认是 Normal 模式。如果启用 SMB 模式,FTP 用户看到的共享和 SMB 用户完全一样,权限也一致。
四、WebDAV:飞牛自研服务
WebDAV 是基于 HTTP 的文件共享协议,适合跨网络访问和移动端使用。fnOS 的 WebDAV 是自研服务,配置非常简单:
[server]
infinity = true
max_sub_dirs = 10000
http = true
http_port = 5005
https = true
https_port = 5006
cert = /usr/trim/var/trim_connect/ssls/fnOS/1782808384/fnOS.crt
key = /usr/trim/var/trim_connect/ssls/fnOS/1782808384/fnOS.key| 配置 | 说明 |
|---|---|
http_port = 5005 | WebDAV HTTP 端口 |
https_port = 5006 | WebDAV HTTPS 端口 |
infinity = true | 支持无限深度目录 |
max_sub_dirs = 10000 | 最大子目录数 |
| SSL 证书 | 和飞牛互联共用 |
WebDAV 的二进制程序应该是 /usr/trim/bin/webdav,配置文件只有几行,说明大部分逻辑是硬编码在程序里的。
五、四协议对比总结
| 协议 | 实现方式 | 端口 | 认证方式 | 配置文件 | 飞牛定制程度 |
|---|---|---|---|---|---|
| SMB/CIFS | Samba(深度定制) | 445 | tdbsam + 系统用户 | /etc/samba/smb.conf + users/UID.share.conf | ★★★★★(4个VFS模块) |
| NFS | 内核 NFS | 2049 | 基于 IP/主机名 | /etc/exports(动态生成) | ★☆☆☆☆ |
| FTP | smbftpd | 21 + 55536-55899 | Unix 系统用户 | /usr/trim/etc/smbftp.conf | ★★☆☆☆ |
| WebDAV | 飞牛自研 | 5005/5006 | 未知 | /usr/trim/etc/webdav.conf | ★★★★☆ |
统一认证:四个协议都用同一套系统用户,没有各自维护用户数据库。SMB 用 tdbsam 存密码但和系统密码同步,FTP 直接用系统用户认证。
六、用户权限体系
搞清楚了文件服务,我们来看用户权限——这是 NAS 安全的核心。
6.1 系统用户
$ cat /etc/passwd | grep -v nologin | grep -v false
root:x:0:0:root:/root:/bin/bash
sync:x:4:65534:sync:/bin:/bin/sync
postgres:x:107:113:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
dio:x:1000:1001::/home/dio:/bin/bash可登录的系统用户只有 4 个,其中只有 dio(UID 1000) 是 Web 界面创建的用户。
但注意:我们之前在 /fs/、/vol2/、/vol3/ 下都看到了 1000、1001、1002 三个用户目录,说明系统里有三个用户。1001 和 1002 被 grep -v nologin 过滤掉了——它们的 shell 是 /usr/sbin/nologin,不能 SSH 登录。
结论:飞牛创建的用户,管理员才有登录 shell(/bin/bash),普通用户是 nologin(不能 SSH 登录)。 这是合理的安全设计——普通用户只能通过 Web、SMB、FTP 访问文件,不能登录系统命令行。
6.2 用户组
$ cat /etc/group | grep -E '100[0-9]'
Administrators:x:1000:dio
Users:x:1001:
G1:x:1002:dio,D| 组名 | GID | 成员 | 说明 |
|---|---|---|---|
| Administrators | 1000 | dio | 管理员组 |
| Users | 1001 | (dio 是主组) | 普通用户组 |
| G1 | 1002 | dio, D | 用户自定义组 |
看当前用户 dio 的信息:
$ id dio
uid=1000(dio) gid=1001(Users) groups=1001(Users),1000(Administrators),1002(G1)- UID 1000,主组是 Users(GID 1001)
- 附属组包括 Administrators(管理员)和 G1(自定义组)
- Administrators 的 GID 是 1000,比 Users 的 1001 还小,说明管理员组是系统先创建的
6.3 Samba 密码数据库
$ ls /var/lib/samba/private/
netlogon_creds_cli.tdb passdb.tdb secrets.tdbSamba 的用户密码存在 passdb.tdb 里(tdbsam 后端),和系统密码(/etc/shadow)是分开的,但通过 unix password sync = yes 保持同步。
也就是说,Web 界面修改用户密码时,会同时改:
- Linux 系统密码(
/etc/shadow) - Samba 密码(
passdb.tdb)
6.4 用户信息主存储:PostgreSQL
我们在系统里找了一圈,没有找到用户相关的 SQLite 数据库:
$ find /usr/trim -name "*.db" -o -name "*.sqlite"
/usr/trim/var/downloadcenter/downloadcenter.db
/usr/trim/var/minidlna/files.db只有下载中心和 DLNA 的数据库,没有用户数据库。而系统里有 PostgreSQL 15 在运行(postgresql@15-main.service),且只监听 127.0.0.1:5432(不对外暴露)。
结论:用户信息、权限配置、共享设置等主要数据存在 PostgreSQL 里。 由于我们没有 postgres 用户的密码,无法直接查看表结构,但可以通过 Web 界面操作 + 观察文件变化来推断。
6.5 trimacl:飞牛自研的统一权限机制
在第二篇存储架构里我们提到过,飞牛给 ZFS 打了一个叫 trimacl 的内核补丁,ZFS 的挂载参数里有这个选项:
trim_6c71e3b3-... on /vol2 type zfs (rw,noatime,xattr,trimacl,casesensitive)trimacl 是飞牛自研的 ACL(访问控制列表)机制,它的核心作用是:跨文件系统统一权限。
普通 Linux 系统里,ext4 用 POSIX ACL,ZFS 用自己的 ACL,NFSv4 又是另一套 ACL,各不相同。飞牛的 trimacl 把这些统一起来——不管底层是 ZFS 还是 ext4,都用同一套权限模型,Web 界面设置的权限能在所有卷上生效。
在 SMB 层,trimacl 通过 trim_perms VFS 模块对接——Samba 的权限请求被 trim_perms 拦截,转换成 trimacl 的权限检查。
6.6 用户创建流程推测
基于以上信息,Web 界面创建用户时的流程大概是:
Web 界面创建用户
↓
调用 /usr/trim/bin/useradd(飞牛自己的 useradd,不是系统的)
↓
1. 创建 Linux 系统用户(/etc/passwd、/etc/shadow、/etc/group)
- 管理员:shell = /bin/bash
- 普通用户:shell = /usr/sbin/nologin
2. 创建 Samba 用户(passdb.tdb),设置密码同步
3. 在 PostgreSQL 里写入用户信息和权限配置
4. 在各存储卷上创建用户目录(/vol1/UID/、/vol2/UID/、/vol3/UID/)
5. 设置 trimacl 权限
6. 生成 Samba 共享配置(/etc/samba/users/UID.share.conf)
7. reload Samba 服务七、端口监听全景
最后看一下所有文件服务和管理端口的监听情况:
$ ss -tlnp | grep -E '2049|21|22|80|443|5666'
LISTEN 0 511 0.0.0.0:5666 ← fnOS Web 管理界面(HTTP)
LISTEN 0 511 0.0.0.0:443 ← HTTPS(重定向到 5667)
LISTEN 0 128 0.0.0.0:22 ← SSH
LISTEN 0 32 0.0.0.0:21 ← FTP(smbftpd)
LISTEN 0 511 0.0.0.0:80 ← HTTP(重定向到 5666)
LISTEN 0 4096 0.0.0.0:8080 ← 内部服务
LISTEN 0 64 0.0.0.0:2049 ← NFS加上 WebDAV 的 5005/5006,SMB 的 445,完整的端口列表:
| 端口 | 服务 |
|---|---|
| 22 | SSH |
| 21 | FTP(smbftpd) |
| 80 | HTTP(→ 5666) |
| 443 | HTTPS(→ 5667) |
| 445 | SMB/CIFS |
| 2049 | NFS |
| 5005/5006 | WebDAV(HTTP/HTTPS) |
| 5666/5667 | fnOS Web 管理(HTTP/HTTPS) |
| 8080/8005 | 内部服务 |
八、本章小结
这一篇我们深入解析了 fnOS 的文件服务和用户权限体系,核心发现:
- SMB 是飞牛定制最深的协议——加了 4 个 VFS 模块(trim_perms、full_audit、shadow_copy2、trim),共享配置动态生成,所有卷都支持 Windows VSS 快照
- FTP 用的是 smbftpd,不是常见的 vsftpd,支持 SMB 模式复用共享配置
- WebDAV 是飞牛自研,配置极简
- NFS 按需启用,当前未配置共享
- 四协议统一认证,都用同一套系统用户
- 用户权限核心是 trimacl——飞牛自研的跨文件系统统一 ACL,通过 trim_perms VFS 模块对接 SMB
- 用户信息主存储是 PostgreSQL,系统用户和 Samba 密码是衍生数据
下一篇我们将进入 Web 后端架构——解析 Nginx 的反向代理规则、30+ 微服务的路由映射、Unix Socket 通信机制,以及飞牛自研的 Nginx 模块。这是二次开发最核心的部分,敬请期