SMB小傳 —— SMB網路檔案系統協議介紹

SMB小傳 —— SMB網路檔案系統協議介紹

SMB網路檔案系統協議, 全名伺服器訊息塊(Server Message Block),曾用名CIFS(通用網際網路檔案系統 Common Internet File System), 公元1983年誕生於IBM[1],幼年得到英特爾和微軟的照料,最終在微軟的培養下成長為當今世上網路檔案系統協議兩極之一的存在。本文就來聊聊SMB的生平二三事。

一、未曾停下的演進

作為一個誕生在谷歌、亞馬遜、雅虎、甚至思科都不曾存在的網際網路“遠古”時代[2]的網路協議,SMB的早期版本(SMB 1.0/CIFS,以下簡稱SMB1)在不停地修修補補中卻也漸漸無法適應現代的網路環境了。如今的網際網路已經不再簡單不再純粹,網際網路上儲存著海量的資料並還在快速生產新資料,執行著各式各樣的網路應用,也同樣充斥著的無處不在的惡意攻擊。

SMB1協議有太多的缺點,除了近期在2017年因為WannaCry病毒事件而再次暴露出來的巨大安全漏洞之外,便是SMB1協議特性導致了其對於網路資源的巨大耗費以及在遠距通訊場景下極差的效能。SMB1顯著的效能問題還使得CIFS加速器成為了WAN加速類產品[3]的必備元件,思科、riverbed等公司都研發過此類功能,當然這些都是題外話了。對於SMB1的種種不足和為什麼要停止使用SMB1,微軟SMB專案的負責人Ned Pyle已經有了清晰的訴說[45],本文便不再贅述了。

下面(表-1),本文列表總結了SMB協議各個版本的釋出時間以及各版本所帶來的重要協議特性。可以看到,從1983年到2007年這整整24年中,SMB作為一個網路檔案系統的基本功能已經比較完整了,各種檔案系統操作、使用者認證、訊息簽名、客戶端快取等等的功能都有,更是取消了對NetBIOS協議層的依賴從而直接使用445埠執行在TCP/IP之上。至於為何SMB在1996年一度改名為CIFS呢?那都是源於微軟面對Sun公司的NFS(Network File System)協議面向Web服務的擴張(WebNFS),而進行的一次失敗的IETF網路檔案系統標準化嘗試[6],對此本文不多作細說。不過這一次改名導致了人們現在有時也會以CIFS來稱呼SMB協議,而在Linux平臺的SMB客戶端甚至一直保持了CIFS的命名。

隨著網際網路產業的快速發展,SMB堪憂的安全性和愈發跟不上時代的效能使得微軟不得不對SMB協議進行大刀闊斧的修訂,並在2007年釋出了SMB 2.0。仔細觀察就會發現,SMB 2.X和SMB 3.X帶來的眾多新特性基本都是是圍繞著增加安全性和提升效能這兩個主題來設計的。

SMB版本 年代 相應作業系統版本 重要協議特性
SMB 3.1.1 2015 Windows 10

Windows Server 2016

– 傳輸加密演算法協商
– 預認證完整性檢查(pre-authentication integrity)
SMB 3.0.2 2013 Windows 8.1

Windows Server 2012 R2

– 客戶端直讀直寫請求
– SMB Direct(RDMA)效能改進
SMB 3.0 2012 Windows 8

Windows Server 2012

– 目錄級元資料客戶端快取(directory lease)
– 持久控制代碼(persistent handle)
– 基於AES-CCM演算法的資料傳輸加密
– 訊息簽名(message signing)改用AES-CMAC演算法
– SMB Direct(RDMA)支援
– 多通道(multi-channel)
SMB 2.1 2009 Windows 7

Windows Server 2008 R2

– 基於Lease的檔案資料客戶端快取
– 多協議版本支援協商(multi-protocol negotiate)
– 彈性控制代碼(resilient handle)
SMB 2.0.2 2008 Windows Vista SP1

Windows Server 2008

– SMB指令數量減至19個
– 基於信用點(credit)的流控機制
– 改進複合請求機制(request compounding)
– 耐用控制代碼(durable handle)
– 訊息簽名(message signing)改用SHA-256演算法
– 支援軟連結(symbolic link)
– 提升最大資料塊尺寸(maximum block size)
SMB 2.0 2007 Windows Vista
======================== 時代的分割線 ========================
SMB 1.0/CIFS 2000 Windows 2000 – 包含100+指令的指令集
– 開啟(open)、讀(read)、修改(modify)、關閉(close)等檔案操作
– 取消(cancel)操作
– 直接運行於TCP/IP協議之上(Direct hosting of SMB over TCP/IP)
– 查詢、設定檔案和卷屬性(attributes)
– 基於NTLM、Kerbeors等協議的使用者認證
– 基於MD5演算法的訊息簽名(message signing)
– 基於機會鎖(opportunistic lock / oplock)的檔案資料客戶端快取
CIFS 1996 Windows NT 4.0
早期SMB 1983 MS-DOS

OS/2

表-1 SMB協議版本歷史與重要特性[7]

然而,如果使用者們想要真正用上新版SMB協議帶來的新特性,就必須保證SMB客戶端和SMB服務端都能夠支援帶有該特性的協議版本。更因為微軟並不支援向舊版Windows系統移植新版的SMB客戶端或服務端程式,使用者只能更新作業系統之後才能夠體驗更新的SMB特性。在表-2中,我們列出了不同Windows系統組合之間所能夠支援的最高的SMB版本以供參考。

Windows版本
Windows 10
WS 2016
Windows 8.1
WS 2012 R2
Windows 8
WS 2012
Windows 7
WS 2008 R2
Windows Vista
WS 2008
更早版本
Windows 10
WS 2016
SMB 3.1.1
SMB 3.0.2
SMB 3.0
SMB 2.1
SMB 2.0.2
SMB 1
Windows 8.1
WS 2012 R2
SMB 3.0.2
SMB 3.0.2
SMB 3.0
SMB 2.1
SMB 2.0.2
SMB 1
Windows 8
WS 2012
SMB 3.0
SMB 3.0
SMB 3.0
SMB 2.1
SMB 2.0.2
SMB 1
Windows 7
WS 2008 R2
SMB 2.1
SMB 2.1
SMB 2.1
SMB 2.1
SMB 2.0.2
SMB 1
Windows Vista
WS 2008
SMB 2.0.2
SMB 2.0.2
SMB 2.0.2
SMB 2.0.2
SMB 2.0.2
SMB 1
更早版本
SMB 1
SMB 1
SMB 1
SMB 1
SMB 1
SMB 1

表-2 SMB協議版本歷史與重要特性 (* WS = Windows Server)

二、一次完整的SMB會話

簡單地聊完SMB的演進之後,本小節再來簡述一下SMB的網路報文格式以及一個典型SMB會話的各個生命階段。本節講述關於SMB2和SMB3相關的協議內容,對於已經被摒棄的SMB1協議便略去不提了。

SMB報文格式

圖-1詳細展示了SMB2和SMB3的報文頭部結構,對這些技術細節不感興趣的讀者可跳過本節。至於每個單獨的SMB指令的報文格式便不在本文中展開了,有興趣的讀者可自行翻閱MS-SMB2協議文件。細心的讀者可能會好奇,為什麼SMB3沒有獨立的協議文件呢?一則SMB2和SMB3在報文格式上並沒有太大差異,並不需要單獨開一篇文件;二則,其實SMB 3.0在WIndows 8測試版階段還是命名為SMB 2.2的,但微軟工程師們經過再三考慮,認為以SMB3新增的程式碼之多、新特性之豐富,一個單獨的主版本號才是理所應當的[8]。

53871b85393eb26a08076ee37c74e2bf0dd1ecfb

圖-1 SMB報文格式

SMB會話的生命階段

如圖-2所示,一個普通的SMB會話從開始到結束一般會經過以下六個生命階段:

1. SMB協議協商(Negotiate)

在一個SMB還沒有開始的時候,由客戶端率先發出一個協商請求。在請求中,客戶端會列出所有它所支援協議版本以及所支援的一些特性(比如加密Encryption、持久控制代碼Persistent Handle、客戶端快取Leasing等等)。而服務端在回覆中則會指定一個SMB版本且列出客戶端與服務端共同支援的特性。

2. 建立SMB會話(Session Setup)

客戶端選擇一個服務端支援的協議來進行使用者認證,可以選擇的認證協議一般包括NTLM、Kerberos等。按照選擇的認證協議的不同,這個階段可能會進行一次或多次SESSION_SETOP請求/回覆的網路包交換。至於NTLM或Kerberos認證協議的細節,我們會另文再敘。

3. 連線一個檔案分享(Tree Connect)

在會話建立之後,客戶端會發出連線檔案分享的請求。源於檔案系統的樹形結構,該請求被命名為樹連線(Tree Connect)。以SMB協議的阿里雲NAS為例,一般的SMB掛載命令為:

net use z: \\XXX.nas.aliyuncs.com\myshare

其中的“ \\XXX.nas.aliyuncs.com\myshare”便是我們將要連線的那個檔案分享,也便是那棵“樹”。如果在“myshare”中建立有子目錄“abc”,那直接連線“abc”這棵子樹也是可以的:

net use z: \\XXX.nas.aliyuncs.com\myshare\abc

4. 檔案系統操作

在檔案分享連線成功之後,使用者通過SMB客戶端進行真正的對於目標檔案分享的業務操作。這個階段可以用到的指令有CREATE、CLOSE、FLUSH、READ、WRITE、SETINFO、GETINFO等等。

5. 斷開檔案分享連線(Tree Disconnect)

當一個SMB會話被閒置一定時間之後,Windows會自動斷開檔案分享連線並隨後中止SMB會話。這個閒置時間可以通過Windows登錄檔進行設定[ 9 ]。當然,使用者也可以主動發起斷開連線請求。

6. 終止SMB會話(Logoff)

當客戶端發出會話中止請求並得到服務端發回的中止成功的回覆之後,這個SMB會話至此便正式結束了。

3b9bdee70e94d9c5ddee54cb7d2ddcf145ea54df

圖-2 SMB會話的六個階段

三、現狀與展望

聊過了SMB的過往歷史和一小部分技術細節之後,本文再來說說關於SMB的一些其他的故事,也對SMB協議的未來做一個淺薄的展望。

與開源社群的恩怨情仇

雖然微軟長久以來主導著SMB協議標準的訂立與發展,是SMB協議的實質擁有者。不過我們無法忽視開源社群對SMB發展的貢獻。最早釋出於1992年的SAMBA則是開源界對SMB協議支援最完整也是使用者最多的專案。SAMBA是一個鬆散的開發者團隊,開發SAMBA本身並不會獲得收入或盈利,所以這個團隊的成員大多還有另一份謀以生計的正職工作[10]。在2018年6的微軟互操作研討會上[11],筆者便有幸遇到幾位SAMBA的開發者,他們中有SAMBA主要維護者,來自谷歌的Jeremy Allison和當時剛剛受聘于微軟的Linux CIFS客戶端開發者Steve French。表-3和表-4列出了歷年來SAMBA對在Unix/Linux平臺上支援SMB協議作出的努力和成績。

現在的微軟每年都會和開源社群的開發者們一起參加各種研討會,有微軟主辦的互操作研討會、全球網路儲存工業協會(SNIA,Storage Networking Industry Association)舉辦的儲存開發者大會等等。然而,早年的微軟和開源社群之間的關係並沒有現在這般和諧,甚至整個開源社群都曾將微軟視為頭號公敵。微軟和SAMBA之間也曾一度在歐洲對簿公堂[12]。但這些都在2010前後發生了轉變,微軟逐漸確立了其雲優先的公司路線,也逐漸以開放的心態來對待開源社群,時至今日,微軟已經成為了全球最大的開原始碼貢獻者之一了[13]。從2011年起,微軟便遵循GPL開源協議開始向SAMBA專案貢獻程式碼[14]。甚至其最近還收購了全球最大的開原始碼平臺Github。

SAMBA版本
釋出日期
SMB協議支援版本
4.3.0
2015年9月
SMB 3.1.1
4.1.0
2013年10月
SMB 3
3.6.0
2011年8月
SMB 2
3.5.0
2010年3月
SMB 2(實驗性支援)

表-3 SAMBA對SMB協議的支援(SMB服務端)[15]

Linux核心版本
釋出日期
Linux CIFS重要更新內容
4.17
2018年6月
支援SMB 3.1.1
4.13
2017年9月
預設SMB協議版本由SMB1改為SMB3
4.11
2017年4月
支援SMB DFS; 支援SMB3傳輸加密
3.12
2013年11月
支援SMB 3.0.2
3.8
2013年2月
支援SMB 2.0.2
3.7
2012年12月
支援SMB 2.1
2.5.42
2002年10月
以核心模組形式新增CIFS虛擬檔案系統

表-4 Linux核心對SMB協議的支援(SMB客戶端)[16]

兼收幷蓄是未來

雖然很多人知道,Windows可以連線NFS協議的檔案分享,Linux上也可以掛載SMB協議的網路儲存。但是大家也都普遍認為,這種“跨平臺”的網路檔案系統會有很多不可知的問題,效能也不好。在過去的很長的一段時間裡,也確實大致如此。

不過隨著近年來微軟和開源社群,特別是和SAMBA的緊密合作,Unix/Linux平臺上對SMB協議的支援已經比較完整了,功能和效能上都有了長足的進步。特別是近期在Linux 4.18核心版本中,CIFS客戶端增加了SMB 3.1.1版協議對POSIX extension的實驗性支援[17]。一直以來,Windows和POSIX的檔案系統語義相容都是阻礙使用者跨平臺(Windows、Linux、MAC等)進行檔案訪問的阻礙。在雲端計算大發展的當下,Linux系統和Windows系統分別統治消費者市場[18]和伺服器市場[19],資料和檔案的跨平臺訪問會是一個可以預見的強大需求。而隨著SMB POSIX extension的到來,必將使SMB協議在跨平臺的網路檔案訪問上得以大展身手。在今天,主要的雲端計算廠商幾乎都已經推出了雲上的檔案儲存服務,使用者一般可以使用SMB或者NFS協議來掛載訪問這些雲檔案儲存,本文也對各家廠商對SMB和NFS的協議支援情況做了個簡單總結(見表-5)供讀者參考。

雲廠商
產品
SMB​協議支援
NFS協議支援
阿里雲
檔案儲存 NAS
SMB2,SMB3
NFS3,NFS4
​亞馬遜AWS
EFS
X
NFS4
FSx for Windows File Server
SMB2, SMB3
X
微軟Azure
File Storage
SMB3
X
谷歌GCP
Filestore
X
NFS3
騰訊雲
檔案儲存 CFS
SMB1, SMB2, SMB3
NFS3, NFS4
華為雲
彈性檔案服務 SFS
X (即將上線)
NFS3
*表中資料收集自2018年11月29日

表-5 主要雲廠商檔案儲存產品對SMB和NFS協議的支援

四、寫在最後

隨著儲存行業的發展,雲檔案儲存也會向跨地域大叢集的方向發展,如SMB、NFS之類的網路檔案系統協議為了不被淘汰出歷史舞臺,也必然會做出更多的改變。SMB的故事還會繼續,我們且繼續關注。

參考資料

[1] Myths about Samba
[2] History of the Internet
[3] CIFS acceleration techniques
[4] Stop Using SMB1
[5] 禁用SMB1協議
[6] Common Internet File System Protocol (CIFS/1.0)
[7] MS-SMB2
[8] SMB 2.2 is now SMB 3.0
[9] SMB timeout
[10] Samba team
[11] Redmond Interoperability Plugfest 2018
[12] Samba and the PFIF
[13] Microsoft open source
[14] Microsoft contributes open source code to samba
[15] SAMBA release History
[16] Linux CIFS Kernel
[17] POSIX extension
[18] Desktop OS market share