ポート番号
1台の機器の中で通信の窓口を区別する番号。IPアドレスが住所ならポートは部屋番号。
概要
ポート番号は、1台のコンピュータの中で通信の「窓口」を区別するための番号です。IPアドレスが建物の住所だとすれば、ポート番号は部屋番号にあたります。データが機器まで届いても、その機器の中ではWebサーバ、メールサーバ、SSHなど複数のプログラムが同時に動いているかもしれません。どのプログラムに渡すべきかを決めるのがポート番号の役割です。
開発の現場では「ローカルの3000番でアプリを起動する」「ファイアウォールで443番だけ開ける」「ポートが衝突して起動できない」といった言い回しで日常的に登場します。URLの「localhost:8080」の「8080」もポート番号です。
なぜ生まれたか
IPアドレスだけでは、宛先の「機器」までしか特定できません。しかし1台の機器で動かしたい通信プログラムは1つとは限らず、むしろ複数のサービスを同居させるのが普通です。もし機器単位でしか宛先を指定できなければ、Webとメールを提供するために物理的に2台のマシンを用意するか、届いたデータの中身を覗いて振り分ける独自の仕組みを毎回作る必要があります。
そこでTCP/IPの設計では、IPアドレスの一段内側に16ビットの番号を設け、「同じ機器宛でも番号ごとに別の通信」として扱えるようにしました。1本の回線・1つのアドレスの上に多数の独立した通信を多重化する——ポート番号はそのための仕分けラベルとして生まれました。
詳細
番号の範囲と割り当て
ポート番号は0〜65535の整数です。このうち0〜1023は「ウェルノウンポート」と呼ばれ、主要なプロトコルに慣習と標準(IANAの管理)で割り当てられています。HTTPの80番、HTTPSの443番、SSHの22番、DNSの53番などが代表です。ブラウザで「https://example.com」と打つだけで通じるのは、「httpsなら443番」という取り決めをブラウザが知っているからです。1024〜49151は登録済みポート(PostgreSQLの5432番、MySQLの3306番など)、49152以降は「エフェメラルポート」としてOSが一時的な通信用に自動で割り当てます。
通信は「IPアドレス+ポート」の4つ組で識別される
見落とされがちですが、ポート番号はサーバ側だけでなくクライアント側にもあります。ブラウザがWebサーバに接続するとき、OSはクライアント側に空いているエフェメラルポート(例: 51234番)を自動で割り当てます。1つの通信は「送信元IP・送信元ポート・宛先IP・宛先ポート」の4つ組で一意に識別され、だからこそ同じPCから同じサーバへタブを何枚開いても、それぞれ独立した通信として混線せずに成立します。
サーバに届いたデータは、OSが宛先ポート番号を見て、その番号で待ち受けているプログラムへ振り分けます。応答は送信元ポート(例の51234番)宛に返ります。
この「番号で待ち受け、届いたデータをプログラムに渡す」仕組みをプログラムから扱うインターフェースがソケットです。「アドレスとポートにバインドする」という表現は、あるプログラムがその窓口を占有することを意味します。
「ポートを開ける」「ポートが衝突する」
運用でいう「ポートを開ける」は、ファイアウォールがそのポート宛の通信を通すよう許可することです。セキュリティの基本は「必要なポートだけ開ける」で、公開Webサーバなら80番・443番以外は閉じておくのが定石です。逆に攻撃者が最初に行うのも「どのポートが開いているか」の調査(ポートスキャン)で、開いたポートはそのまま攻撃対象の一覧になります。
「ポートの衝突」は開発中によく遭遇するエラーです。1つのポートで待ち受けられるプログラムは原則1つなので、3000番で開発サーバを起動したまま別のアプリを3000番で立ち上げると「Address already in use」で失敗します。前のプロセスを止めるか、別の番号を指定するのが対処法です。
設計上の注意点
ポート番号はUDPとTCPで独立した空間を持ちます。「TCPの53番」と「UDPの53番」は別物で、DNSのように両方を使うプロトコルもあります。また、1024未満のポートで待ち受けるには多くのOSで管理者権限が必要なため、実務ではアプリケーションを8080番などの高い番号で動かし、前段のリバースプロキシやロードバランサが443番で受けて転送する構成が一般的です。「外から見えるポート」と「アプリが実際に聞いているポート」が別になるこの構図は、コンテナのポートマッピングを理解するうえでも基本になります。