短命ポートの問題は10年に一度やってくる

  • 投稿日:
  • by
  • カテゴリ:

10年前は、ポートの枯渇問題で出くわしました。

短命ポートは、「エフェメラルポート」です。

TCPでは、接続先ポートだけでなく接続元でもポートが使われます。そうでないとIPレベル(例えばイーサ)でduplex通信できませんからね?

例えばブラウザでhttpやsslで通信していると、以下のように、大きい番号のポートが使われることはご存知でしょう?

TCP [240b:250:2140:200:24c2:f939:514d:86f6]:55647 [2a01:111:f102:8001::1761:4f8b]:443 ESTABLISHED
TCP [240b:250:2140:200:24c2:f939:514d:86f6]:57584 [2404:6800:4004:80e::2005]:443 ESTABLISHED
TCP [240b:250:2140:200:24c2:f939:514d:86f6]:57595 [2404:6800:400a:808::200e]:443 TIME_WAIT
TCP [240b:250:2140:200:24c2:f939:514d:86f6]:57632 [2404:6800:4008:c01::bd]:443 ESTABLISHED
TCP [240b:250:2140:200:24c2:f939:514d:86f6]:57636 [2404:6800:4004:80b::2003]:443 ESTABLISHED
TCP [240b:250:2140:200:24c2:f939:514d:86f6]:59758 [2600:140b:15:188::3114]:80 ESTABLISHED
TCP [240b:250:2140:200:24c2:f939:514d:86f6]:59759 [2600:140b:15:188::3114]:80 ESTABLISHED
TCP [240b:250:2140:200:24c2:f939:514d:86f6]:59760 [2600:140b:15:188::3114]:80 ESTABLISHED
TCP [240b:250:2140:200:24c2:f939:514d:86f6]:59761 [2600:140b:15:188::3114]:80 ESTABLISHED
TCP [240b:250:2140:200:24c2:f939:514d:86f6]:59762 [2600:140b:15:188::3114]:80 ESTABLISHED
TCP [240b:250:2140:200:24c2:f939:514d:86f6]:59763 [2600:140b:15:188::3114]:80 ESTABLISHED

上記でもTIME_WAITのものがひとつありますが、CLOSE_WAITが数千、数万個あったら、ポート番号が枯渇してTCPのconnectができなくなります。

これがよくあるポート枯渇問題です。

サーバでlistenしているからつながるはず(でもつながらない)

という経験不足のネットワークプログラマがはまる落とし穴ですね。(10年前の私も)

でまぁ、ポートの枯渇はもう広く知れ渡っています。

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

短命ポートには別の問題もあります。それは短命ポートで使われているポートはlistenできないことです。

つまり上記の状況の場合、55647 や59763 番ポートでlistenできないということですね。

しばらく待てば、ポートは解放され、listenできるようになるかもしれませんが、いつそうなるかは誰にもわかりません。

短命ポートはプロトコルスタックが選択します。

短命ポートで使われるポート番号を使ってTCPサーバを構成しようとする場合、そのプロセスは、システムの起動直後にlisten(bind)しないといけません。

普通のアプリケーションが好きなタイミングで55647番ポートをlistenしようという場合、短命ポートとしてすでに他のアプリやサービスに占有されている可能性を考慮しなければならないということです。

長々と書きましたが、ポート番号をOSレベルで予約することはできませんので、短命ポートの番号を指定して回避するのが普通のやり方でしょう。Windowsの場合、以下に書かれてます。

Windows Vista および Windows Server 2008 以降、動的な TCP/IP の既定のポート範囲が変更されました。

貼り付け元 <https://support.microsoft.com/ja-jp/help/929851/the-default-dynamic-port-range-for-tcp-ip-has-changed-in-windows-vista>

手元の環境では、以下のように55000~が使われています。

netsh int ipv4 show dynamicport tcp

プロトコル tcp の動的ポートの範囲
---------------------------------
開始ポート : 55000
ポート数 : 5000

この環境なら、45000番ポートでlistenするアプリケーションは問題ないわけですが、55000番ポートをlistenするアプリは正常に動作できる保証はありません。

そういう場合は再起動したら動く、とか、特定のPCで動かないことがある、などという「おまじない」を信じている人にとってはどうでもいいかもしれませんね。