エクスプローラーで \\fs01\営業資料\見積.xlsx をダブルクリックすると、一瞬でファイルが開きます。その裏では、PCとファイルサーバの間でいくつものやり取りが順番に行われています。この流れを知っておくと、「共有フォルダに入れない」「アクセスが拒否された」といったトラブルのとき、どこで止まっているのかを切り分けられるようになります。この記事では、SMBで共有フォルダのファイルを開くまでの流れを、6つのステップに分けて見ていきます。
- 共有フォルダのファイルを開くまでの6つのステップ
- 各ステップで決まること・確かめられること
- どのステップで失敗したかの見分け方
全体像:6つのステップ
SMBのやり取りは、大きく次の6つのステップで進みます。ホテルの部屋に入って書類を取り出すまでの流れにたとえると、イメージしやすいかもしれません。
実際のやり取りを、DNSとKerberosのやり取りも含めて並べると、次のようになります。
以下、ステップごとに中身を見ていきます。
① 名前解決とTCP接続
最初に、PCは接続先の名前(fs01.corp.example.com)をDNSに問い合わせて、IPアドレスを調べます。次に、そのIPアドレスのTCP 445番ポートに接続します。ここまではSMBではなく、ふつうのTCP/IPの通信です。
ここで失敗すると、「ネットワーク パスが見つかりません」のようなエラーになります。名前が引けない、途中のファイアウォールで445番が止められている、サーバのServerサービスが止まっている、といった原因が考えられます。
② Negotiate:話し方を決める
TCPでつながったら、最初のSMBのメッセージとして NEGOTIATE を送ります。PCは使えるバージョン(2.0.2〜3.1.1)や機能の一覧を送り、サーバは両方が使えるいちばん新しいバージョンを選んで返します。
| 決まること | 内容 |
|---|---|
| バージョン | 使うSMBのバージョン(今のWindows同士なら3.1.1) |
| 機能 | マルチチャネル、DFS、暗号化、大きなデータの読み書きなど、両方が使える機能 |
| 署名の要否 | 署名を使えるか、必須か(SecurityMode) |
| 暗号の方式(3.1.1) | 暗号化の方式(AES-128-GCMなど)、署名の方式(AES-128-GMACなど)、圧縮の方式 |
| 認証の方式の候補 | サーバが受け付ける認証の方式(KerberosやNTLM)の一覧。次のSession Setupで使う |
NegotiateとSession Setupのメッセージは、まだ暗号化も署名もされていない状態でやり取りされます。もし途中で書き換えられて、古いバージョンや弱い方式に落とされたら困ります。そこでSMB 3.1.1では、これらのメッセージを順につなげたハッシュ(SHA-512)を両者が計算し、その値を使って署名や暗号化の鍵を作ります。途中で1か所でも書き換えられていると両者の鍵が合わなくなるので、改ざんに気づけます。この機能は「事前認証の完全性」と呼ばれ、3.1.1では必ず使われます。
③ Session Setup:だれなのかを確かめる
次は認証です。PCは SESSION_SETUP というメッセージの中に認証データを入れて送ります。この認証データは、SMBが自分で作るのではなく、WindowsのSSPIとSSP(Kerberos や NTLM の担当)が作ったものです。SMBは中身を知らずに運ぶだけです。
| 方式 | 流れ |
|---|---|
| Kerberos | PCは事前にDCから cifs/fs01.corp.example.com のサービスチケットをもらっておき、それを1回目の SESSION_SETUP で渡す。サーバは自分の鍵でチケットを開いて本人を確かめ、成功を返す |
| NTLM | 1回目でNTLMを使うことを伝えると、サーバは「続きがある」(STATUS_MORE_PROCESSING_REQUIRED)とチャレンジを返す。2回目でチャレンジへの応答を送ると、サーバはDCに確認してから結果を返す |
認証に成功すると、次のものが決まります。
- SessionId:このPCとユーザーの組み合わせを表す番号。以降のメッセージに付けて送る
- セッションキー:認証のときに両者が手に入れる共通の鍵。ここから署名用や暗号化用の鍵を作る
- アクセストークン:サーバは、認証された利用者のアクセストークンを自分で作る。このあとのアクセス許可の確認に使う
SMB 3.1.1では、認証が成功したことを伝える最後の応答に、必ず署名が付きます。署名が付いていなければ、PCは接続を失敗にします。ここで失敗すると、「ユーザー名またはパスワードが正しくありません」(STATUS_LOGON_FAILURE)などのエラーになります。
④ Tree Connect:どの共有を使うか
認証が済んだら、TREE_CONNECT で使いたい共有(\\fs01\営業資料)を伝えます。サーバはここで、共有のアクセス許可(共有の設定画面の「アクセス許可」)を確かめます。通れば、この共有を表す番号(TreeId)が返されます。
応答には、その共有の性質も入っています。たとえば、この共有では暗号化が必須か、DFSの共有か、といった情報です。共有が見つからなければ STATUS_BAD_NETWORK_NAME、共有のアクセス許可で拒否されれば STATUS_ACCESS_DENIED になります。
なお、同じユーザーで同じサーバの別の共有を開くときは、①〜③をやり直さず、今あるセッションの上で TREE_CONNECT だけを行います。
⑤ Create・Read・Write:ファイルを操作する
共有に入れたら、ファイルを開きます。SMBでは、ファイルを開く操作を CREATE と呼びます(新しく作るときだけでなく、既存のファイルを開くときも CREATE です)。サーバはここで、NTFSのアクセス許可(ファイルのプロパティの「セキュリティ」タブ)と、③で作ったアクセストークンを照らし合わせます。通れば、開いたファイルを表す番号(FileId)が返されます。
あとは FileId を指定して READ(読む)や WRITE(書く)を繰り返し、終わったら CLOSE で閉じます。フォルダの中身を一覧で見るときは QUERY_DIRECTORY を使います。
| メッセージ | やること |
|---|---|
| CREATE | ファイルやフォルダを開く(または作る)。NTFSのアクセス許可を確かめる |
| READ / WRITE | ファイルの中身を読む・書く |
| QUERY_DIRECTORY | フォルダの中のファイルの一覧を取る |
| QUERY_INFO / SET_INFO | ファイルのサイズや日時などの情報を読む・変える |
| CLOSE | 開いたファイルを閉じる |
ほかの人がそのファイルを開いていて共有できない状態なら STATUS_SHARING_VIOLATION(「ほかのプロセスが使用中」)、NTFSのアクセス許可で拒否されれば STATUS_ACCESS_DENIED になります。
⑥ 後片付け
使い終わると、TREE_DISCONNECT で共有から離れ、LOGOFF でセッションを終えます。ただし、エクスプローラーを閉じてもすぐに切断されるとは限りません。WindowsのSMBクライアントは、しばらく接続を残しておき、次にアクセスしたときに使い回します。
どこで止まったかの見分け方
共有フォルダのトラブルは、どのステップで止まったかが分かると原因を絞り込めます。
| ステップ | よくある症状 | 確かめること |
|---|---|---|
| ① 名前・TCP | ネットワーク パスが見つからない | 名前が引けるか、TCP 445 に届くか |
| ② Negotiate | 古い機器につながらない、SMB1が必要というエラー | 相手がSMB2以降に対応しているか、バージョンの下限・上限の設定 |
| ③ Session Setup | パスワードを聞かれ続ける、ログオンに失敗する | 資格情報、Kerberosのチケット(SPN)、NTLMの遮断や署名の設定、ゲストでの接続になっていないか |
| ④ Tree Connect | 共有名が見つからない、共有に入れない | 共有名のつづり、共有のアクセス許可 |
| ⑤ Create | フォルダは見えるが、ファイルを開けない・保存できない | NTFSのアクセス許可、ほかの人が使用中でないか |
Wiresharkなどでキャプチャするときは、表示フィルターに smb2 を入れると、ここで紹介した NEGOTIATE、SESSION_SETUP、TREE_CONNECT、CREATE などのメッセージが順に並びます。各応答の Status 欄を見ると、どのメッセージで何のエラーが返ったかが分かります。暗号化された接続では、Session Setup のあとの中身は読めません。
確認に使うコマンド
PC(PowerShell):ファイルサーバの名前を引けるか確かめる
Resolve-DnsName fs01.corp.example.com
PC(PowerShell):ファイルサーバのTCP 445に届くか確かめる
Test-NetConnection -ComputerName fs01.corp.example.com -Port 445
PC(PowerShell):今のSMBの接続(サーバ、共有、ユーザー、バージョン)を表示する
Get-SmbConnection | Select-Object ServerName, ShareName, UserName, Dialect
PC(コマンドプロンプト):ファイルサーバ向けのKerberosのチケット(cifs/…)を持っているか確かめる
klist
ファイルサーバ(PowerShell・管理者):つながっているセッション(利用者とバージョン)を表示する
Get-SmbSession | Select-Object ClientComputerName, ClientUserName, Dialect, NumOpens
ファイルサーバ(PowerShell・管理者):開かれているファイルと、開いている利用者を表示する
Get-SmbOpenFile | Select-Object ClientUserName, Path
PC(コマンドプロンプト):SMBの接続を切って、次のアクセスで①からやり直させる
net use \\fs01.corp.example.com\営業資料 /delete
まとめ
| ステップ | ポイント |
|---|---|
| ① 名前解決・TCP接続 | DNSでIPアドレスを調べ、TCP 445につなぐ |
| ② Negotiate | バージョン、機能、署名や暗号化の方式を決める。3.1.1では改ざん検知のハッシュを計算し始める |
| ③ Session Setup | SSPが作った認証データを運んで認証する。Kerberosは1往復、NTLMは2往復。セッションキーとアクセストークンができる |
| ④ Tree Connect | 使う共有を伝え、共有のアクセス許可を確かめる |
| ⑤ Create・Read・Write | ファイルを開くときにNTFSのアクセス許可を確かめ、読み書きする |
| ⑥ 後片付け | 閉じて切断する。接続はしばらく残して使い回す |
「どのステップで止まっているか」を意識するだけで、ネットワークの問題なのか、認証の問題なのか、アクセス許可の問題なのかを分けて考えられるようになります。
- [MS-SMB2] 3.2.4.2 Application Requests a Connection to a Share(Microsoft Learn)
- [MS-SMB2] 4.3 Connecting to a Share by Using an SMB2 Negotiate(Microsoft Learn)
- [MS-SMB2] 2.2.5 SMB2 SESSION_SETUP Request(Microsoft Learn)
- [MS-SMB2] 3.3.5.5.3 Handling GSS-API Authentication(Microsoft Learn)
- [MS-SMB2] 3.2.5.3.1 Handling a New Authentication(Microsoft Learn)
- [MS-SMB2] 3.2.5.5 Receiving an SMB2 TREE_CONNECT Response(Microsoft Learn)
- SMB security enhancements(事前認証の完全性)(Microsoft Learn)
- Protect SMB traffic from interception(Microsoft Learn)
- SMB features in Windows and Windows Server(Microsoft Learn)
- Microsoft Negotiate(Microsoft Learn)
コメント