エフェメラルポートとは
概要
ソケットを使ったUDP通信を試す際に、「エフェメラルポートって何?」 という疑問に遭遇したので、勉強したことを書き残します。
エフェメラルポートとは
クライアントがサーバと通信する際、送信元として使用されるポート番号を指します。エフェメラル(ephemeral)
は一時的な
という意味です。
その名の通り、このポートは短命で、通信終了後は解放されて再利用されます。通常は49152〜65535
が指定されますが、OSごとに異なります。
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が自動的にエフェメラルポートを割り当てます。
たとえば、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