🐧 Linux 総合学習プラットフォーム
ネットワーク基礎 ・ 中級

ポートとプロトコル(TCP/UDP)

1台の機器では複数のサービスが同時に動くため、IPアドレスだけでなく「ポート番号」で通信相手のサービスを区別します。Webは80や443、SSHは22といった具合です。通信方式にはTCPとUDPがあり、TCPは到達と順序を保証する確実な方式、UDPは確認をしない代わりに高速・軽量な方式です。どのポートが待ち受けているかは ss コマンドで確認します。

IPアドレスは「どの機器か」を指し示しますが、それだけでは通信相手を特定しきれません。1台のサーバの上では、Webサーバ・メールサーバ・SSHなど複数のサービスが同時に動いているのが普通だからです。そこで、機器の中のどのサービスとやり取りするのかを区別する番号として使われるのがポート番号です。IPアドレスが建物の住所だとすれば、ポート番号はその建物の何号室か(どのサービスの窓口か)を表す部屋番号にあたります。住所と部屋番号の両方がそろってはじめて、目的のサービスへ正確に話しかけられる、というわけです。ポート番号は0〜65535の範囲の値を取り、これから説明するTCPとUDPというプロトコルが共通して持っている仕組みです。

ウェルノウンポート

ポート番号のうち0〜1023の範囲は「ウェルノウンポート」と呼ばれ、主要なサービスにあらかじめ用途が割り当てられています。代表的なものとして、Webの通信に使うHTTPは80番、その暗号化版であるHTTPSは443番、リモート操作に使うSSHは22番、名前解決のDNSは53番、メール送信のSMTPは25番です。これらは世界共通の慣習なので、たとえばブラウザでWebサイトを開くときは、ユーザが意識しなくても自動的に相手の443番(または80番)へ接続しに行きます。逆にサーバを公開する側は、提供したいサービスに対応するポートで待ち受けるよう設定します。一方、サービスを利用する側(クライアント)が使う送信元のポートには、その都度OSが空いている高めの番号(エフェメラルポート)を自動で割り当てます。サーバは要求に応答するとき、相手の送信元ポート宛てに返すので、複数の通信が同時に流れても、要求と応答を取り違えずに対応づけられます。

TCPとUDP

ポート番号と並んで重要なのが、データの運び方を決めるTCPとUDP(あわせてTCP/UDPと書かれることもあります)という2つのプロトコルです。TCPは到達と順序を保証する確実な方式で、通信の前に相手と「これから話します」「いいですよ」と確認し合ってから(コネクションを確立してから)データを送り、受信側が「ここまで受け取った」と応答を返します。このコネクション確立の最初のやり取りは、SYN・SYN+ACK・ACKという3回の手続き(3ウェイ・ハンドシェイク)で行われます。途中でデータが欠けたり壊れたりすれば再送するので、ファイルの転送やWebページの表示のように、一文字でも欠けては困る用途に向きます。一方UDPは、こうした確認をいっさい行わず、相手が受け取ったかを気にせずデータを送りつける高速・軽量な方式です。手紙をポストに入れて出すように送りっぱなしにするイメージで、多少の欠落が許される音声・動画のストリーミングや、やり取りが小さくて速さを優先したいDNS・NTPなどで使われます。

TCPとUDPは正反対の性格を持つので、用途で使い分けられます。TCPは確実さと引き換えに、コネクションの確立や応答確認のぶん通信のやり取りが増え、わずかに遅くなります。UDPは確実さを捨てる代わりに、送りたいタイミングでそのまま送れるため遅延が小さく、リアルタイム性が求められる通信に強みがあります。「確実に届けるTCP、速さ優先のUDP」と覚えておくと、どのサービスがどちらを使うかの見当がつきます。たとえばHTTP・HTTPSやSSHはTCP、DNSの問い合わせや時刻同期のNTPは主にUDP、という具合です。なお近年は、UDPの上で動きながらTCP並みの信頼性と暗号化を実現するQUICという新しいプロトコルも登場し、HTTP/3として一部のWebサービスで使われ始めています。

ss でポートを確認する

自分の機器でどのポートが待ち受けているか、どんな接続が成立しているかを調べるには ss コマンドを使います。よく使うのが ss -tuln で、-t はTCP、-u はUDP、-l は待ち受け(listen)状態のもの、-n は名前解決せず番号のまま表示、という意味の組み合わせです。これを実行すると、Local Address:Port の欄に 0.0.0.0:22 や [::]:443 のように、待ち受け中のポートが一覧されます。22番が出ていればSSHサーバが、443番が出ていればHTTPSのサーバが起動して待ち受けている、と読み取れます。いま確立しているTCP接続だけを見たいときは ss -t state established とすると、相手のアドレスとポートの組が並び、ブラウザを開いていれば相手側443番への行が見えるはずです。何も表示されないときは、通信中のアプリが無いだけのことが多いので、ブラウザでページを開いてから再実行してみましょう。

実務では、サービスを立ち上げたのに外からつながらない、というときに ss -tuln が活躍します。まず狙ったポートが待ち受け一覧に出ているかを確認し、出ていなければサービス自体が起動していないか、設定したポートが違う可能性があります。逆に、相手側のポートが開いているか(接続を受け付けるか)を外から確かめたいときは curl -I https://例.example/ のようにすると、TCP接続が成立すればHTTPのステータス行(例: HTTP/2 200)とヘッダだけが返り、接続できなければ Connection refused や timed out が返るので、ポートが閉じている・到達できないサインとして切り分けに使えます。Connection refused は「相手まで届いたがそのポートで待ち受けていない」、timed out は「そもそも相手まで届いていない、あるいは途中でパケットが捨てられている」ことが多く、メッセージの違いから原因の見当もつけられます。前者ならサービスの起動やポート番号を、後者なら経路やファイアーウォールを疑う、というように次に調べる場所が変わってきます。古い環境では netstat -tuln でも近い情報が得られますが、現在は net-tools という古いパッケージから iproute2 の ss への置き換えが進んでいるため、ss -tuln を手の内に入れておくと現行の環境でそのまま通用します。UDPの待ち受けを見たいときは ss -u を、待ち受けだけでなく確立中のものも含めて見たいときはオプションを足して使い分けます。

この項目に出てくる用語

ポートぽーと
1台の機器内でサービスを区別する番号(0〜65535)。
TCP/UDPてぃーしーぴーゆーでぃーぴー
通信方式の2種類。確実なTCPと、高速・軽量なUDP。
ウェルノウンポートうぇるのうんぽーと
用途が広く決まっている0〜1023番のポート。

関連コマンド

sscurl

▶ 学習アプリでこの続きを学ぶ・演習する