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

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

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

  • 一時的なポート(通常は動的なポート) は、すべてのコンピューターに既定で送信接続を作成するためのポートのセットです。
  • 既知のポートとは、特定のアプリケーションまたはサービスに対して定義されたポートのことです。 たとえば、file server service はポート445、HTTPS は443、HTTP は80、RPC は135です。 カスタムアプリケーションには、定義されたポート番号もあります。

アプリケーションまたはサービスに接続する場合、クライアントはそのコンピューターの一時的なポートを使用して、そのアプリケーションまたはサービスに対して定義された既知のポートに接続します。 クライアントコンピューター上のブラウザーは、一時的なポートを使用しhttps://www.microsoft.comて、ポート443に接続します。

同じブラウザーが複数の web サイトへの多数の接続を作成しているシナリオでは、ブラウザーが試みる新しい接続の場合、一時的なポートが使用されます。 しばらくすると、接続が失敗することがあります。これは、ブラウザーが利用可能なすべてのポートを使って接続を確立していて、接続を確立しようとしても、新しい接続を確立することができないために、この問題が発生する可能性があることに注意してください。使用可能なポート。 マシン上のすべてのポートが使用されている場合は、「ポートの枯渇」ということになります。

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

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

具体的には、着信接続としての送信接続について、接続を受け入れるための一時的なポートは必要ありません。

送信接続が失敗すると、次のような現象が発生します。

  • ドメインの資格情報を使用してコンピューターにサインインできませんが、local account によるサインインは動作します。 ドメインのサインインでは、もう一度送信接続となる認証のために DC に問い合わせる必要があります。 キャッシュの資格情報が設定されている場合は、ドメインのサインインが機能する可能性があります。

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

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

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

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

    "Windows はアクセスできません" というエラーメッセージのスクリーンショット

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

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

  • コンピューターで実行されているその他のアプリケーションが、エラーの発生を開始します

サーバーを再起動すると一時的に問題が解決しますが、すべての現象が一定期間続いて表示されます。

コンピュータが port exhaustion の状態にあると考えられる場合は、次の操作を行います。

  1. 送信接続を試してみてください。 サーバー/コンピューターからリモート共有にアクセスするか、RDP を別のサーバーに接続するか、ポート上のサーバーに対して telnet を実行します。 すべての送信接続が失敗した場合は、次の手順に進みます。

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

    a. イベント ID 4227

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

    b. イベント ID 4231

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

  3. サーバーからnetstat -anob output a を収集します。 Netstat の出力には、1つの PID について、TIME_WAIT 状態の多数のエントリが表示されます。

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

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

また、CLOSE_WAIT state connections が同じ出力に表示されることもあります。ただし、CLOSE_WAIT state は、TCP ピアの一方の側に、送信するデータがなくなって (FIN 送信)、もう一方のエンドからデータを受信できることを示す状態です。 この状態は、ポートの枯渇を示すとは限りません。

注意

TIME_WAIT 状態での接続が非常に大きい場合でも、最初の2つの点が確認されていない限り、サーバーが現在ポートを利用していないことを示すわけではありません。 TIME_WAIT 接続が多いと、プロセスが大量の TCP 接続を作成しているため、最終的にポートが枯渇する可能性があります。

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

10/2016 まで、netstat は不正確でした。 Netstat、back (2012 R2) 向けの修正プログラムについては、Netstat.exe と NetTcpConnection を使用して、Windows Server 2012 R2 で TCP または UDP ポートの使用状況を正しく報告してください。 詳細については、「 Windows Server 2012 R2: 一時ポートホットフィックス」を参照してください。

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

    Netsh trace start scenario=netconnection capture=yes tracefile=c:\Server.etl
    
  2. ネットワークモニターを使用してサーバーの .etl ファイルを開き、[フィルター] セクションで、"Wscore_MicrosoftWindowsWinsockAFD" というフィルターを適用します。 LENTStatus = = 0x209STATUS_TOO_MANY_ADDRESSESというエントリが表示されます。 エントリが見つからない場合でも、サーバーはまだポートを使用していません。 該当するものが見つかった場合は、そのサーバーが [port exhaustion] の下に表示されていることを確認できます。

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

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

方法1

まず、netstat の出力を見ていきます。 Windows 10 または Windows Server 2016 を使っている場合は、コマンドnetstat -anobqを実行して、最大エントリがバインドされているプロセス 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 および Windows Server 2012 R2 より前) を特定することができない場合は、次のようにタスクマネージャーについて確認してください。

  1. [詳細/プロセス] の下に "handles" という列を追加します。
  2. 列ハンドルを並べ替えて、ハンドルの数が最も多いプロセスを特定します。 通常、3000より大きいハンドルを持つプロセスは、システム、lsass.exe、store.exe、store.exe などのプロセスを除き、問題の原因となる可能性があります。

    Windows タスクマニフェストの [ハンドル] 列のスクリーンショット

  3. その他のプロセスがより大きい場合は、そのプロセスを停止し、ドメイン資格情報を使用してログインして、成功したかどうかを確認します。

方法3

タスクマネージャーがプロセスを特定できなかった場合は、プロセスエクスプローラーを使用して問題を調査します。

プロセスエクスプローラーの使用手順:

  1. プロセスエクスプローラーをダウンロードして、管理者特権で実行します。
  2. Alt キーを押しながら列見出しをクリックして、[列の選択] を選択し、[プロセスパフォーマンス] タブで [ハンドル数の追加] をクリックします。
  3. [表示] を選択します。
  4. [ビュー] の [下枠のビュー \ ハンドル] を選択します。
  5. その値で並べ替えるには、[ハンドル] 列をクリックします。
  6. より大きいハンドル数のプロセスを (送信接続ができない場合は、1万よりも) 調べます。
  7. クリックすると、大きいハンドルカウントを持つプロセスの1つが強調表示されます。
  8. 下のウィンドウでは、次のようなハンドルがソケットになっています。 (ソケットは厳密にはファイルハンドルになります)。

    ファイル \Device\AFD

    プロセスエクスプローラーのスクリーンショット

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

最後に、上記の方法でプロセスを分離できなかった場合は、コンピューターの完全なメモリダンプを問題の状態で収集することをお勧めします。 このダンプによって、どのプロセスの最大ハンドルが表示されているかがわかります。

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

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

これにより、動的ポート範囲がポート1万から始まり、ポート 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 に適用される)