ポートの枯渇に関する問題のトラブルシューティング

適用対象: Windows 10

TCP および UDP プロトコルは、接続の確立に使用されるポート番号に基づいて機能します。 TCP/UDP 接続を確立する必要があるアプリケーションまたはサービスでは、その側にポートが必要です。

ポートには次の 2 種類があります。

  • エフェメラル ポート (動的ポート) は、すべてのマシンが既定で送信接続を行う必要があるポートのセットです。
  • 既知のポートは、特定のアプリケーションまたはサービスに対して定義されたポートです。 たとえば、ファイル サーバー サービスはポート 445、HTTPS は 443、HTTP は 80、RPC は 135 です。 カスタム アプリケーションには、独自のポート番号も定義されます。

アプリケーションまたはサービスとの接続が確立されている場合、クライアント デバイスはデバイスからのエフェメラル ポートを使用して、そのアプリケーションまたはサービスに対して定義されている既知のポートに接続します。 クライアント マシン上のブラウザーでは、エフェメラル ポートを使用して、ポート 443 で に https://www.microsoft.com 接続します。

同じブラウザーが複数の Web サイトへの多数の接続を作成しているシナリオでは、ブラウザーが試行している新しい接続に対して、エフェメラル ポートが使用されます。 しばらくすると、接続が失敗し始め、このエラーの可能性が高くなる可能性が 1 つあります。これは、ブラウザーが使用可能なすべてのポートを使用して外部に接続を行い、使用可能なポートがなくなったため、接続を確立するための新しい試行が失敗するためです。 マシン上のすべてのポートが使用されると、ポート枯渇と呼ばれます。

TCP/IP の既定のダイナミック ポート範囲

インターネット割り当て番号機関 (IANA) の推奨事項に準拠するために、Microsoft は送信接続の動的クライアント ポート範囲を増やしました。 新しい既定の開始ポートは 49152 で、新しい既定のエンド ポートは 65535 です。 この増加は、既定のポート範囲 1025 から 5000 を使用した以前のバージョンの Windows の構成からの変更です。

netsh のコマンドを使用して、コンピューター上の動的ポート範囲を表示できます。

  • netsh int ipv4 show dynamicport tcp
    
  • netsh int ipv4 show dynamicport udp
    
  • netsh int ipv6 show dynamicport tcp
    
  • netsh int ipv6 show dynamicport udp
    

範囲は、トランスポート (TCP または UDP) ごとに個別に設定されます。 ポート範囲は、開始点と終了ポイントを持つ範囲になりました。 Windows Server を実行しているサーバーを展開する Microsoft のお客様は、ファイアウォールが内部ネットワークで使用されている場合、サーバー間の RPC 通信に影響する問題が発生する可能性があります。 このような状況では、49152 から 65535 のダイナミック ポート範囲のサーバー間のトラフィックを許可するようにファイアウォールを再構成することをお勧めします。 この範囲は、サービスとアプリケーションによって使用される既知のポートに加えてです。 または、サーバーによって使用されるポート範囲は、各サーバーで変更できます。 この範囲は、次のように netsh コマンドを使用して調整します。 上記のコマンドは、TCP のダイナミック ポート範囲を設定します。

netsh int <ipv4|ipv6> set dynamic <tcp|udp> start=number num=range

開始ポートは数値で、ポートの合計数は範囲です。 コマンドの例を次に示します。

  • netsh int ipv4 set dynamicport tcp start=10000 num=1000
    
  • netsh int ipv4 set dynamicport udp start=10000 num=1000
    
  • netsh int ipv6 set dynamicport tcp start=10000 num=1000
    
  • netsh int ipv6 set dynamicport udp start=10000 num=1000
    

これらのサンプル コマンドは、ポート 10000 から開始し、ポート 10999 (1000 ポート) で終了するようにダイナミック ポート範囲を設定します。 設定できるポートの最小範囲は 255 です。 設定できる最小開始ポートは 1025 です。 最大エンド ポート (構成されている範囲に基づく) は、65535 を超えることはできません。 Windows Server 2003 の既定の動作を複製するには、開始ポートとして 1025 を使用し、TCP と UDP の両方の範囲として 3976 を使用します。 この使用パターンにより、開始ポートは 1025、エンド ポートは 5000 になります。

具体的には、受信接続としての送信接続については、接続を受け入れるためにエフェメラル ポートは必要ありません。

送信接続が失敗し始めたので、次の動作の多くのインスタンスが表示されます。

  • ドメイン資格情報を使用してマシンにサインインできませんが、ローカル アカウントでのサインインは機能します。 ドメイン サインインでは、認証のために DC に接続する必要があります。これは、もう一度送信接続です。 キャッシュ資格情報が設定されている場合は、ドメイン サインインが引き続き機能する可能性があります。

    イベント ビューアーの NETLOGON のエラーのスクリーンショット。

  • グループ ポリシー更新エラー:

    グループ ポリシーエラーのイベント プロパティのスクリーンショット。

  • ファイル共有にアクセスできません。

    Windows がアクセスできないというエラー メッセージのスクリーンショット。

  • 影響を受けるサーバーからの RDP が失敗します。

    リモート デスクトップが接続できない場合のエラーのスクリーンショット。

  • マシン上で実行されている他のアプリケーションは、エラーを出し始めます

サーバーを再起動すると一時的に問題が解決されますが、一定の時間が経過するとすべての症状が返されます。

マシンがポート枯渇状態にあると思われる場合:

  1. 送信接続を作成してみてください。 サーバー/マシンから、リモート共有にアクセスするか、別のサーバーへの RDP またはポート上のサーバーへの telnet を試します。 これらのすべてのオプションで送信接続が失敗した場合は、次の手順に進みます。

  2. イベント ビューアーを開き、システム ログの下で、現在の状態を明確に示すイベントを探します。

    1. イベント ID 4227

      イベント ビューアーのイベント ID 4227 のスクリーンショット。

    2. イベント ID 4231

      イベント ビューアーのイベント ID 4231 のスクリーンショット。

  3. サーバーから出力を netstat -anob 収集します。 netstat 出力には、1 つの PID のTIME_WAIT状態に関する膨大な数のエントリが表示されます。

    netstate コマンド出力のスクリーンショット。

    正常な終了またはセッションの突然の終了の後、4 分 (既定値) の期間が経過すると、プロセスまたはアプリケーションによって使用されるポートが使用可能なプールに解放されます。 この 4 分間、TCP 接続状態はTIME_WAIT状態になります。 ポートの枯渇が疑われる状況では、アプリケーションまたはプロセスは、使用したすべてのポートを解放できず、TIME_WAIT状態のままです。

    また、CLOSE_WAIT状態の接続が同じ出力に表示される場合もあります。ただし、CLOSE_WAIT状態は、TCP ピアの一方の側に送信するデータ (FIN 送信) がなくなったが、もう一方の側からデータを受信できる場合の状態です。 この状態は、必ずしもポートの枯渇を示すわけではありません。

    注:

    TIME_WAIT状態の巨大な接続がある場合、最初の 2 つのポイントが検証されない限り、サーバーが現在ポートから外れているとは限りません。 TIME_WAIT接続が多いということは、プロセスによって多数の TCP 接続が作成され、最終的にポートが枯渇する可能性があることを示しています。

    Netstat はWindows 10で更新され、スイッチが追加-Qされ、BOUND 状態のように時間切れ待機状態に遷移したポートが表示されます。 この機能を含む Windows 8.1 および Windows Server 2012 R2 の更新プログラムがリリースされました。 Windows 10の PowerShell コマンドレットGet-NetTCPConnectionには、これらの BOUND ポートも表示されます。

    2016 年 10 月まで、netstat は不正確でした。 2012 R2 にバックポートされた netstat の修正。Netstat.exe を許可しGet-NetTcpConnection、Windows Server 2012 R2 で TCP または UDP ポートの使用状況を正しく報告します。 詳細については、「Windows Server 2012 R2: エフェメラル ポート修正プログラム」を参照してください。

  4. 管理者モードでコマンド プロンプトを開き、次のコマンドを実行します。

    Netsh trace start scenario=netconnection capture=yes tracefile=c:\Server.etl
    
  5. ネットワーク モニターserver.etl ファイルを開き、フィルター セクションでフィルターを適用しますWscore_MicrosoftWindowsWinsockAFD.AFD_EVENT_BIND.Status.LENTStatus.Code == 0x209STATUS_TOO_MANY_ADDRESSESというエントリが表示されます。 エントリが見つからない場合でも、サーバーはポートから外れられません。 見つかると、サーバーがポート枯渇していることを確認できます。

ポートの枯渇のトラブルシューティング

重要なのは、すべてのポートを使用しているプロセスまたはアプリケーションを特定することです。 1 つのプロセスに分離するために使用できるツールの一部を次に示します

方法 1

まず、netstat の出力を確認します。 Windows 10またはWindows Server 2016を使用している場合は、コマンドnetstat -anobqを実行し、BOUND として最大エントリを持つプロセス ID に対してチェックできます。 または、次の PowerShell コマンドを実行して、プロセスを特定することもできます。

Get-NetTCPConnection | Group-Object -Property State, OwningProcess | Select -Property Count, Name, @{Name="ProcessName";Expression={(Get-Process -PID ($_.Name.Split(',')[-1].Trim(' '))).Name}}, Group | Sort Count -Descending 

ほとんどのポート リークは、エラーが発生したときにユーザー モード プロセスがポートを正しく閉じなかったために発生します。 ユーザー モード レベルでは、ポート (実際にはソケット) はハンドルです。 TaskManagerProcessExplorer の両方でハンドル数を表示できるため、すべてのポートを使用しているプロセスを特定できます。

Windows 7 および Windows Server 2008 R2 の場合は、上記のコマンドレットを含むように PowerShell バージョンを更新できます。

方法 2

方法 1 でプロセスを識別できない場合 (Windows 10前に R2 をWindows Server 2012)、タスク マネージャーを確認します。

  1. 詳細/プロセスの下に"ハンドル" という名前の列を追加します。

  2. 列ハンドルを並べ替えて、ハンドルの数が最も多いプロセスを識別します。 通常、3000 を超えるハンドルを持つプロセスは、System、 lsass.exe、store.exesqlsvr.exeなどのプロセスを除き、 原因となる可能性があります。

    Windows タスク マネージャーの [ハンドル] 列のスクリーンショット。

  3. これらのプロセス以外のプロセスの数が多い場合は、そのプロセスを停止してから、ドメイン資格情報を使用してサインインし、成功するかどうかを確認します。

方法 3

タスク マネージャーがプロセスの特定に役立たない場合は、プロセス エクスプローラーを使用して問題を調査します。

プロセス エクスプローラーを使用する手順:

  1. プロセス エクスプローラーをダウンロードし、管理者特権で実行します

  2. Alt キーを押しながら列ヘッダーを選択し、[ 列の選択] を選択し、[ プロセス パフォーマンス ] タブで [ハンドル数] を追加します。

  3. [下のウィンドウを表示]> を選択します。

  4. [下のウィンドウ ビュー ハンドルの表示>>] を選択します

  5. [ ハンドル ] 列を選択して、その値で並べ替えます。

  6. 残りのプロセスよりもハンドル数が多いプロセスを調べます (送信接続を確立できない場合は 10,000 を超える可能性があります)。

  7. クリックすると、ハンドル数が多いプロセスの 1 つが強調表示されます。

  8. 下のペインでは、次に示すハンドルがソケットです。 (ソケットは技術的にはファイル ハンドルです)。

    ファイル \Device\AFD

    プロセスがハンドルで並べ替えられたプロセス エクスプローラーのスクリーンショット。

  9. 一部は正常ですが、それらの多数は (数百から数千) ではありません。 問題のプロセスを閉じます。 送信接続が復元された場合は、アプリが原因であることがさらに実証されています。 そのアプリのベンダーに問い合わせてください。

最後に、上記の方法でプロセスを分離できない場合は、問題状態のマシンの完全なメモリ ダンプを収集することをお勧めします。 ダンプは、最大ハンドルを持つプロセスを示します。

回避策として、コンピューターを再起動すると通常の状態に戻り、当面の間問題を解決するのに役立ちます。 ただし、再起動が実用的でない場合は、次のコマンドを使用して、マシン上のポートの数を増やすことも検討できます。

netsh int ipv4 set dynamicport tcp start=10000 num=1000

このコマンドは、ダイナミック ポート範囲をポート 10000 から開始し、ポート 10999 (1000 ポート) で終了するように設定します。 設定できるポートの最小範囲は 255 です。 設定できる最小開始ポートは 1025 です。 最大エンド ポート (構成されている範囲に基づく) は、65535 を超えることはできません。

注:

ダイナミック ポート範囲を増やすことは永続的な解決策ではなく、一時的な解決策であることに注意してください。 最大数のポートを消費しているプロセス/プロセッサを追跡し、そのプロセスの観点から、このような多数のポートを使用している理由に関するトラブルシューティングを行う必要があります。

Windows 7 および Windows Server 2008 R2 の場合は、次のスクリプトを使用して、定義された頻度で netstat 出力を収集できます。 出力から、ポートの使用状況の傾向を確認できます。

@ECHO ON
set v=%1
:loop
set /a v+=1
ECHO %date% %time% >> netstat.txt
netstat -ano >> netstat.txt
 
PING 1.1.1.1 -n 1 -w 60000 >NUL
 
goto loop

詳細

  • ポート枯渇とあなた! - この記事では、netstat の状態の詳細と、netstat 出力を使用してポートの状態を判断する方法について説明します
  • エフェメラル ポートの枯渇の検出: この記事には、ポートの状態を報告するループで実行されるスクリプトがあります。 (Windows 2012 R2、Windows 8、Windows 10、Windows 11に適用)