LinuxでSMBパケットをキャプチャしてダイアレクトのやりとりを見てみた。

Linux(ubuntu)からwindows10の共有フォルダにアクセスして、そのときに流れるSMBパケットをwiresharkでキャプチャしてみました。SMBのダイアレクトのやりとりを見るためです。ダイアレクトとはSMBのバージョン識別に使われるもので、ダイアレクトをやりとりしてどのバージョンのSMBでファイル共有をするかをサーバーとクライアントの双方で決めます。SMBのバージョンについては前回の記事を見てください。

ubuntuにはlibsmbclientがインストール済みです。libsmbclientというのはSMBのクライアントソフトです。windowsの共有フォルダにアクセスするにはlibsmbclientが必要です。

libsmbclientはubuntuをインストールしたときから入っているようです(libsmbclientを意図的にインストールした記憶がないので)。

ubuntuからwindowsの共有フォルダへのアクセスはubuntuのファイルアプリから行います。ファイルアプリを開き「他の場所」を選択し下部にある「サーバー接続」に「smb://windowsのIPアドレス」を入力して接続ボタンを押下します。

windowsログインのアカウント、ワークグループ、パスワードを求められたら入力してください。windows側の共有フォルダの設定によります。

そのときのSMBパケットをwiresharkでキャプチャしたものです。wiresharkのフィルタでプロトコルをSMBとSMB2のパケットに絞っています。SMBプロトコルはSMBのバージョンが1.0のもの、SMB2プロトコルはSMBのバージョンが2.0以降のものです。

キャプチャの結果を見てみるとSMBのネゴシエートプロトコルで4回のやりとりをしています。

・Negotiate Protocol Request(SMB)
・Negotiate Protocol Response(SMB2)
・Negotiate Protocol Request(SMB2)
・Negotiate Protocol Response(SMB2)

それぞれの内容を見てみます。まずは上から1つ目です。SMBでは445ポートを使っているようです。

SMBパケットの中にリクエストダイアレクトのブロックがあります。ubuntuからSMBで使用できるダイアレクトを提示しています。いくつかあるのですが調べたところ以下の意味です(わかったものだけですが)。

・NT LM 0.12 (SMB1.0の意味合い)
・SMB 2.002 (SMB2.0の意味合い)
・SMB 2.??? (SMB2.1以降の意味合い)

これに対しwindowsからのレスポンスが2つ目です。

ダイアレクトが0x02ffとなっています。ubuntuからwindowsへのリクエスト時は16進数を使っていなかったのですがレスポンス時は16進数になっています。そもそもSMBプロトコルでリクエストしたのにレスポンスはSMB2プロトコルになっています。これは接続元がSMB2.1以降に対応していて(ダイアレクトでSMB 2.???を提示していて)接続先もSMB2.1以降に対応していれば、SMB2プロトコルを使って改めてネゴシエートを行う仕様になっているからです。SMBのネゴシエートで4回のやりとりがあるのはこのためです。

3つ目のキャプチャ結果を見てみます。

ubuntuからwindowsに再度ダイアレクトを提示しています。16進数表示でいくつかあるのですがSMBのバージョンを表していると思われます。

・0x0202(SMB2.0の意味合い)
・0x0210(SMB2.1の意味合い)
・0x0300(SMB3.0の意味合い)
・0x0311(SMB3.1.1の意味合い)

最後に4つ目のキャプチャ結果です。

windowsでダイアレクトの0x0311を選択しています。windows10はSMB3.1.1に対応しているのでそれが選ばれたわけです。windowsのファイル共有ではSMBのネゴシエートでお互いに利用可能な最上位のバージョンを決めています。

windowsのネットワークプロトコル SMBとCIFSの違い。

SMB(Sever Message Block)はwindowsネットワークにおいて中心となるプロトコルですが、その歴史は長く今まで何度かのバージョンアップが行われています。CIFS(Common Internet File System)と比べる上でSMBの歴史が関わっているので、それを振り返ってみます。

SMBはMS-DOSの時代から存在していましたがwindowsに標準で搭載されたのはwindows 95、windows NTからになります。1995年のことです。

その当時、マイクロソフトはSMBをネットワークプロトコルの標準にしたいと考えたらしく、1997年にSMBの標準化案をIETF(Internet Engineering Task Force)に提出しました。windowsだけでなく他のOSでも使うことを想定し仕様を公開したプロトコルがCIFSです。そしてマイクロソフトはCIFSを自ら実装してwindows 2000に取り入れています。これがSMBの完成形となり、SMB 1.0と呼ばれています。そのためSMB 1.0とCIFSは同じものと考えて良いです。

その後、SMBは2.0、3.0とさらに進化していきます。どのような機能が追加されたかは割愛しますが、ネットワーク機能の強化ということで、その後のwindows OSには採用されています。

一方のCIFSですが、IETFに提案がされたものの標準化には至っておらず、またバージョンアップの提案もなされていません。

改めてSMBとCIFSの違いを言うと、CIFSはSMBと同じではなく、CIFSはあくまでもSMBの一時代のバージョンと同じということです。SMB 1.0がCIFSのことですが、SMB 1.0はwindows 2000からwindowsXPやwindows Server 2003 R2までの長い期間採用されています。

[2021/4/15 追記]
Linuxから見たSMBについて記載しておきます。LinuxのSMBをサポートするカーネルモジュールはcifs.soなのですが、このcifs.soはバージョンによってサポートするSMBが異なるようです。

RHEL(CentOS) 6系
⇒ SMB 1.0 をサポートする

RHEL(CentOS) 7系
⇒ SMB 2.0、2.1、3.0 をサポートする

RHEL(CentOS) 8系
⇒ SMB 2.0、2.1、3.0、3.1.1 をサポートする