Smb协议分析及应用

Posted by wsxq2 on 2020-06-16
TAGS:  SMBCIFS文件与打印机共享协议

本文最后一次编辑时间:2020-06-18 14:45:38 +0800

本文是《网络存储技术》一课的大作业,要求写一篇网络存储相关的论文。其本来的格式为.docx,现为了以后查阅方便,将其整理到个人博客。

摘要

SMB 协议作为一个历史悠久的文件共享协议,现在得到了大量应用,如每个现代 Windows 系统都集成了文件与打印机共享服务,其中用到的实际上就是 SMB 协议(或者叫 CIFS)。

此外,SMB 早已不再局限于 Windows 平台,其开源版本(www.samba.org)得到的了大量使用。例如,Linux 常用的两大文件共享协议之一便是 SMB(另一个是 NFS);安卓手机中也有大量使用 SMB 协议的软件(如著名的开源播放器 VLC 安卓版中本地网络功能、ES文件浏览器中的局域网功能);MacOS中的 OS X Mavericks 及更高版本默认的共享文件协议便是 SMB。

当然,SMB 还有众多其它领域的应用尚未提及,如域控制、域成员、集群、分布式文件系统等等。足见 SMB 协议的流行程度。

然而,SMB 协议实现复杂,大量依赖其它协议,理解和分析起来异常困难,其相关文档多而杂乱,却没有简单明了的文档,导致在 Windows 上配置个文件共享服务都总是遇到各种问题却找不到解决之法。

因此,本文的目标是对其协议部分进行简要分析,不求面面俱到,但求通俗易懂,并且重点讲解其应用

简介

服务器消息块(Server Message Block,缩写为 SMB),又称网络文件共享系统(Common Internet File System,缩写为CIFS, /ˈsɪfs/),一种应用层网络传输协议,由微软开发,主要功能是使网络上的机器能够共享计算机文件、打印机、串行端口和通讯等资源。

服务器消息块(SMB)协议是一种网络文件共享协议,在 Microsoft Windows 中的实现称为 Microsoft SMB 协议。定义特定协议版本的消息包集称为方言。通用 Internet 文件系统(CIFS)协议是 SMB 的一种方言。SMB 和 CIFS 也可用于 VMS,几个版本的 Unix 和其他操作系统。

与功能类似的网络文件系统(NFS)相比,NFS 的消息格式是固定长度,而 CIFS 的消息格式大多数是可变长度,这增加了协议的复杂性。CIFS 消息一般使用 NetBIOS 或 TCP 协议发送,分别使用不同的端口 139 或 445,当前倾向于使用 445 端口。CIFS 的消息包括一个信头(32 字节)和消息体(1 个或多个,可变长)。

在 OSI 网络模型中,Microsoft SMB 协议最常用作应用层或表示层协议,它依赖于较低级别的协议进行传输。Microsoft SMB 协议最常用的传输层协议是 TCP/IP 上的 NetBIOS(NBT)。但是,Microsoft SMB协议也可以在没有单独的传输协议的情况下使用,Microsoft SMB 协议/NBT 组合通常用于向后兼容。

Microsoft SMB 协议是客户端 - 服务器实现,由一组数据包组成,每个数据包包含客户端发送的请求或服务器发送的响应。这些数据包可大致分类如下:

  • 会话控制数据包:建立和中断与共享服务器资源的连接。
  • 文件访问数据包:访问和操作远程服务器上的文件和目录。
  • 常规消息包:将数据发送到打印队列,邮件槽和命名管道,并提供有关打印队列状态的数据。

分析

方言(Dialect)

定义特定协议版本的消息包集称为方言(Dialect)。通用 Internet 文件系统(CIFS)协议是 SMB 的一种方言

多年来,Microsoft SMB 协议消息数据包的列表不断增长,以适应 Microsoft SMB 协议日益增长的功能,现在数以百计。其增长的每个阶段都标有标准数据包集或方言。每种方言由标准字符串标识,例如“PC NETWORK PROGRAM 1.0”,“MICROSOFT NETWORKS 3.0”,“DOS LANMAN 2.1”或“NT LM 0.12”。

大多数 Windows 客户端支持至少六种不同的 Microsoft SMB 协议方言,因此使用 Microsoft SMB 协议在客户端和服务器之间建立连接的第一步是确定具有客户端和客户端的最高功能级别的方言。这个过程被称为“谈判方言”。为此目的,上述方言字符串包括在方言协商请求和响应分组中。

身份验证

Microsoft SMB 协议中使用的安全模型与 SMB 的其他变体使用的安全模型相同,由安全用户共享两个级别组成:

  • 用户级身份验证表示尝试访问服务器上的共享的客户端必须提供用户名和密码。经过身份验证后,用户可以访问不受共享级别安全保护的服务器上的所有共享。此安全级别允许系统管理员专门确定哪些用户和组可以访问共享。
  • 共享级别身份验证表示对共享的访问权限仅由分配给该共享的密码控制。与用户级安全性不同,此安全级别不需要用户名进行身份验证,也不会建立用户身份。

在这两个安全级别下,密码在发送到服务器之前都会被加密。Microsoft SMB 协议支持 NTLM 和旧的 LAN Manager(LM)加密。两种加密方法都使用质询 - 响应身份验证,其中服务器向客户端发送随机字符串,客户端返回计算的响应字符串,证明客户端具有足够的访问凭据。

简单示例

让我们来看一个简单的示例。以下步骤概述了整个过程:

  1. 客户端和服务器建立 NetBIOS 会话。
  2. 客户端和服务器协商 Microsoft SMB 协议方言。
  3. 客户端登录到服务器。
  4. 客户端连接到服务器上的共享。
  5. 客户端在共享上打开一个文件。
  6. 客户端从文件中读取。

首先,客户端与服务器建立全双工 TCP 连接。然后,客户端通过 TCP 连接构建并发送 NetBIOS 会话请求数据包。如果数据包格式正确,则服务器返回包含确认会话已建立的消息的数据包。此后,客户端将第一个Microsoft SMB 协议数据包发送到服务器。

  1. 数据包1:SMB_COM_NEGOTIATE
    • 方向:客户端到服务器
    • 说明:客户端请求服务器协商 Microsoft SMB 协议方言。标识包括客户端可以使用的方言的字符串列表包含在数据包中。
  2. 数据包2:SMB_COM_NEGOTIATE
    • 方向:服务器到客户端
    • 说明:服务器响应客户端的请求,以识别将在会话中使用的 Microsoft SMB 协议方言。返回的数据包还包括一个 8 字节的随机字符串,该字符串将在下一步中用于在登录过程中对客户端进行身份验证。
  3. 数据包3:SMB_COM_SESSION_SETUP_ANDX
    • 方向:客户端到服务器
    • 说明:此数据包包含有关客户端功能的信息,因此即使服务器仅实现了共享级别的安全性,也必须发送此数据包。
  4. 数据包3:SMB_COM_SESSION_SETUP_ANDX
    • 方向:服务器到客户端
    • 说明:如果服务器接受质询/响应,则返回给客户端的数据包中包含有效的 UID。如果不接受,服务器将在此数据包中返回错误代码并拒绝访问。
  5. 数据包4:SMB_COM_TREE_CONNECT_ANDX
    • 方向:客户端到服务器
    • 说明:客户端请求访问共享。该数据包包含 UNC 格式的完全指定的共享路径。
  6. 数据包5:SMB_COM_TREE_CONNECT_ANDX
    • 方向:服务器到客户端
    • 说明:如果授予对共享的访问权限,则服务器返回与此数据包中的共享对应的 16 位树 ID(TID)。如果共享不存在或用户没有足够的凭据来访问共享,则服务器将在此数据包中返回错误代码并拒绝访问共享。
  7. 数据包6:SMB_COM_OPEN_ANDX
    • 方向:客户端到服务器
    • 说明:客户端请求服务器代表客户端在访问的共享上打开文件。该数据包包含要打开的文件的名称。
  8. 数据包7:SMB_COM_OPEN_ANDX
    • 方向:服务器到客户端
    • 说明:如果授予了对文件的访问权限,则服务器返回所请求文件的文件ID。如果文件不存在或用户没有足够的凭据来访问该文件,则服务器将在此数据包中返回错误代码并拒绝访问该文件。
  9. 数据包8:SMB_COM_READ_ANDX
    • 方向:客户端到服务器
    • 说明:客户端请求服务器代表客户端从打开的文件中读取数据,并将此数据返回给客户端。打开文件时客户端获取的文件ID包含在此数据包中,以便识别服务器应从哪个打开的文件读取数据。
  10. 数据包9:SMB_COM_READ_ANDX
    • 方向:服务器到客户端
    • 说明:服务器返回此数据包中请求的文件数据。由于已授予对服务器,共享和文件的访问权限,因此不太可能出现错误。但是,在某些情况下可能会发生这种情况:例如,如果在打开文件的时间和从中读取文件的时间之间更改了对共享的访问权限。

抓包验证

在 Windows 10 上搭建共享

下面我们将在 IP 为192.168.56.100的名为 WSXQ2 的 Windows10 家庭版主机上进行文件夹D:\share的共享,共享路径为\\WSXQ2\share。如下图所示:

Windows10上搭建SMB共享.png

从 CentOS 访问

然后我们在 IP 地址为192.168.56.11的名为 master 的 CentOS 主机(Virtual Box,Host Only)上访问该共享。如下图所示:

从CentOS访问SMB共享.png

其中密码输入的是空密码(即无密码),且在/etc/hosts文件中添加了如下内容(否则要使用\\192.168.56.100\share进行访问):

1
192.168.56.100 host

抓包

与此同时我们使用wireshark抓包工具在Oracle VirtualBox Host-Only Network网卡上抓包得到如下结果:

Wireshark对SMB访问过程抓包1.png

Wireshark对SMB访问过程抓包2.png

Wireshark对SMB访问过程抓包3.png

分析

可以对上述抓包分析如下:

序列号(图中第一列) 说明
7,8,9 TCP 三次握手
10,11,12,13,14,17 SMB 协议版本(方言)协商
19,21,22,23,24 建立 NetBIOS 会话
23~32,35 客户端连接到服务器上的共享
36~38 Keep Alive(大约每 5 秒发一次)
46~103 列出分享的文件(ls命令)
106~118 在共享上下载一个文件(get命令)
126~132 断开链接(q命令)

应用

Windows 10

作为服务器

基本方法

右键要共享的文件夹(或者进入要共享的文件夹,然后右键空白处)-属性-共享-高级共享-勾选共享此文件夹-权限-添加(如果有everyone就不必了)-everyone-确定-确定。如下图所示:

Windows10上搭建SMB共享.png

常见问题
开启匿名用户共享

实际上就是要启用guest用户将其密码置为空,可以使用如下命令:

1
2
3
4
5
6
PS C:\windows\system32> net user guest /active:yes
命令成功完成。
PS C:\windows\system32> net user guest *
请键入用户的密码:
请再键入一次密码以便确认:
命令成功完成。

其中键入用户密码时请直接回车(置空)

上述步骤实际上等价于在控制面板网络和共享中心高级共享设置中的密码保护的共享处点击关闭密码保护共享,这正是网上广为流传的方法,但是它可能存在无法关闭的问题,需要通过将guest用户密码置为空来解决。所以简单起见,直接执行上述命令就可以了,并且执行完后,你可以在控制面板网络和共享中心高级共享设置中的密码保护的共享处确认

事实上,为了安全,建议启用guest用户但是给guest用户设置密码。这样在访问共享时使用guest用户及其密码就可以了

防火墙

SMB 协议主要使用 TCP 445 端口进行通信(新版本是这样的)。所以在高级防火墙中只需打开 TCP 445 端口即可。如下图所示(我当前所在的网络即为专用网络):

防火墙设置允许SMB协议.png

另外,对于控制面板网络和共享中心高级共享设置中专用(当前配置文件)处的网络发现文件和打印机共享启用关闭实际上就是操作的高级防火墙,这一点很容易得到验证。所以只要正确配置好高级防火墙就可以了,而且必需打开的只有 TCP 445 端口(如上图所示)

权限设置

权限设置对于共享的成功与否是非常重要的。SMB 共享中,权限有两种,共享和安全用户。简单起见,直接将两者皆设置为everyone可读(可写)即可

  • 共享中权限设置:共享中的权限设置即高级共享中的权限设置。它通常需要给 everyone 提供权限(只读即可)。如下图所示:

    Windows10上搭建SMB共享.png

  • 安全中的权限设置:安全中的权限设置即指文件夹属性中的安全标签的权限设置。它通常也需要给 everyone 提供权限。如下图所示:

    对要共享的文件夹设置权限(安全标签).png

作为客户端

Win+R打开运行,输入\\192.168.2.108\share即可访问

或者先在 powershell(或 CMD)中执行如下命令连接到共享文件的主机:

1
net use \\192.168.2.108\share

然后再打开运行访问

CentOS 7

作为服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
setenforce 0 #临时关闭 SELinux
sed -i "/SELINUX=/c SELINUX=disable" /etc/sysconfig/selinux
#永久关闭SELinux
systemctl stop firewalld #临时关闭防火墙
systemctl disable firewalld #永久关闭防火墙
yum install samba #安装samba软件包
mkdir /var/share #创建共享目录
chown share.share /var/share #修改share目录的所有者和所属组
chmod -R 777 /var/share #修改share目录的权限为所有人可读写
echo "hello the world" > /var/share/a.txt #创建测试文件
useradd -s /sbin/nologin share #创建用户share
smbpasswd -a share #将用户添加至SMB
vim /etc/samba/smb.conf #修改配置文件,添加如下内容
[share]
# 共享文件目录描述
comment = Shared Directories
# 共享文件目录
path = /var/share
# 是否允许guest访问
public = no
guest ok = no
# 指定管理用户
admin users = share
# 可访问的用户组、用户
valid users = share
# 是否浏览权限
browseable = yes
# 是否可写权限
writable = yes
# 文件权限设置
create mask = 0777
directory mask = 0777
force directory mode = 0777
force create mode = 0777
systemctl start smb #启动smb服务
systemctl enable smb #设置开机自启

作为客户端

smbclient
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
root@master:~# smbclient -U guest '\host\share'
Enter SAMBA\guest's password:
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Sat May 25 15:38:25 2019
.. D 0 Sat May 25 15:38:25 2019
.DS\_Store AH 8196 Thu May 31 20:11:41 2018
a.txt A 4 Sat May 25 15:38:28 2019
EOP大讲堂-Everyone Piano新手入门教程 D 0 Tue Jun 19 13:21:39 2018
免下载卷下载百度文库文档网站.url A 112 Wed May 2 19:06:41 2018
动漫 D 0 Fri Mar 22 20:50:12 2019
录制屏幕网站.url A 143 Thu May 10 16:26:50 2018
校内动漫资源.url A 225 Thu May 10 16:14:30 2018
校内动漫资源网站使用教程.mp4 A 2628603 Thu May 10 15:57:37 2018
电影 D 0 Wed Apr 17 09:59:45 2019
简单的截图方法.txt A 168 Thu May 10 17:03:49 2018
败家仔.1981.BluRay.720p.x264.2Audio.AC3-CnSCG.mkv A 3547858804 Sat May 4
00:57:04 2019
217975985 blocks of size 4096. 41030017 blocks available
smb: \> q
root@master:~#
mount.cifs
1
2
root@master:~# mount.cifs '\\host\share' /mnt/tmp -o username=guest,password=share1314,vers=3.0
root@master:~#

Ubuntu 16.04

作为服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
apt install samba
useradd -s /sbin/nologin share #创建用户share
smbpasswd -a share #将用户添加至SMB
mkdir /var/share #创建共享目录
chown share.share /var/share #修改share目录的所有者和所属组
chmod -R 777 /var/share #修改share目录的权限为所有人可读写
echo "hello the world" > /var/share/a.txt #创建测试文件
vim /etc/samba/smb.conf #修改配置文件,添加如下内容
[share]
# 共享文件目录描述
comment = Shared Directories
# 共享文件目录
path = /var/share
# 是否允许guest访问
public = no
guest ok = no
# 指定管理用户
admin users = share
# 可访问的用户组、用户
valid users = share
# 是否浏览权限
browseable = yes
# 是否可写权限
writable = yes
# 文件权限设置
create mask = 0777
directory mask = 0777
force directory mode = 0777
force create mode = 0777
systemctl start smbd #启动smb服务
systemctl enable smbd #设置开机自启

作为客户端

参见前文:CentOS7-作为客户端部分

MacOS

关于作为服务器和客户端的方法均参见https://support.apple.com/zh-cn/HT204445或者谷歌搜索macos smb site:support.apple.com

Android

安卓设备通常是作为 SMB 客户端使用,有很多安卓软件支持 SMB 协议,下面以两个典型的软件为例:ES文件浏览器VLC媒体播放器

ES文件浏览器

使用ES文件浏览器特定版本(新版本需要一些非常麻烦的操作才能使用 smb2.0 功能):

百度网盘网址:https://pan.baidu.com/s/1cp0zaPWFWONkHJb9hVTkfA

提取码:hq81

VLC媒体播放器

VLC 是一款自由、开源的跨平台多媒体播放器及框架,可播放大多数多媒体文件,以及 DVD、音频 CD、VCD 及各类流媒体协议。其安卓版本也相当好用,并且对 SMB 支持良好。

打开VLC app,在左侧边栏的本地网络中可以添加各种文件服务器(支持FTP, FTPS, SFTP, SMB, NFS),配置SMB好后即可访问文件服务器上共享的文件,甚至在线播放视频(不占用对外流量,只占用局域网内流量)

参考链接和文献

  1. Microsoft SMB协议身份验证 - Windows应用程序- Microsoft Docs
  2. 服务器消息块 - 维基百科
  3. Samba (software) - Wikipedia
  4. Windows Server 2012 R2:您使用的是哪种版本的SMB协议(SMB 1.0,SMB 2.0,SMB 2.1,SMB 3.0或SMB 3.02)? - Jose Barreto的博客
  5. wireshark过滤规则及使用方法 - wojiaopanpan - CSDN博客
  6. Windows 8/10的密码保护共享,无需密码访问共享文件 - Microsoft Community
  7. 记window10下samba切换用户 - 简书
  8. Windows 10 无法访问共享的解决办法大全-逍遥峡谷
  9. ubuntu - 如何检查SMB连接和Linux上使用的方言? - Unix和Linux堆栈交换
  10. mount error(112): Host is down - Red Hat Customer Portal
  11. 特定于分发的软件包安装 - SambaWiki
  12. CentOS7下Samba服务安装与配置 - 简书
  13. 丁明一(2016年8月)。Linux运维之道(第2版)。北京:电子工业出版社