IT の基礎
TCP、UDP、ポート
データは小さなパケットに分けて送ります。届いたか確かめて欠けたら送り直すのが TCP、確かめずに送りっぱなしにするのが UDP で、届いた先のどのプログラムに渡すかはポート番号で決まります。
ネットワークで送るデータは、パケットと呼ぶ小さな単位に分けて運ばれます。途中で失われるパケットもあるので、送る側には 2 つのやり方があります。届いたか確かめ、欠けたら送り直す TCP と、確かめずに送りっぱなしにする UDP です。どちらも、届いた先のコンピューターで受け取るプログラムをポート番号で指定します。Google Cloud のファイアウォールに tcp:22 のような書き方が出てくるのは、このためです。
パケットは途中で失われる
パケットは、データの一部に宛先の IP アドレスなどを書いた見出し (ヘッダー) を付けたものです。パケットはルーターを何台も経由して届き、混雑したルーターは処理しきれないパケットを捨てます。電波の弱い Wi-Fi でも失われます。インターネットでパケットを運ぶ IP という仕組みは、届けようと努力はしますが、届くことも順番どおりに着くことも約束しません。その約束を足すかどうかを決めるのが、1 つ上の層の TCP と UDP です。
TCP は確かめて送り直す
TCP は、データを送る前に相手と接続を作ります。この手順を 3 ウェイハンドシェイクと呼び、3 回のやり取りで済みます。
- SYN: 送信側が「接続したい」と伝える
- SYN-ACK: 受信側が「受け付けた」と返す
- ACK: 送信側が「確認した」と返し、データを送り始める
接続ができたら、TCP はパケットに通し番号を付けて送ります。受信側は受け取った番号を確認応答 (ACK) で返し、送信側は一定時間 ACK が返ってこないパケットを送り直します (再送)。番号があるので、受信側は順番が入れ替わって着いたパケットも並べ直せます。こうして、アプリには欠けも入れ替わりもないデータが渡ります。
その代わり、TCP は接続の準備に 1 往復ぶん待ち、失われたパケットの再送でも待ちます。Web ページ、メール、ファイルの転送、データベースへの接続のように、1 バイトでも欠けると困る通信は TCP を使います。仕様は RFC 9293 にあります。
UDP は送りっぱなしにする
UDP は接続を作らず、ACK も再送もありません。欠けたパケットは欠けたまま、アプリに届いたものだけが渡ります (RFC 768)。
それでも UDP を選ぶのは、待たないからです。ビデオ通話で 0.5 秒前の音声を再送されても、もう役に立ちません。少し欠けても今の音声を流し続けるほうが自然に聞こえます。オンラインゲームや音声通話のほか、短い問い合わせ 1 回で済む DNS (名前から IP アドレスを調べる仕組み) も UDP を使います。HTTP の新しい版の HTTP/3 は、UDP の上に QUIC という仕組みを載せ、再送などを QUIC の側で行います。
下のシミュレーターで、同じ通信路に TCP と UDP で同じ数のパケットを流せます。損失率を 0% から 30% に上げると、TCP は再送の回数が増えて全部届き、UDP は一部が欠けます。「もう一度送る」で、失われるパケットが変わります。
ポート番号で受け取るプログラムを決める
IP アドレスで届くのはコンピューターまでです。1 台のサーバーでは、Web サーバーと SSH (遠隔ログインの仕組み) とデータベースが同時に動いていることがあります。どのプログラムに渡すかを決める番号がポート番号で、0 から 65535 まであります。TCP と UDP はポートを別々に持つので、TCP の 53 番と UDP の 53 番は別のものです。
サービスを待ち受ける側は決まった番号を使い、接続する側のポートは OS がその都度空いている番号を選びます。番号の範囲は RFC 6335 で 3 つに分かれています。0〜1023 が代表的なサービス用 (ウェルノウンポート)、1024〜49151 が登録済みの番号、49152〜65535 が接続する側が一時的に使う番号です。
覚えておきたい番号は次のとおりです。試験の問題文やファイアウォールの設定に、説明なしで出てきます。
| ポート | プロトコル | 用途 |
|---|---|---|
| 22 | TCP | SSH (Linux のサーバーに遠隔ログイン) |
| 25 | TCP | SMTP (メールの送信) |
| 53 | UDP と TCP | DNS |
| 80 | TCP | HTTP |
| 443 | TCP (HTTP/3 は UDP) | HTTPS |
| 3306 | TCP | MySQL |
| 3389 | TCP | RDP (Windows のサーバーに遠隔ログイン) |
| 5432 | TCP | PostgreSQL |
Google Cloud ではどこに出てくるか
VPC のファイアウォールルールは、プロトコルとポートの組で許可と拒否を書きます。--allow=tcp:22 なら TCP の 22 番だけを通します。プロジェクトに最初からある default ネットワークには、SSH の tcp:22 と RDP の tcp:3389 をどこからでも受け付けるルールが入っています。本番では、VPC の設計で扱う IAP の TCP 転送を使い、22 番を開ける送信元を 35.235.240.0/20 (IAP が使う範囲) だけに絞ります。
Compute Engine の VM から外部の IP アドレスの TCP 25 番へは接続できません。VM からメールを送るときは、SendGrid などの外部サービスを 25 番以外のポートで使います (インスタンスからのメール送信)。
ロードバランサの種類を選ぶときにも、TCP と UDP の違いが効きます。HTTP や HTTPS はアプリケーションロードバランサで扱い、UDP のゲームサーバーや HTTP 以外の TCP の通信はネットワークロードバランサで扱います。
試してみる
default ネットワークのファイアウォールルールを一覧にし、ALLOW の列でプロトコルとポートの書き方を見ます。続けて、IAP の範囲からだけ SSH を受け付けるルールを作り、確かめたら消します。ルールの作成に料金はかかりません。
gcloud compute firewall-rules list --filter="network:default"
gcloud compute firewall-rules create allow-ssh-from-iap \
--network=default --direction=INGRESS \
--allow=tcp:22 --source-ranges=35.235.240.0/20
gcloud compute firewall-rules describe allow-ssh-from-iap --format="yaml(allowed,sourceRanges)"
gcloud compute firewall-rules delete allow-ssh-from-iap --quiet
次のページHTTP と TLSでは、TCP の上で動く HTTP と、それを暗号化する TLS を扱います。