ポートの枯渇問題のトラブルシューティング
適用対象: Windows 10
TCP および UDP プロトコルは、接続の確立に使用されるポート番号に基づいて機能します。 TCP/UDP 接続を確立する必要があるアプリケーションまたはサービスには、その側にポートが必要です。
ポートには次の 2 種類があります。
- エフェメラル ポート (動的ポート) は、すべてのマシンが既定で送信接続を行う必要があるポートのセットです。
- 既知のポートは、特定のアプリケーションまたはサービスに対して定義されたポートです。 たとえば、ファイル サーバー サービスはポート 445、HTTPS は 443、HTTP は 80、RPC は 135 になります。 カスタム アプリケーションには、独自のポート番号も定義されます。
アプリケーションまたはサービスとの接続が確立されている場合、クライアント デバイスはデバイスからのエフェメラル ポートを使用して、そのアプリケーションまたはサービスに定義されている既知のポートに接続します。 クライアント コンピューター上のブラウザーは、エフェメラル ポートを使用してポート 443 の https://www.microsoft.com
に接続します。
同じブラウザーが複数の Web サイトへの多数の接続を作成しているシナリオでは、ブラウザーが試行している新しい接続に対して、エフェメラル ポートが使用されます。 しばらくすると、接続が失敗し始め、このエラーの可能性が高くなる可能性が 1 つあります。これは、ブラウザーが使用可能なすべてのポートを使用して外部に接続を行い、使用可能なポートがなくなったため、接続を確立するための新しい試行が失敗するためです。 マシン上のすべてのポートを使用する場合は、ポート不足と呼びます。
TCP/IP の既定の動的ポート範囲
Internet Assigned Numbers Authority (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 に接続して認証を行う必要があります。これはもう一度送信接続です。 キャッシュ資格情報が設定されている場合でも、ドメイン サインインが機能する可能性があります。
グループ ポリシーの更新エラー:
ファイル共有にアクセスできない:
影響を受けるサーバーからの RDP が失敗する:
マシン上で実行されている他のアプリケーションは、エラーの発生を開始します
サーバーを再起動すると問題は一時的に解決されますが、一定期間後にすべての症状が返されます。
マシンがポート不足の状態にあると思われる場合は、次の手順を実行します。
送信接続を作成してみてください。 サーバー/マシンからリモート共有にアクセスするか、別のサーバーへの RDP またはポート上のサーバーへの telnet を試します。 これらのオプションすべてに対して送信接続が失敗した場合は、次の手順に進みます。
イベント ビューアーを開き、システム ログで、現在の状態を明確に示すイベントを探します。
イベント ID 4227
イベント ID 4231
サーバーから
netstat -anob
出力を収集します。 netstat の出力には、1 つの PID のTIME_WAIT状態に関する膨大な数のエントリが表示されます。正常なクローズまたはセッションの突然のクローズの後、4 分 (既定) の期間が経過すると、プロセスまたはアプリケーションによって使用されるポートが使用可能なプールに解放されます。 この 4 分間、TCP 接続状態は TIME_WAIT 状態になります。 ポートの枯渇が疑われる状況では、アプリケーションまたはプロセスが消費したすべてのポートを解放できず、TIME_WAIT状態のままとなります。
同じ出力にCLOSE_WAIT状態接続が表示される場合もあります。ただし、CLOSE_WAIT状態は、TCP ピアの一方の側に送信するデータ (FIN 送信) がなくなったが、もう一方の側からデータを受信できる状態です。 この状態は、必ずしもポート不足を示すわけではありません。
Note
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 の修正。Windows Server 2012 R2 で TCP または UDP ポートの使用状況を正しく報告するために、 Netstat.exe と
Get-NetTcpConnection
を許可しました。 詳細については、「 Windows Server 2012 R2: エフェメラル ポート修正プログラム を参照してください。管理者モードでコマンド プロンプトを開き、次のコマンドを実行します。
Netsh trace start scenario=netconnection capture=yes tracefile=c:\Server.etl
Network Monitor で server.etl ファイルを開きフィルター セクションでフィルター
Wscore_MicrosoftWindowsWinsockAFD.AFD_EVENT_BIND.Status.LENTStatus.Code == 0x209
を適用します。 STATUS_TOO_MANY_ADDRESSESと表示されるエントリが表示されます。 エントリが見つからない場合、サーバーは引き続きポートから出ていません。 検出された場合は、サーバーのポートが枯渇していることを確認できます。
ポート枯渇のトラブルシューティング
重要なのは、すべてのポートを使用しているプロセスまたはアプリケーションを特定することです。 単一のプロセスに切り分けるために使用できるツールをいくつか次に示します
方法 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
ほとんどのポート リークは、エラー発生時にユーザー モード プロセスによってポートが正しく閉じられないことが原因で発生します。 ユーザー モード レベルでは、ポート (実際にはソケット) はハンドルです。 TaskManagerとProcessExplorerの両方でハンドル数を表示できるため、すべてのポートを使用しているプロセスを識別できます。
Windows 7 および Windows Server 2008 R2 では、PowerShell のバージョンを更新して上記のコマンドレットを含めることができます。
方法 2
方法 1 でプロセスを識別できない場合 (Windows 10 および Windows Server 2012 R2 より前)、タスク マネージャーを確認してください。
詳細/プロセスの下に "handles" という名前の列を追加します。
ハンドルの列を並べ替えて、ハンドル数が最も多いプロセスを特定します。 通常、ハンドルが 3000 を超えるプロセスは、System、 lsass.exe、 store.exe、 sqlsvr.exeなどのプロセスを除き、原因になる可能性があります。
これらのプロセス以外のプロセスの数が多い場合は、そのプロセスを停止し、ドメイン資格情報を使用してサインインを試み、成功したかどうかを確認します。
方法 3
タスク マネージャーがプロセスの特定に役立たない場合は、プロセス エクスプローラーを使用して問題を調査します。
プロセス エクスプローラーを使用する手順:
プロセス エクスプローラーをダウンロードしElevated実行します。
Alt キーを押しながら列ヘッダーを選択 [列の選択、 Process Performance タブで Handle Count を追加します。
View>下のウィンドウを表示を選択します。
View>Lower ウィンドウ ビュー>Handles を選択します。
Handles列を選択して、その値で並べ替えます。
ハンドル数が他のプロセスよりも多いプロセスを調べます (送信接続を確立できない場合は、10,000 を超えている可能性が高くなります)。
ハンドル数が多いプロセスのどれかをクリックして強調表示します。
下部ウィンドウに表示されている次のようなハンドルがソケットです (ソケットは、技術的にはファイル ハンドルです)。
File \Device\AFD
一部は正常ですが、それらの数は (数百から数千) ではありません。 問題のプロセスを終了します。 これにより送信接続が復元される場合は、アプリが原因であることがさらに実証されています。 そのアプリのベンダーに問い合わせてください。
最後に、上記の方法でプロセスを分離できない場合は、問題の状態にあるマシンの完全なメモリ ダンプを収集することをお勧めします。 ダンプから最大数のハンドルを持つプロセスがわかります。
回避策として、コンピューターを再起動すると通常の状態に戻り、当面の問題の解決に役立ちます。 ただし、再起動が実用的でない場合は、次のコマンドを使用してコンピューターのポート数を増やすことも検討できます。
netsh int ipv4 set dynamicport tcp start=10000 num=1000
このコマンドは、動的ポート範囲をポート 10000 から開始し、ポート 10999 (1000 ポート) で終了するように設定します。 設定できるポートの最小範囲は 255 です。 設定できる最小の開始ポートは 1025 です。 (構成されている範囲に基づく) 最大エンド ポートは 65535 を超えることはできません。
Note
ダイナミック ポート範囲を増やすことは永続的な解決策ではなく、一時的なソリューションであることに注意してください。 どのプロセス/プロセッサが最大ポート数を消費しているかを追跡し、そのプロセスの観点からトラブルシューティングを行う必要があります。また、なぜこのような多数のポートが消費されているのかについては、トラブルシューティングを行う必要があります。
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 に適用)