オフィスでは動くのに自宅ではタイムアウトするマップ済みドライブは、それ自体ではほとんど役立つ情報を与えない。トンネルがパケットを運んでいるのは明らかで、そうでなければサーバーに何も届かない。失敗したのは三つの層の一つだ。名前が誤ったアドレスに解決されたか、クライアントがセッションへの署名を拒否したか、古いセッションが接続より長く生き残ったかである。修復方法はそれぞれ異なり、三つのうち二つはクライアント側にある。

三つの不具合が同じエラーをまとう

ドライブ文字はどの層が壊れたかを教えず、エラー文はたいてい三つすべてに当てはまるほど一般的だ。二つの短い質問で切り分ける。サーバーは自分のIPアドレスで応答するか、ポート445は接続を受け付けるか。

その答えは推測ではなく判断表になる。IPは通り名前が通らないなら名前解決、両方通るのにログオンが拒否されるなら署名、両方通るのにトンネル断の後にファイル読み取りが止まるなら古いセッションを指す。

SymptomLayer to inspect
IP works, hostname times outDNS or subnet overlap
TCP 445 opens, logon refusedSMB signing policy
Hangs after reconnectSession state and timers

その順に確認する。誤ったホストに解決される名前は、以降のどのテストも無意味にするからだ。

共有に触れる前に名前を解決する

サーバーが自分のアドレスで応答し、共有名がタイムアウトするなら、トンネルは仕事をしており、クライアントが場所を間違えている。リモートアクセスでは、その大半を二つの原因が説明する。

一つ目はアドレスの重複だ。オフィスが 192.168.70.0/24 を使い、家庭のルーターが同じ範囲を配ると、192.168.70.20 に解決されるホスト名が、トンネルの先のサーバーではなくローカル機器を指すことがある。Windows は要求をローカルに送るか、経路を拒否するか、たまたまそのアドレスを持つプリンターに解決してしまう。直すのは片側の再採番であり、別の経路を足すことではない。

二つ目は DNS の範囲だ。内部 DNS サーバーを持たない、またはトンネル経由で到達できない DNS を使う VPN アダプターでは、短い名前が公開リゾルバーに流れる。共有に触れる前に、アダプターの DNS エントリを読み、内部名を直接問い合わせる。

> ipconfig /all | findstr /i "DNS Servers"
> nslookup files.corp.internal
Server: 10.90.0.2
Address: 10.90.0.2
Name: files.corp.internal
Address: 10.90.0.15

その問い合わせが期待どおりのアドレスを返せば、名前解決は片づき、問題はスタックの上にある。

両端で署名の要件を読む

到達できるのにすべてのログオンを拒否するサーバーは、ネットワーク障害ではなくポリシーの不一致の印だ。Windows はクライアント側に SMB 署名を要求でき、署名しないサーバーや NAS は、トンネルがどれほど健全でもセッションを完了できない。

ポリシーエディターを探さずにクライアント設定を読める。

> Get-SmbClientConfiguration | Select-Object RequireSecuritySignature
RequireSecuritySignature
-------------------------
True
> Get-SmbConnection

サーバー側の対応する値はサーバーの SMB 構成にあり、両者が一致していなければならない。報告された一例では、クライアントがローカルポリシーで要件を有効にしていた一方、サーバーはまったく署名していなかった。要件を無効にして gpupdate /force を実行すると、共有はすぐに復旧した。これは原因を確認するための診断手順であり、恒久的な修正ではない。

サーバーが対応している場合は、両端で署名を有効にすることを優先する。共有を動かすためにセキュリティ設定を変えるなら、以前の値と理由を記録しておき、次の監査で誰も再発見しなくて済むようにする。

タイマーを調整する前に古いセッションを消す

VPN が切れて再接続した後にだけ止まる共有は、たいていサーバーがすでに破棄したセッションを保持している。サーバーは LanmanServer\Parameters 配下の Autodisconnect タイマーでアイドル状態の SMB セッションを閉じる。既定は 15 分で、クライアントは LanmanWorkstation\Parameters 配下に独自の SessTimeout を持つ。これらの値を超える切断は、両端でセッションの認識を食い違わせる。

結果に意味を持たせるため、決まった順序で再現する。トンネルを接続し、共有を開き、二分間トンネルを切り、復旧させ、それからファイルを読んでみる。マウントが自然に戻るならタイマーは触らない。再マウントするまで止まるなら、トンネルが上がってから共有を再接続する。トンネルが存在する前にマウントするのではなく、マウントヘルパーが再試行するかも確認する。

不安定な回線ではタイムアウトを延ばすのが妥当な最後の一手だが、それは対症療法だ。サーバーが忘れたセッションを長く待つクライアントは、依然として待ち続ける。

最後に、マウント経由でファイルを一つ読み、もう一度トンネルを切って復旧させる。その受け入れテストは三つの層を一度に覆い、利用者の実際の操作と一致する唯一のテストだ。

関連記事