坑边闲话ksmbd 是韩国三星集团工程师 Namjae Jeon 基于 Linux 内核态开发的一个 SMB 文件共享服务器,其源码现已合并到 Linux 内核主干。传统的 Samba 工作在用户态,使用时会有较大的性能开销。但截至目前,Samba 的 smbd 明显要更加完善,支持的功能更多。因此,本文并不尝试带领读者将 Samba 替换为 ksmbd,而是想带大家尝试新鲜事物,窥探未来的文件存储发展方向。

  • SMB 协议:全称 Server Message Block. SMB 协议最初由 IBM 的 Barry A. Feigenbaum 于 1983 年开发,用于在 IBM OS/2 的网络里共享文件和打印机;
  • smbd:Samba 的 SMB 实现。
  • ksmbd:前缀 k 代表它工作在 Linux 内核态。

1. SMB 协议简史·

SMB 是非常重要的一个网络文件系统协议,它涉及到多个彼此差异很大的版本,因此有必要对其发展历史进行梳理。

历史部分主要参考维基百科相关页面,使用 ChatGPT 4 机器翻译加人工精调。

1.1 SMB 1.0·

  • Barry Feigenbaum 于 1983 年初在 IBM 设计了 SMB,目的是将 DOS INT 21h 的本地文件访问转化为网络文件系统。
  • 到了 1990 年左右,微软对这一版本进行了重大改进,并在其与 3Com 共同为 OS/2 开发的 LAN Manager 操作系统中引入了 SMB 支持。
  • 随后,微软在 Windows for Workgroups(约 1992 年推出)及其后续的 Windows 版本中继续增强了该协议的功能。
  • LAN Manager 的认证基于存在缺陷的 DES 加密,导致密码易被破解。由于出口限制,Windows 域登录协议在美国以外使用 40 位加密;后来,在 1996 年克林顿总统签署了第 13026 号行政命令,取消了对 128 位更强加密的限制。

SMB 1.0(即 SMB1)最初是在 NetBIOS Frame(通过 IEEE 802.2 上 的 NetBIOS)上运行的。后来,它被适配到 IPX/SPX 的 NetBIOS(NBX)和 TCP/IP 的 NetBIOS(NetBT)。从 Windows 2000 开始,SMB 开始在 TCP上运行,使用 TCP 端口 445,这种方式被称为 Direct Host SMB。在 SMB 与 TCP 之间,仍有一层轻量的抽象层,类似于 NetBT 会话服务中的会话消息包。Windows Server 2003 和传统 NAS 设备原生支持 SMB1。

SMB1 是一个交互频繁的协议,在延迟低的局域网中使用并不成问题。但在延迟高的广域网中,协议的频繁握手会导致速度显著降低。后续版本的协议减少了握手交换的次数。微软在 2013 年 6 月宣布 SMB1 为废弃技术,在 Windows Server 2016 和 Windows 10 版本 1709 中,默认不再安装 SMB1.

1.2 CIFS·

1996 年,当 Sun Microsystems 宣布推出 WebNFS 时,微软发起了一个将 SMB 重命名为通用互联网文件系统(Common Internet File System,CIFS)的倡议,并增加了更多功能,包括对符号链接、硬链接和更大文件大小的支持,以及尝试通过 TCP 端口 445 直接连接而无需 NetBIOS 作为传输层的初步尝试(这是一项很大程度上处于实验阶段的努力,需要进一步完善)。微软提交了一些部分规范作为互联网草案给互联网工程任务组 IETF. 这些提交后来已经过期。

1.3 SMB 2.0·

微软于 2006 年随 Windows Vista 和 Windows Server 2008 推出了新版本的协议(SMB 2.0 或 SMB2)。尽管这一协议是专有的,但其规范已经公开发布,以便其他系统可以与使用新协议的微软操作系统进行互操作。

SMB2 大幅减少了 SMB 1.0 频繁交互的问题,将命令和子命令的数量从一百多个减少到仅十九个。它引入了流水线机制,即在前一个请求的响应到达之前发送额外的请求,从而提高了在高延迟链路上的性能。SMB2 还增加了将多个操作合并为单个请求的能力,显著减少了客户端与服务器之间的往返次数,因此提升了性能。虽然 SMB1 也具有合并多个操作的机制 AndX,但微软客户端很少使用 AndX。此外,SMB2 引入了持久文件句柄的概念:这些句柄允许 SMB 服务器的连接在短暂的网络中断期间继续存在,例如在无线网络中常见的中断,而无需重新协商新会话的开销

SMB2 支持符号链接。其他改进包括文件属性的缓存、使用 HMAC SHA-256 哈希算法改进的消息签名以及通过增加服务器每个用户、共享和打开文件的数量等来提高可扩展性。SMB1 协议使用 16 位数据大小,这限制了最大块大小为 64K. SMB2 使用 32 位或 64 位的存储字段,并在文件句柄的情况下使用 128 位,从而消除了块大小的先前限制,并在快速网络上大文件传输的性能得到了改善。

从 Windows Vista/Server 2008 及以后的操作系统开始,当与其他同样支持 SMB2 的机器通信时会使用 SMB2. 对于与旧版本的 Windows 或各种供应商的 NAS 解决方案的连接,仍然使用 SMB1. Samba 3.5 也包括了对 SMB2 的实验性支持。Samba 3.6 完全支持 SMB2(除了使用 Windows 配额管理工具修改用户配额外)

当 SMB2 推出时,它为第三方 SMB 协议的实现者带来了许多优势。最初由 IBM 设计的 SMB1 是通过逆向工程进行的,并后来成为了如 Xenix、OS/2 和 VMS(Pathworks)等多种非 Windows 操作系统的一部分。X/Open 对其进行了部分标准化;微软提交了描述 SMB2 的互联网草案给 IETF,部分是为了回应 IETF 在 2000 年 12 月将网络文件系统的第 4 版正式标准化为 IETF RFC 3010 的行为;然而,这些与 SMB 相关的互联网草案没有获得 IETF 的任何标准批准或其他 IETF 认可。SMB2 也在很大程度上与过去断开了联系。微软的 SMB1 代码必须与多种 SMB 客户端和服务器兼容。SMB1 的信息版本众多,因为如 Unicode 支持等功能是后来才加入的。SMB2 大大减少了协议实现者的兼容性测试需求。SMB2 代码的复杂性大为减少。

1.4 SMB 2.1·

SMB 2.1 是随 Windows 7 和 Server 2008 R2 推出的,它引入了轻微的性能提升,主要是通过一种新的机会锁定机制。

1.5 SMB 3.0·

SMB 3.0(原名 SMB 2.2)与 Windows 8 和 Windows Server 2012 一同推出。它带来了若干重大变化,旨在增加功能并提升 SMB2 的性能,特别是在虚拟化数据中心中:

  • SMB Direct 协议,借助 RDMA 网卡的特性大幅提升文件传输性能
  • SMB Multi-Channel
  • SMB 透明故障转移

此外,它还引入了几项安全增强功能,例如端到端加密和基于新 AES 的签名算法。

1.6 SMB 3.0.2·

SMB 3.0.2(当时称为3.02)随 Windows 8.1 和 Windows Server 2012 R2 推出;在这些及后续版本中,可以选择禁用早期的 SMB 1.0 以提高安全性。

1.7 SMB 3.1.1·

SMB 3.1.1 与 Windows 10 和 Windows Server 2016 一起推出。这个版本在 SMB3 中添加的 AES-128 CCM 加密基础上,支持 AES-128 GCM 加密,并实现了使用 SHA-512 哈希的预认证完整性检查。SMB 3.1.1 还使得在连接到支持此功能的 SMB 版本的客户端时,强制进行安全协商。

2. ksmbd 简介·

ksmbd 是一个新的 Linux 内核模块,它实现了 SMB 服务器,且旨在成为低开销、低占用空间、高性能的文件服务器。ksmbd 涵盖许多基本用例,适合在资源有限的小型设备上运行。OpenWrt 很早就采用了 ksmbd,而当时 ksmbd 仍在开发中。ksmbd 并非旨在取代现有的 Samba 文件服务器 smbd,而是成为一个 Samba 的扩展,将来会与 Samba 集成。Samba 的文件服务器 smbd 的范围更广,支持 ksmbd 目前尚不具有的各种用例和功能:

  • 作为 Active Directory 域成员运行
  • 横向扩展集群
  • 通过专用的 VFS 模块针对 GlusterFS 或 Ceph 等特定文件系统进行优化
  • 卷影复制支持

虽然 ksmbd 是一个功能齐全的 SMB3 服务器,目前它只能使用本地用户和密码,这使其无法在通常使用 Active Directory 或类似身份源的企业环境中使用。还有一种观点认为,内核服务器可能更容易支持 SMB-Direct RDMA 在系统之间传输数据。

3. ksmbd 软件架构分析·

图 . ksmbd 并非一个单纯的内核模块,而是一个小型的软件包。内核态的 forker kthread ksmbd 监听会话连接并创建服务,用户态的 ksmbd.mountd 通过 netlink socket 与内核通信,它可以解析配置文件,管理用户密钥,或者做一些类似列出共享条目的 RPC.

4. ksmbd 安装与配置·

4.1 安装 ksmbd-tools·

对于 Debian 12 bookworm 系统,可直接运行下列命令安装。

1
sudo apt install ksmbd-tools

4.2 配置 ksmbd 共享服务·

4.2.1 创建共享条目·

所谓共享条目指的是 /etc/ksmbd/ksmbd.conf 里的一个表项,在 Windows 运行里输入 \\${IP_ADDR} 并完成认证后将弹出所有合法共享的入口。

1
sudo ksmbd.addshare --option "path = ${SHARED_PATH}}" --option 'read only = no' -a ${SHARE_NAME}

4.2.2 创建用户·

1
sudo ksmbd.adduser --add ${USER_NAME}

4.2.3 停止 ksmbd 服务器·

1
sudo ksmbd.control -s
1
2
sudo modprobe ksmbd
sudo ksmbd.mountd

5. ksmbdsmbd 的性能对比·

To Do.

对存储进行 benchmark 是很麻烦的。目前笔者的环境较为复杂。

  1. TrueNAS SCALE 的定制化程度很低,基本上不具备测试条件,尽管该机器有 ConnectX-6 MCX653106A ECAT 100Gbps 网卡;
  2. 另一台高性能的 Debian 12 服务器具有多网卡,但是唯一支持 RDMA 的是 ConnectX-6 MCX653106A ECAT,其余 RDMA 网卡皆因 team 聚合而失去了 RDMA 功能;
  3. 另一台有 ConnectX-6 MCX653106A ECAT 100Gbps 网卡的 Windows Server 2022 因为系统不是 Linux,所以无法进行深度的 Linux 兼容性测试。
  4. 其余的 Linux 机器只有 ConnectX-4 Lx 网卡,接入的交换机因为缺乏 ECN 功能而不方便排查无法建立 RDMA 通信的原因。

解决方案

  1. 将 Cisco N9K 92160YC-X 交换机的 RoCE 功能配置起来,使用 ConnectX-4 Lx 网卡完成实验;
  2. 将 TrueNAS SCALE 换成 Debian 系统,使用 100Gbps 网卡做测试

不管哪种,都不是近期可以实现的。

6. ksmbd 当前的局限性·

6.1 尚未完全合并到 Samba 项目·

Samba 项目在很久以前就已经建立,而且经历了很多年的完善。时至今日,Samba 套件一直是 TrueNAS SCALE 等严肃存储系统的默认组件。据说未来 ksmbd 将会以模块的形式添加到 Samba 中,但是目前 ksmbd 依旧以独立的 ksmbd-tools 进行提供。

高情商的说法就是未来可期,低情商的说法就是还不成熟。

6.2 RDMA 高性能传输配置复杂·

SMB-Direct 是 SMB 协议的高性能实现,使用 SMB Direct 可以

  • 提高吞吐量:充分利用高速网络的吞吐量,其中网络适配器能以线速进行大量数据的传输;
  • 低延迟:对网络请求提供快速响应,这使得远程文件存储就像本地块存储一样快;
  • 低 CPU 利用率:通过网络传输数据时使用更少的 CPU 周期,从而让 CPU 专注于 App 而非无聊的存储和网络。

ksmbd 据说支持 SMB-Direct,但是需要很复杂的配置。笔者在 Debian 12 系统上做了配置:

  • 编译 Linux 内核 6.1.90,并开启 CONFIG_SMB_SERVER_SMBDIRECT 选项;
  • 安装所有内核模块并重启;
  • 确认 MCX653106A-ECAT 网卡支持 RDMA 传输且驱动已开启。

然而,经过一番测试我依旧发现 Debian 12 无法与 Windows Server 2022 进行 SMB-Direct 存储通信。基于对韩国人的刻板印象,我觉得这个特性大概率是没经过严格测试。

总结·

ksmbd 目前进展较为缓慢,主力开发工程师基本上只有一人,希望能在未来看到这个技术成熟并大规模应用。不过目前来看,该技术并没有 WireGuard 那种摧枯拉朽的势头。