SMB 实战与排错 — smbclient 抓包、共享配置与权限定位

SMB 动手实战:Wireshark smb2 过滤式、smbclient/mount.cifs/net use/PowerShell 命令、smb.conf 配置、ACCESS_DENIED 与版本协商排错、SMB1 加固、与 NFS 对比 / TCP 445

这篇你能学到

  • 怎么用 smbclient / mount.cifs / net use / Get-SmbConnection 把 SMB 共享"连起来、看进去",以及 smb.conf 里哪些开关决定安全与性能。
  • 怎么用 Wireshark smb2 过滤式从 NEGOTIATE → SESSION_SETUP → TREE_CONNECT 抓包,一眼区分"版本协商失败 / 认证失败 / 共享级还是文件系统级权限不足"。
  • 遇到 LOGON_FAILUREACCESS_DENIEDBAD_NETWORK_NAME、版本协商失败、文件被占用、性能差时先记结论再排查,以及 SMB1/EternalBlue 的加固清单与和 NFS 的选型对比。

抓包观察

Wireshark 显示过滤式

下面这些过滤式是 SMB 排错的"目录",先扫一眼:看到 smb 说明环境里还有 SMB1(应立即整改),smb2.nt_status != 0 是看错误响应的第一过滤式,smb2.dialect 能确认有没有被降级。

过滤式用途
smb2所有 SMB2/3 报文(最常用)
smbSMB1 报文 —— 抓到就说明环境里还有 SMB1,应立即整改
tcp.port == 445Direct Hosting
tcp.port == 139SMB over NetBIOS(旧)
nbnsNetBIOS 名称服务(UDP 137)—— Responder 投毒的信号
smb2.cmd == 0只看 NEGOTIATE(排查版本协商失败
smb2.cmd == 1只看 SESSION_SETUP(排查认证问题
smb2.cmd == 3只看 TREE_CONNECT(排查共享名/共享权限
smb2.cmd == 5只看 CREATE(打开文件)
smb2.cmd == 8 || smb2.cmd == 9只看 READ / WRITE(性能分析)
smb2.nt_status != 0只看出错的响应,排错第一过滤式
smb2.nt_status == 0xc000006dSTATUS_LOGON_FAILURE(密码错,暴力破解检测
smb2.nt_status == 0xc0000022STATUS_ACCESS_DENIED(权限不足)
smb2.nt_status == 0xc00000ccSTATUS_BAD_NETWORK_NAME(共享名不存在
smb2.nt_status == 0xc0000043STATUS_SHARING_VIOLATION(文件被占用
smb2.dialect协商出的方言版本
smb2.filename contains "report"按文件名筛
smb2.tree contains "IPC$"谁在访问 IPC$(横向移动检测)
ntlmsspNTLM 认证交换(看挑战/响应
kerberosKerberos 认证
smb2.flags.signature == 1已签名的报文
smb2.protocol_id == 0xfd534d42加密的 SMB3 报文(TRANSFORM_HEADER)
smb2.time > 1响应超过 1 秒的慢请求

命令行抓包:下面这套 tcpdump/tshark 覆盖"抓全量、捞错误、查 SMB1、统计认证失败来源、确认协商方言、SMB 性能统计"六个动作。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
sudo tcpdump -i eth0 -s 0 -w smb.pcap 'port 445 or port 139 or port 137'

# 找出所有失败的 SMB2 操作
tshark -r smb.pcap -Y 'smb2.nt_status != 0' -T fields \
  -e frame.number -e ip.src -e ip.dst -e smb2.cmd -e smb2.nt_status -e smb2.filename

# 检测环境中是否还有 SMB1(安全审计必做)
tshark -r smb.pcap -Y 'smb' -T fields -e ip.src -e ip.dst | sort -u

# 统计认证失败来源(口令喷洒检测)
tshark -r smb.pcap -Y 'smb2.nt_status == 0xc000006d' -T fields -e ip.src | sort | uniq -c | sort -rn

# 看协商出的方言(确认没有降级)
tshark -r smb.pcap -Y 'smb2.cmd == 0 && smb2.flags.response == 1' \
  -T fields -e ip.src -e smb2.dialect

# SMB 性能统计(Wireshark 内置)
tshark -r smb.pcap -q -z smb2,srt

典型字段说明

NEGOTIATE Response(确认协商结果):重点看 Dialect 是不是 3.1.1、Signing required 是不是 True、Cipher 是什么——这三项直接反映服务端安全水位。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
SMB2 (Server Message Block Protocol version 2)
    SMB2 Header
        Server Component: SMB2 (0xfe534d42) ← 0xFE = SMB2/3;0xFF = SMB1;0xFD = 已加密
        Header Length: 64
        Command: Negotiate Protocol (0)
        NT Status: STATUS_SUCCESS (0x00000000)
        Credits granted: 1
        Flags: 0x00000001 .... ...1 = Response: This is a RESPONSE
        Message ID: 0
    Negotiate Protocol Response (0x00)
        Security mode: 0x03
            .... ...1 = Signing enabled: True
            .... ..1. = Signing required: True ← 服务器【要求】签名
        Dialect: 0x0311 ← 协商出 SMB 3.1.1 ✅
        Capabilities: 0x0000007f
            ... DFS / LEASING / LARGE_MTU / MULTI_CHANNEL / ENCRYPTION
        Negotiate Context: SMB2_PREAUTH_INTEGRITY_CAPABILITIES
            HashAlgorithm: SHA-512
        Negotiate Context: SMB2_ENCRYPTION_CAPABILITIES
            Cipher: AES-128-GCM ← 加密算法

NTLMSSP 认证三步(工作组/IP 直连时可见):注意用户名是明文、NTLMv2 响应可被离线爆破或 Relay。

1
2
3
4
5
6
7
8
9
① SESSION_SETUP Request → NTLMSSP_NEGOTIATE (messageType=1)
② SESSION_SETUP Response → NTLMSSP_CHALLENGE (messageType=2)
      NTLM Server Challenge: 1122334455667788 ← 8 字节挑战值
      Target Name: WORKGROUP
③ SESSION_SETUP Request → NTLMSSP_AUTH (messageType=3)
      Domain name: EXAMPLE
      User name: administrator ← 用户名明文可见
      NTLMv2 Response: <HMAC-MD5 结果> ← 可离线爆破 / 可被 Relay
④ SESSION_SETUP Response → STATUS_SUCCESS + SessionId

排错四看

  1. NEGOTIATE 响应的 Dialect:确认协商到的版本。若是 0x0202 或看到 SMB1,说明一端太老或被降级。
  2. SESSION_SETUP 的 NT Status0xC0000016 MORE_PROCESSING_REQUIRED 是 NTLM 多轮的正常中间态,不是错误;最终变 SUCCESS 才算认证通过。
  3. TREE_CONNECT 的 NT Status0xC00000CC = 共享名错;0xC0000022 = 共享级权限不足。这一步能区分"共享权限"和"NTFS 权限" —— 能 TREE_CONNECT 成功但 CREATE 失败,说明是 NTFS ACL 问题。
  4. 有没有 TRANSFORM_HEADER(0xFD534D42):有 = SMB3 加密生效,Wireshark 看不到内容(这是好事)。

常用命令 / 配置

Linux 客户端

下面这组是 Linux 侧"装工具 → 探共享 → 交互访问 → 挂载"的常规动作;其中 -m SMB1/SMB2/SMB3 还能用来试探服务端支持哪些版本。

 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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# 安装
sudo apt install smbclient cifs-utils # Debian/Ubuntu
sudo yum install samba-client cifs-utils # RHEL/Rocky

# ---------- 探测 ----------
# 列出共享(匿名)
smbclient -L //192.168.1.100 -N

# 列出共享(指定凭据 + 强制 SMB3)
smbclient -L //192.168.1.100 -U 'EXAMPLE\zhangsan' -m SMB3

# 只探测支持的协议版本(排查版本问题)
smbclient -L //192.168.1.100 -N -m SMB1 # 若成功 = 服务端还开着 SMB1 smbclient -L //192.168.1.100 -N -m SMB2
smbclient -L //192.168.1.100 -N -m SMB3

# nmap 全面探测(版本、共享、漏洞)
nmap -p 445 --script smb-protocols,smb-security-mode,smb-os-discovery 192.168.1.100
nmap -p 445 --script smb-enum-shares,smb-enum-users 192.168.1.100
nmap -p 445 --script smb-vuln-ms17-010 192.168.1.100 # EternalBlue 检测

# ---------- 交互式访问(类 FTP)----------
smbclient //192.168.1.100/share -U 'EXAMPLE\zhangsan'
# smb: \> ls
# smb: \> cd docs
# smb: \> get report.docx
# smb: \> put local.txt
# smb: \> mget *.log
# smb: \> prompt off # 关闭 mget/mput 的逐个确认
# smb: \> recurse on # 递归
# smb: \> mask ""
# smb: \> exit

# 非交互执行命令(脚本用)
smbclient //192.168.1.100/share -U 'user%password' -c 'ls; get report.docx'

# 用凭据文件(避免密码进 history 和 ps)
cat > ~/.smbcreds <<'EOF'
username=zhangsan
password=P@ssw0rd
domain=EXAMPLE
EOF
chmod 600 ~/.smbcreds
smbclient //192.168.1.100/share --authentication-file=~/.smbcreds

# ---------- 挂载到本地 ----------
sudo mkdir -p /mnt/smb
sudo mount -t cifs //192.168.1.100/share /mnt/smb \
  -o credentials=/root/.smbcreds,vers=3.1.1,uid=1000,gid=1000,file_mode=0644,dir_mode=0755,iocharset=utf8,seal

# 常用挂载参数:
# vers=3.1.1|3.0|2.1|2.0 协议版本(不指定则自动协商,建议显式指定)
# credentials=<file> 凭据文件
# uid=/gid= Linux 侧文件属主(SMB 无 POSIX 属主概念,必须映射)
# file_mode=/dir_mode= Linux 侧权限位
# iocharset=utf8 中文文件名必需
# seal 【强制 SMB3 加密】
# sec=ntlmssp|krb5 认证方式
# noperm 不做本地权限检查(交给服务器判断)
# cache=strict|none|loose 缓存策略
# actimeo=1 属性缓存秒数(默认 1)
# nobrl 禁用字节范围锁(某些应用需要)
# _netdev fstab 中标记网络设备

sudo umount /mnt/smb

# fstab 持久化
# //192.168.1.100/share /mnt/smb cifs credentials=/root/.smbcreds,vers=3.1.1,uid=1000,gid=1000,iocharset=utf8,seal,_netdev,x-systemd.automount 0 0

# ---------- Kerberos 挂载(域环境)----------
kinit zhangsan@EXAMPLE.COM
sudo mount -t cifs //fs01.example.com/share /mnt/smb -o sec=krb5,cruid=$(id -u),vers=3.1.1

Windows 客户端(PowerShell 优先)

下面这组 Windows 侧命令里,Get-SmbConnection 能直接看到协商到的 Dialect 和是否加密签名,是诊断首选。

 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
37
38
39
40
41
# ---------- 探测与连接 ----------
net view \\192.168.1.100 # 列出共享(依赖 srvsvc)
net use Z: \\192.168.1.100\share /user:EXAMPLE\zhangsan *
net use # 查看当前映射
net use Z: /delete # 断开
net use * /delete /y # 断开全部

# PowerShell 方式(推荐)
New-SmbMapping -LocalPath 'Z:' -RemotePath '\\192.168.1.100\share' `
  -UserName 'EXAMPLE\zhangsan' -Password 'P@ssw0rd' -Persistent $true
Remove-SmbMapping -LocalPath 'Z:' -Force

# ---------- 诊断(最有用的几条)----------
Get-SmbConnection # 当前连接【含协商出的 Dialect】Get-SmbConnection | Format-Table ServerName,ShareName,Dialect,Encrypted,Signed
Get-SmbMultichannelConnection # 多通道状态
Get-SmbClientNetworkInterface # 客户端网卡与 RSS/RDMA 能力
Get-SmbClientConfiguration # 客户端全局配置
Get-SmbOpenFile # 服务端:谁打开了哪些文件 Get-SmbSession # 服务端:当前会话
Get-SmbShare # 服务端:本机共享列表
Get-SmbShareAccess -Name 'share' # 共享级权限(不是 NTFS 权限!)

# ---------- 服务端配置 ----------
New-SmbShare -Name 'data' -Path 'D:\data' -FullAccess 'EXAMPLE\Admins' -ReadAccess 'EXAMPLE\Users'
Set-SmbShare -Name 'data' -EncryptData $true # 该共享强制 SMB3 加密
Grant-SmbShareAccess -Name 'data' -AccountName 'EXAMPLE\zhangsan' -AccessRight Change -Force
Revoke-SmbShareAccess -Name 'data' -AccountName 'Everyone' -Force
Remove-SmbShare -Name 'data' -Force

# 全局强制加密与签名
Set-SmbServerConfiguration -EncryptData $true -Force
Set-SmbServerConfiguration -RequireSecuritySignature $true -Force
Set-SmbClientConfiguration -RequireSecuritySignature $true -Force

# ---------- 禁用 SMB1(安全加固,必做)----------
Get-WindowsOptionalFeature -Online -FeatureName SMB1Protocol # 查状态
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart
Get-SmbServerConfiguration | Select EnableSMB1Protocol
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
# 审计谁还在用 SMB1(先审计再禁用,避免误伤老设备)
Set-SmbServerConfiguration -AuditSmb1Access $true -Force
Get-WinEvent -LogName 'Microsoft-Windows-SMBServer/Audit' -MaxEvents 50

Linux 服务端(Samba)

装好 Samba 后,真正的重点在 smb.conf:下面这份配置同时做了"禁 SMB1、强制签名加密、禁空会话、禁 NTLMv1"四项加固。

1
sudo apt install samba

/etc/samba/smb.conf

 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
37
38
39
40
41
42
43
[global]
    workgroup = EXAMPLE
    server string = File Server
    security = user
    map to guest = Never

    # ---- 协议版本:禁用 SMB1,只允许 SMB2/3 ----
    server min protocol = SMB2_10
    server max protocol = SMB3_11
    client min protocol = SMB2_10

    # ---- 安全加固 ----
    server signing = mandatory # 强制签名
    smb encrypt = required # 强制 SMB3 加密(desired = 尽量加密)
    restrict anonymous = 2 # 禁止空会话
    ntlm auth = no # 只允许 NTLMv2(禁 NTLMv1)

    # ---- 性能 ----
    socket options = TCP_NODELAY IPTOS_LOWDELAY
    use sendfile = yes
    aio read size = 16384
    aio write size = 16384

    # ---- 日志 ----
    log file = /var/log/samba/log.%m
    max log size = 5000
    log level = 1

[data]
    path = /srv/samba/data
    browseable = yes
    read only = no
    valid users = @smbusers
    create mask = 0664
    directory mask = 0775
    force group = smbusers
    veto files = /.DS_Store/Thumbs.db/

[public]
    path = /srv/samba/public
    browseable = yes
    read only = yes
    guest ok = yes
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# 校验配置语法(改完必做)
testparm
testparm -s # 只输出有效配置(含默认值)

# 用户管理(Samba 密码库与 Linux 密码独立!)
sudo useradd -M -s /sbin/nologin zhangsan
sudo smbpasswd -a zhangsan # 添加到 Samba 密码库
sudo smbpasswd -e zhangsan # 启用
sudo pdbedit -L -v # 列出所有 Samba 用户

sudo systemctl restart smbd nmbd
sudo systemctl status smbd

# 运行状态
sudo smbstatus # 当前连接、锁定的文件 sudo smbstatus -b # 只看会话
sudo smbstatus -L # 只看锁

# 日志
sudo tail -f /var/log/samba/log.smbd

常见故障与排错

故障 1:NT_STATUS_LOGON_FAILURE —— 认证失败

先记住结论:认证失败先怀疑"密码 / 域名写法 / Samba 独立密码库不同步"这三样,Kerberos 场景还要看两端时差是否超 5 分钟。Samba 的密码库和 Linux 系统密码是两套,改了系统密码不等于 Samba 能用。

原因排查
密码错换个已知正确的账号试
域名写法错EXAMPLE\useruser@example.com、纯 user 三种写法
Samba 密码库与系统密码不同步sudo smbpasswd -a user 重设(Samba 有独立密码库!)
账号被禁用/锁定/密码过期Windows:net user zhangsan /domain;Samba:pdbedit -L -v
NTLMv1 被禁但客户端只支持 v1服务端日志会有提示;老设备需临时 ntlm auth = yes不推荐
时间不同步(Kerberos)Kerberos 要求两端时差 < 5 分钟chronyc sources / w32tm /query /status
用 IP 连导致回落 NTLM 而域策略禁止改用 FQDN 连接以走 Kerberos
1
2
3
4
# 提高 Samba 日志级别定位
sudo smbcontrol smbd debug 5
sudo tail -f /var/log/samba/log.smbd
sudo smbcontrol smbd debug 1 # 记得调回去

故障 2:NT_STATUS_ACCESS_DENIED —— 认证过了但访问不了

先记住结论:SMB 是两层权限取交集——共享级(TREE_CONNECT 阶段检查)和文件系统级(CREATE 阶段检查)。一眼区分法:TREE_CONNECT 就拒是共享级问题;连上了 CREATE 才拒是 NTFS/POSIX 问题(Samba 上还常是 SELinux 上下文没设 samba_share_t)。

关键:Windows/Samba 有两层权限,取交集(更严格的那个生效):

1
2
3
① 共享级权限(Share Permissions) ← TREE_CONNECT 阶段检查
② NTFS / POSIX 文件系统权限 ← CREATE 阶段检查
最终权限 = ① ∩ ②

用抓包精确定位是哪一层

  • TREE_CONNECT 就返回 0xC0000022共享级权限问题
  • TREE_CONNECT 成功但 CREATE 返回 0xC0000022NTFS/POSIX 权限问题
1
2
3
4
# Windows:查两层权限
Get-SmbShareAccess -Name 'data' # 共享级
Get-Acl 'D:\data' | Format-List # NTFS 级
(Get-Acl 'D:\data').Access | Format-Table IdentityReference,FileSystemRights,AccessControlType
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Linux/Samba:查两层
testparm -s | grep -A10 '\[data\]' # 共享级:valid users / read only
ls -ld /srv/samba/data # POSIX 级
getfacl /srv/samba/data # POSIX ACL
ls -Z /srv/samba/data # SELinux 上下文

# SELinux 是 Samba 最常见的隐形杀手
sudo setsebool -P samba_export_all_rw on
sudo chcon -R -t samba_share_t /srv/samba/data
sudo semanage fcontext -a -t samba_share_t "/srv/samba/data(/.*)?"
sudo restorecon -Rv /srv/samba/data

故障 3:NT_STATUS_BAD_NETWORK_NAME —— 共享名不存在

先记住结论:这是共享名拼错或共享不存在,先 smbclient -L 列一遍确认真实共享名;隐藏共享($ 结尾)不会出现在列表里需直接指定。

1
smbclient -L //192.168.1.100 -U user # 先确认共享名拼写
原因排查
共享名拼错/大小写SMB 共享名不区分大小写但要拼对
共享是隐藏共享($ 结尾)C$ADMIN$IPC$ 不会出现在列表里,需直接指定
Samba 里 path 指向的目录不存在testparm + ls -ld <path>
共享被删除或服务未重启systemctl restart smbd

故障 4:连接失败 / 版本协商问题

先记住结论:版本协商失败九成是"一端还发 SMB1、另一端已禁"(或反过来)。逐版本 smbclient -m SMB1/SMB2/SMB3 试探,就能定位服务端支持范围;Windows 10/11 默认不装 SMB1 连老 NAS 失败时,别重新开 SMB1,去升级 NAS。

1
2
Protocol negotiation failed: NT_STATUS_CONNECTION_RESET
Unable to connect with SMB1 -- no workgroup available
原因排查
服务端禁用了 SMB1,客户端只发 SMB1客户端加 -m SMB3;升级客户端;老设备(老打印机、老 NAS)需单独隔离
客户端太老不支持 SMB2检查 smbclient -L //host -m SMB2 是否成功
Windows 10/11 默认不装 SMB1,连老 NAS 失败优先升级 NAS 固件;不要为此重新启用 SMB1
3.1.1 预认证算法不匹配0xC05D0000,两端 Samba/Windows 版本差异大时出现
1
2
3
4
5
# 逐版本试探,定位服务端支持范围
for v in SMB1 SMB2 SMB3; do
  echo "--- $v ---"
  smbclient -L //192.168.1.100 -N -m $v 2>&1 | head -3
done

故障 5:端口不通

先记住结论:445 不通先分"服务没起 / 防火墙 / 被 ISP 封"三类;家宽普遍封 445,公网跑 SMB 既不可行也不应该,用 VPN 或 SMB over QUIC。

1
2
3
nc -zv 192.168.1.100 445
nc -zv 192.168.1.100 139
nmap -p 139,445 192.168.1.100
原因排查
Windows 防火墙Enable-NetFirewallRule -DisplayGroup "File and Printer Sharing"
ISP 封禁 445(家宽普遍)公网访问 SMB 不可行也不应该,用 VPN 或 SMB over QUIC
Samba 服务未启动systemctl status smbdss -tlnp | grep 445
Samba 只绑定了部分接口smb.confinterfaces / bind interfaces only

故障 6:中文文件名乱码

先记住结论:中文乱码几乎都是字符集没对齐——Linux 挂载必须加 iocharset=utf8,服务端 unix charset = UTF-8,并确认系统 locale 是 UTF-8。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Linux 挂载必须加 iocharset
sudo mount -t cifs //host/share /mnt/smb -o credentials=/root/.smbcreds,iocharset=utf8

# Samba 服务端
# smb.conf:
# unix charset = UTF-8
# dos charset = CP936 # 仅当需要兼容极老的中文 Windows 客户端

# 确认系统 locale
locale
export LANG=zh_CN.UTF-8

故障 7:STATUS_SHARING_VIOLATION —— 文件被占用

先记住结论:这正是 Windows 强制锁的"特性"而非故障——某进程以 ShareAccess=0 独占打开文件,别人连读都被拒,这是 Unix 没有的语义。定位是谁占着,必要时由服务端强制关闭句柄。

这是 Windows 语义与 Unix 语义的根本差异:Windows 的 CreateFileShareAccess 参数,若某进程以 ShareAccess=0 打开文件,其他人连读都打不开。Unix 则允许任意并发打开。

1
2
3
# 服务端定位是谁占着
Get-SmbOpenFile | Where-Object Path -like '*report.docx*' | Format-Table ClientUserName,ClientComputerName,Path
Close-SmbOpenFile -FileId <ID> -Force # 强制关闭(可能导致对方数据丢失)
1
2
# Samba 侧
sudo smbstatus -L # 看锁定的文件

故障 8:性能问题

先记住结论:性能差先确认协商到的版本——还在 SMB 2.0 就没有大 MTU、单连接跑不满万兆就开 Multichannel、海量小文件慢是 SMB 固有短板(靠复合请求+Lease 缓解,改不了本质)。加密掉速就升到 3.1.1 的 AES-GCM,几乎免费。

1
2
3
# 确认协商到的版本与特性(旧版本性能差很多)
Get-SmbConnection | Format-Table ServerName,ShareName,Dialect,Encrypted,NumOpens
Get-SmbMultichannelConnection # 多通道是否生效
症状原因解决
大文件传输慢协商到 SMB 2.0,无大 MTU升级两端到 SMB3
万兆网跑不满单连接单核瓶颈启用 Multichannel(多网卡或 RSS 网卡);Set-SmbClientConfiguration -EnableMultiChannel $true
海量小文件极慢每个文件多次 RTTSMB 的固有短板;用压缩打包传输;确认复合请求生效(SMB2+);启用 Lease 缓存
开启加密后掉速AES 运算开销确认 CPU 支持 AES-NI;SMB3.1.1 的 AES-128-GCM 比 3.0 的 CCM 快得多,升级到 3.1.1
Linux 挂载慢缓存策略cache=loose牺牲一致性)、actimeo=30rsize/wsize=1048576
目录列表慢目录项太多SMB 的 QUERY_DIRECTORY 分批返回;减少单目录文件数
1
2
3
# Linux 侧看统计
cat /proc/fs/cifs/Stats
sudo mount -t cifs ... -o rsize=1048576,wsize=1048576,cache=strict

故障 9:安全加固清单

先记住结论:SMB 是勒索软件和横向移动的头号通道(WannaCry / NotPetya / EternalBlue 全走 SMB1),加固顺序永远是"禁 SMB1 → 强制签名加密 → 445 不出内网"。网络层那一条(禁止工作站之间互连 445、445 不出边界)能挡掉 90% 的横向传播。

SMB 是勒索软件和横向移动的头号通道(WannaCry / NotPetya / EternalBlue MS17-010 全走 SMB1)。

 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
# ===== Windows =====
# ① 禁用 SMB1(最重要)
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart

# ② 强制签名(防中间人篡改与 NTLM Relay)
Set-SmbServerConfiguration -RequireSecuritySignature $true -Force
Set-SmbClientConfiguration -RequireSecuritySignature $true -Force

# ③ 强制加密(防窃听)
Set-SmbServerConfiguration -EncryptData $true -Force
Set-SmbServerConfiguration -RejectUnencryptedAccess $true -Force

# ④ 禁用 Guest 回落(防止误连到伪造服务器)
Set-SmbClientConfiguration -EnableInsecureGuestLogons $false -Force

# ⑤ 关闭 NetBIOS over TCP/IP(消除 NBT-NS 投毒面)
Get-NetAdapter | ForEach-Object {
  $key = "HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters\Interfaces\Tcpip_$($_.InterfaceGuid)"
  Set-ItemProperty -Path $key -Name NetbiosOptions -Value 2
}
# 同时在组策略中禁用 LLMNR 和 mDNS

# ⑥ 关闭不必要的管理共享(评估影响后再做)
Set-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters' AutoShareServer 0
1
2
3
4
5
6
7
8
9
# ===== Samba(smb.conf)=====
[global]
    server min protocol = SMB2_10 # 禁 SMB1
    server signing = mandatory # 强制签名
    smb encrypt = required # 强制加密
    restrict anonymous = 2 # 禁空会话
    ntlm auth = no # 禁 NTLMv1
    map to guest = Never # 禁 guest 回落
    # hosts allow = 192.168.1.0/24 # IP 白名单
1
2
3
4
5
6
7
# ===== 网络层(最关键)=====
# 445/139/137/138 【绝不出内网边界】,防火墙 deny
# 内网做微分段:只允许文件服务器接收 445,禁止工作站之间互连 445
# (这一条能挡住 90% 的勒索软件横向传播)

# 自查是否暴露
nmap -p 139,445 --script smb-protocols,smb-vuln-ms17-010 <你的公网IP>

与其他协议对比

SMB vs NFS —— 核心对比

维度SMBNFS
出身IBM/Microsoft(1983),DOS/WindowsSun Microsystems(1984),Unix
标准化微软 MS-SMB2 开放规范(非 RFCIETF RFC(RFC 1813 / 7530 / 8881)
端口TCP 445(旧 139 + UDP 137/138)TCP 2049(v3 另需 111 + 动态端口)
承载自有消息格式,4 字节长度分帧ONC RPC + XDR
状态始终有状态(Session/Tree/File 三层)v3 无状态 / v4 有状态
文件语义Windows:ACL、不区分大小写但保留大小写、ADS 备用数据流、打开的文件不可删POSIX:mode 位、区分大小写、硬链接、可删除已打开的文件
文件锁强制锁(ShareAccess 冲突检测,语义严格)v3 咨询锁(NLM,弱)/ v4 内置
缓存一致性(Oplock/Lease + 服务器主动 Break 回调)(close-to-open + 属性缓存超时)
认证内置 NTLM/Kerberos,开箱即用AUTH_SYS 自报 UID(极弱),强认证需额外部署 Kerberos
加密SMB3 原生 AES-GCM,一条命令开启sec=krb5p(部署复杂)
权限模型NTFS ACL(细粒度)POSIX mode / NFSv4 ACL
性能特点元数据操作与小文件更优(复合请求、Lease);大文件靠 Multichannel/RDMA大文件顺序 I/O 强;小文件弱
高可用持久句柄 + 透明故障转移 + 多通道pNFS(v4.1)横向扩展
客户端Windows 原生;Linux 用 cifs-utilsLinux/Unix 原生;Windows 需装 NFS 客户端
主要风险445 暴露 = 勒索软件入口;NTLM RelayAUTH_SYS 可冒充任意 UIDno_root_squash 提权
选型有 Windows 客户端 / 需要 ACL 与强锁语义纯 Linux 环境 / K8s PV / HPC

SMB 与其他文件访问方式

维度SMBNFSFTP/SFTPWebDAVS3
挂载为本地盘需 FUSE✅(性能差)需 s3fs
部分读写Range
文件锁✅ 强
内置加密✅ SMB3❌ 需 Kerberos✅ SFTP✅ HTTPS✅ HTTPS
广域网友好❌(QUIC 除外)
打印共享
典型场景Windows 办公共享Linux 集群文件分发跨平台协作云存储

速查表 / 常见面试题

端口 / 关键值速查

SMB Direct HostingTCP 445
SMB over NetBIOSTCP 139
NetBIOS 名称服务UDP 137
NetBIOS 数据报UDP 138
SMB over QUICUDP 443
SMB1 魔数0xFF534D42\xFFSMB
SMB2/3 魔数0xFE534D42\xFESMB
SMB3 加密报文魔数0xFD534D42
SMB2 头部长度64 字节(SMB1 为 32)
方言编号2.0.2=0x0202 / 2.1=0x0210 / 3.0=0x0300 / 3.0.2=0x0302 / 3.1.1=0x0311
默认隐藏共享C$ADMIN$IPC$

常见 NTSTATUS 速查

名称一句话
0x00000000SUCCESS成功
0xC0000016MORE_PROCESSING_REQUIREDNTLM 多轮中间态,不是错误
0xC000006DLOGON_FAILURE账号或密码错
0xC0000022ACCESS_DENIED权限不足(分共享级/NTFS 级)
0xC00000CCBAD_NETWORK_NAME共享名不存在
0xC0000043SHARING_VIOLATION文件被占用
0xC0000034OBJECT_NAME_NOT_FOUND文件不存在
0xC0000203USER_SESSION_DELETED会话失效需重认证
0xC00000BBNOT_SUPPORTED版本/特性不支持

一行命令速查

1
2
3
4
5
6
7
smbclient -L //HOST -N # 列共享(匿名)
smbclient //HOST/share -U 'DOM\user' # 交互访问
smbclient -L //HOST -N -m SMB1 # 探测是否还开着 SMB1
mount -t cifs //HOST/share /mnt -o credentials=/root/.cred,vers=3.1.1,seal
smbstatus # Samba:当前连接与锁
testparm # Samba:校验配置
nmap -p445 --script smb-protocols,smb-vuln-ms17-010 HOST
 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
Get-SmbConnection | ft ServerName,ShareName,Dialect,Encrypted # 看协商版本 Get-SmbOpenFile # 谁开着文件
Get-SmbShareAccess -Name 'share' # 共享级权限
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force # 禁 SMB1 ```

### 常见面试题

**Q1SMB1  SMB2 的区别为什么必须禁用 SMB1**
ASMB2 **彻底重写**而非小改命令从 100+ 精简到 19 头部从 32 字节变 64 字节引入 Credit 流控和复合请求文件 ID 扩展到 128 单次 I/O  64KB 提升到 8MB必须禁用 SMB1 的原因:① **无强制签名**易被中间人篡改;② 认证机制弱LM/NTLMv1);③ **EternalBlueMS17-010**等严重漏洞是 WannaCry/NotPetya 的传播途径;④ 性能极差每个操作一次 RTT);⑤ 微软已正式宣布弃用Windows 10/11 默认不安装

**Q2445  139 端口有什么区别**
A**139**  SMB over NetBIOS over TCPNBT),需要配合 UDP 137名称服务 138数据报), Windows 2000 之前的方式**445**  Direct HostingSMB 直接跑在 TCP 名称解析交给 DNS现代环境应**只用 445彻底关闭 137/138/139** —— NBT-NS 广播是内网 Responder 投毒攻击的主要入口有意思的是 445 报文前仍保留 4 字节长度前缀这是从 NBSS 头继承的分帧机制

**Q3Oplock  Lease 有什么区别**
A两者都是让客户端安全缓存文件的机制服务器在冲突时主动回调打断**Oplock**SMB1/2.0只有 Level II / Exclusive / Batch 三个粗粒度级别**绑定"打开实例"** —— 同一台机器上第二个进程打开同一文件就会打破 Oplock缓存失效**Lease**SMB 2.1+把权限拆成 **R/W/H 三个独立位**读缓存/写缓存/句柄缓存),且用 **LeaseKey 绑定"客户端+文件"**同一客户端的多个进程共享租约**互不打断**这在真实场景 Office 打开文档编译器反复读头文件中性能差异巨大

**Q4SMB3.1.1 的预认证完整性Pre-Auth Integrity解决什么问题**
A解决**降级攻击**SMB3.0 之前中间人可以篡改 NEGOTIATE 报文把方言列表改成只剩 SMB1 或去掉加密能力迫使双方用弱协议通信而这个篡改无法被检测因为签名密钥是认证后才有的)。3.1.1 让双方**从第一个 NEGOTIATE 报文开始累积计算 SHA-512 哈希链**这个哈希参与派生会话密钥中间人一旦篡改任何握手报文两端算出的哈希不同  密钥不同  签名校验失败  连接中断

**Q5SMB 的两层权限是什么怎么定位是哪一层出问题**
A**共享级权限Share Permissions**  **NTFS/POSIX 文件系统权限**最终权限取**交集**更严格者生效)。抓包定位法`TREE_CONNECT` 就返回 `ACCESS_DENIED`  共享级问题`TREE_CONNECT` 成功但 `CREATE` 返回 `ACCESS_DENIED`  NTFS/POSIX 问题Windows  `Get-SmbShareAccess`  `Get-Acl` 分别查Linux/Samba 还要额外检查 **SELinux 上下文**`samba_share_t`),这是最常见的隐形杀手

**Q6`IPC$` 是什么为什么它是安全重点**
A`IPC$` 是每台 Windows 上的隐藏共享共享类型是 `PIPE`承载**命名管道**大量 Windows 远程管理协议实际是 **MSRPC over SMB Named Pipe**`\svcctl`服务控制**PsExec 横向移动的原理**)、`\samr`枚举用户)、`\winreg`远程注册表)、`\netlogon`**Zerologon 攻击面**)。这意味着**仅仅关闭文件共享是不够的** —— 只要 445 开着且 `IPC$` 可访问攻击者就能做大量事情老系统的**空会话Null Session**还能匿名枚举用户列表

**Q7SMB  NFS 怎么选**
A看客户端 OS 和文件语义需求**SMB**Windows 原生支持NTFS ACL 细粒度权限**强制锁语义严格**ShareAccess 冲突检测)、缓存一致性强Lease 回调)、**SMB3 内置 AES 加密和 Kerberos 开箱即用****NFS**POSIX 语义原生mode 硬链接区分大小写可删除已打开文件)、Linux 内核态实现大文件顺序 I/O K8s 生态支持好** Windows 客户端就选 SMB Linux 就选 NFS**安全性上 SMB3 明显优于默认配置的 NFSAUTH_SYS 形同虚设)。

**Q8什么是 SMB Multichannel**
ASMB3.0 的特性——**一个 SMB 会话可以同时使用多条 TCP 连接**跨多张网卡或在支持 RSS 的单网卡上开多条连接)。客户端通过 `FSCTL_QUERY_NETWORK_INTERFACE_INFO` 发现服务器的网卡列表然后建立多条通道收益有三:① **带宽聚合**双万兆口可跑 20Gbps);② **CPU 多核并行**单条 TCP 受限于单核);③ **链路故障自动切换**无需网卡组队)。 `Get-SmbMultichannelConnection` 查看是否生效

**Q9为什么 SMB 传大量小文件很慢**
A每个文件都需要 `CREATE`  `QUERY_INFO`  `READ`  `CLOSE` 多次交互虽然 SMB2 **复合请求**能把这些打包进一个 TCP 报文 SMB1 好很多),但文件数量本身带来的开销无法消除——1 万个小文件就是至少 1 万次往返**这不是调参能解决的**缓解手段打包成压缩文件传输使用 Lease 句柄缓存H )、减少单目录文件数高延迟链路考虑用 robocopy 的多线程模式`/MT:32`)。

**Q10NTLM Relay 攻击是怎么回事SMB 签名如何防御**
ANTLM **挑战-响应**认证**不绑定通信信道**攻击者诱使受害者向自己发起 SMB 连接 UNC 路径注入LLMNR/NBT-NS 投毒),然后把收到的 NTLM 认证消息**原样转发**到真正的目标服务器从而以受害者身份登录——攻击者全程不需要知道密码**SMB 签名**的防御原理是签名密钥由**会话密钥**派生而会话密钥与具体的认证会话绑定中继者拿不到会话密钥就无法为后续报文生成正确签名连接会被拒绝因此**强制 SMB 签名 + 禁用 NTLM改用 Kerberos+ 关闭 LLMNR/NBT-NS** 是标准防御组合