Zenn

エフェメラルポートとは

に公開

概要

ソケットを使ったUDP通信を試す際に、「エフェメラルポートって何?」 という疑問に遭遇したので、勉強したことを書き残します。

https://zenn.dev/shimiyu/articles/e34f6895ab3573

エフェメラルポートとは

クライアントがサーバと通信する際、送信元として使用されるポート番号を指します。エフェメラル(ephemeral)一時的なという意味です。

その名の通り、このポートは短命で、通信終了後は解放されて再利用されます。通常は49152〜65535が指定されますが、OSごとに異なります。

https://datatracker.ietf.org/doc/html/rfc6335?utm_source=chatgpt.com#section-6

RFC 6335 Section6

このセクションでは、IANAによるポート番号の割り当てと、それに基づく分類が定義されているようです。

範囲 名称 用途
0–1023 ウェルノウンポート(Well-Known Ports) HTTP(80), SSH(22)など、よく知られた標準サービス用
1024–49151 レジスタードポート(Registered Ports) 登録済みアプリケーション用
49152–65535 エフェメラルポート 一時的・動的に使われる。クライアント側の送信用やローカル開発環境でよく使われる。OSによって自動割り当てされる範囲。

MacOSのエフェメラルポートを確認する

sysctl net.inet.ip.portrangeは、ネットワーク(IPv4)のIPポートに関する範囲設定を、一覧表示するコマンドです。

% sysctl net.inet.ip.portrange
net.inet.ip.portrange.lowfirst: 1023
net.inet.ip.portrange.lowlast: 600
net.inet.ip.portrange.first: 49152
net.inet.ip.portrange.last: 65535
net.inet.ip.portrange.hifirst: 49152
net.inet.ip.portrange.hilast: 65535
net.inet.ip.portrange.ipport_allow_udp_port_exhaustion: 0

Linuxのエフェメラルポートを確認する

一方、Linux(Ubuntu)では、cat /proc/sys/net/ipv4/ip_local_port_rangeで確認できます。多くのディストリビューションでエフェメラルポートの範囲は32768-60999です。

cat /proc/sys/net/ipv4/ip_local_port_range
32768 60999

実際にUDP通信で確認してみる

以下は、ソケットを使ったUDP通信のサンプルです。UDP通信ではクライアント側で送信元ポートを明示的に bind()しない限り、OSが自動的にエフェメラルポートを割り当てます

https://zenn.dev/shimiyu/articles/e34f6895ab3573#ソケットを使ったudp通信のサンプル

たとえば、Linux環境のクライアントからサーバにメッセージを送信した際、以下のようなログがサーバに出力されました。

% python3 udp_server.py
UDPサーバを起動しました: 0.0.0.0:12345
[受信] ('192.168.10.9', 34326) から: message from linux
[送信] ('192.168.10.9', 34326) へメッセージを返却しました

送信元のポート番号として 34326 が使われており、これはLinuxでのエフェメラルポートの範囲(32768〜60999) の中に含まれています。

一方、前述の通り、macOSではエフェメラルポートの範囲が49152〜65535に設定されており、34326はその範囲外です。このことからも、OSごとにエフェメラルポートの範囲が異なることが分かります。

最後に

普段あまり深く意識せずに使っている「ポート番号」について、今回は少し立ち止まって見てみました。ちょっとだけ解像度が上がった気がします。

Discussion

ログインするとコメントできます