Day 3: TCP/IPプロトコルスイート
今日学ぶこと
- TCP/IP 4層モデルの詳細
- IP(Internet Protocol)とIPv4ヘッダの構造
- TCPの3ウェイハンドシェイクと信頼性のある通信
- UDPのコネクションレス通信
- ポート番号とソケット
- パケットキャプチャの基礎
TCP/IP 4層モデルの詳細
TCP/IPモデルは、実際のインターネット通信で使われるプロトコルスタックです。Day 1で概要を学びましたが、ここでは各層のプロトコルを詳細に見ていきます。
flowchart TB
subgraph TCPIP["TCP/IP プロトコルスタック"]
subgraph App["アプリケーション層"]
HTTP["HTTP"]
DNS["DNS"]
SMTP["SMTP"]
FTP["FTP"]
SSH["SSH"]
end
subgraph Trans["トランスポート層"]
TCP["TCP"]
UDP["UDP"]
end
subgraph Net["インターネット層"]
IP["IP"]
ICMP["ICMP"]
ARP["ARP"]
end
subgraph Link["ネットワークアクセス層"]
ETH["Ethernet"]
WIFI["Wi-Fi"]
end
end
App --> Trans --> Net --> Link
style App fill:#ef4444,color:#fff
style Trans fill:#8b5cf6,color:#fff
style Net fill:#3b82f6,color:#fff
style Link fill:#22c55e,color:#fff
style TCPIP fill:#1e293b,color:#fff
IP(Internet Protocol)
IPはインターネット層の中核プロトコルで、パケットのアドレッシングとルーティングを担当します。コネクションレスでベストエフォートのプロトコルです(信頼性はTCPに任せる)。
IPv4ヘッダの構造
IPv4ヘッダは最小20バイト(オプションなし)で構成されます。
flowchart TB
subgraph IPv4["IPv4ヘッダ(20バイト)"]
direction TB
Row1["バージョン(4) | IHL(4) | ToS(8) | 全長(16)"]
Row2["識別子(16) | フラグ(3) | フラグメントオフセット(13)"]
Row3["TTL(8) | プロトコル(8) | ヘッダチェックサム(16)"]
Row4["送信元IPアドレス(32)"]
Row5["宛先IPアドレス(32)"]
end
Row1 --- Row2 --- Row3 --- Row4 --- Row5
style Row1 fill:#3b82f6,color:#fff
style Row2 fill:#f59e0b,color:#fff
style Row3 fill:#8b5cf6,color:#fff
style Row4 fill:#22c55e,color:#fff
style Row5 fill:#ef4444,color:#fff
style IPv4 fill:#1e293b,color:#fff
| フィールド | サイズ | 説明 |
|---|---|---|
| バージョン | 4ビット | IPのバージョン(IPv4 = 4) |
| IHL | 4ビット | ヘッダ長(32ビット単位) |
| ToS | 8ビット | サービスタイプ(QoS用) |
| 全長 | 16ビット | パケット全体の長さ(最大65535バイト) |
| 識別子 | 16ビット | フラグメントの識別に使用 |
| フラグ | 3ビット | フラグメント制御 |
| フラグメントオフセット | 13ビット | フラグメントの位置 |
| TTL | 8ビット | ルーターを通過するたびに1減少。0でパケット破棄 |
| プロトコル | 8ビット | 上位プロトコル(6=TCP、17=UDP) |
| チェックサム | 16ビット | ヘッダのエラー検出 |
| 送信元IP | 32ビット | 送信元IPアドレス |
| 宛先IP | 32ビット | 宛先IPアドレス |
IPフラグメンテーション
ネットワークのMTU(Maximum Transmission Unit) よりも大きなパケットは、複数のフラグメントに分割されます。Ethernetの標準MTUは1500バイトです。
flowchart LR
subgraph Original["元のパケット(3000バイト)"]
O["IPヘッダ + 2980バイトのデータ"]
end
subgraph Frag["フラグメント化"]
F1["フラグメント1\nIPヘッダ + 1480バイト\nオフセット: 0\nMF=1"]
F2["フラグメント2\nIPヘッダ + 1480バイト\nオフセット: 185\nMF=1"]
F3["フラグメント3\nIPヘッダ + 20バイト\nオフセット: 370\nMF=0"]
end
O --> F1
O --> F2
O --> F3
style Original fill:#3b82f6,color:#fff
style Frag fill:#f59e0b,color:#fff
- MF(More Fragments)フラグ: 後続のフラグメントがある場合は1
- フラグメントオフセット: 元のデータの位置を8バイト単位で示す
- フラグメントの再組み立ては宛先ホストで行われる
TCP(Transmission Control Protocol)
TCPは、信頼性のあるコネクション型プロトコルです。データが確実に順序通りに届くことを保証します。
TCPヘッダの構造
| フィールド | サイズ | 説明 |
|---|---|---|
| 送信元ポート | 16ビット | 送信元のポート番号 |
| 宛先ポート | 16ビット | 宛先のポート番号 |
| シーケンス番号 | 32ビット | 送信データのバイト位置 |
| 確認応答番号 | 32ビット | 次に受信を期待するバイト位置 |
| フラグ | 6ビット | SYN、ACK、FIN、RST、PSH、URG |
| ウィンドウサイズ | 16ビット | 受信バッファのサイズ |
| チェックサム | 16ビット | エラー検出 |
3ウェイハンドシェイク
TCP接続は3ウェイハンドシェイクで確立されます。
sequenceDiagram
participant C as クライアント
participant S as サーバー
Note over C: CLOSED
Note over S: LISTEN
C->>S: SYN (seq=100)
Note over C: SYN_SENT
S->>C: SYN+ACK (seq=300, ack=101)
Note over S: SYN_RECEIVED
C->>S: ACK (seq=101, ack=301)
Note over C: ESTABLISHED
Note over S: ESTABLISHED
C->>S: データ送信開始
- SYN: クライアントが接続要求を送信(初期シーケンス番号を通知)
- SYN+ACK: サーバーが接続を受け入れ、自身のシーケンス番号を通知
- ACK: クライアントが確認応答を送信。接続確立
TCP接続の終了(4ウェイハンドシェイク)
sequenceDiagram
participant C as クライアント
participant S as サーバー
C->>S: FIN (seq=500)
Note over C: FIN_WAIT_1
S->>C: ACK (ack=501)
Note over C: FIN_WAIT_2
Note over S: CLOSE_WAIT
S->>C: FIN (seq=800)
Note over S: LAST_ACK
C->>S: ACK (ack=801)
Note over C: TIME_WAIT
Note over S: CLOSED
Note over C: CLOSED(2MSL後)
フロー制御(スライディングウィンドウ)
TCPはスライディングウィンドウ方式でフロー制御を行います。受信側はウィンドウサイズを通知し、送信側はその範囲内でデータを送信します。
flowchart LR
subgraph Window["スライディングウィンドウ"]
direction LR
Sent["送信済み\n確認済み"]
InFlight["送信済み\n未確認"]
Ready["送信可能"]
NotReady["送信不可"]
end
Sent --> InFlight --> Ready --> NotReady
style Sent fill:#22c55e,color:#fff
style InFlight fill:#f59e0b,color:#fff
style Ready fill:#3b82f6,color:#fff
style NotReady fill:#ef4444,color:#fff
style Window fill:#1e293b,color:#fff
- ウィンドウサイズ: 受信側が処理できるデータ量を示す
- ACKを受信するとウィンドウがスライドし、新しいデータを送信可能に
- 受信側のバッファが一杯になるとウィンドウサイズ=0を通知(ゼロウィンドウ)
輻輳制御
ネットワークの混雑を防ぐため、TCPは以下の輻輳制御アルゴリズムを使用します。
| アルゴリズム | 動作 |
|---|---|
| スロースタート | 初期ウィンドウサイズを小さくし、ACKを受信するたびに指数的に増加 |
| 輻輳回避 | 閾値に達した後は線形に増加 |
| 高速再送 | 3つの重複ACKを受信したらパケットロスと判断して即座に再送 |
| 高速回復 | 高速再送後、スロースタートに戻らずウィンドウを半減して継続 |
UDP(User Datagram Protocol)
UDPは、コネクションレスで軽量なトランスポート層プロトコルです。信頼性よりも速度と効率を重視します。
UDPヘッダの構造
UDPヘッダはわずか8バイトです。
| フィールド | サイズ | 説明 |
|---|---|---|
| 送信元ポート | 16ビット | 送信元のポート番号 |
| 宛先ポート | 16ビット | 宛先のポート番号 |
| データ長 | 16ビット | UDPヘッダ + データの長さ |
| チェックサム | 16ビット | エラー検出(IPv4ではオプション) |
TCP vs UDP
| 特徴 | TCP | UDP |
|---|---|---|
| 接続 | コネクション型 | コネクションレス |
| 信頼性 | 高い(再送、順序保証) | なし(ベストエフォート) |
| ヘッダサイズ | 20バイト〜 | 8バイト |
| 速度 | 遅い(オーバーヘッド大) | 速い(オーバーヘッド小) |
| フロー制御 | あり | なし |
| 輻輳制御 | あり | なし |
| 用途 | Web、メール、ファイル転送 | DNS、動画ストリーミング、VoIP、ゲーム |
flowchart TB
subgraph Decide["TCP or UDP?"]
Q["信頼性が必要?"]
Q -->|"はい"| TCP["TCP\nHTTP, SMTP, FTP, SSH"]
Q -->|"いいえ"| Q2["リアルタイム性が重要?"]
Q2 -->|"はい"| UDP["UDP\nDNS, VoIP, ゲーム, 動画"]
Q2 -->|"いいえ"| TCP
end
style TCP fill:#3b82f6,color:#fff
style UDP fill:#22c55e,color:#fff
style Q fill:#f59e0b,color:#fff
style Q2 fill:#8b5cf6,color:#fff
style Decide fill:#1e293b,color:#fff
ポート番号とソケット
ポート番号
ポート番号は、同一ホスト上の複数のアプリケーションを識別するための16ビットの数値(0〜65535)です。
| 範囲 | 種類 | 説明 |
|---|---|---|
| 0〜1023 | ウェルノウンポート | 標準的なサービス(root権限が必要) |
| 1024〜49151 | 登録ポート | IANAに登録されたアプリケーション |
| 49152〜65535 | 動的/エフェメラルポート | クライアント側で一時的に使用 |
主要なウェルノウンポート
| ポート番号 | プロトコル | サービス |
|---|---|---|
| 20/21 | TCP | FTP(データ/制御) |
| 22 | TCP | SSH |
| 23 | TCP | Telnet |
| 25 | TCP | SMTP |
| 53 | TCP/UDP | DNS |
| 80 | TCP | HTTP |
| 110 | TCP | POP3 |
| 143 | TCP | IMAP |
| 443 | TCP | HTTPS |
| 3306 | TCP | MySQL |
| 5432 | TCP | PostgreSQL |
ソケット
ソケットは、IPアドレスとポート番号の組み合わせで一意に通信の端点を識別します。
ソケット = IPアドレス : ポート番号
例: 192.168.1.10:443
TCP通信は、送信元ソケットと宛先ソケットの組み合わせ(コネクション)で一意に識別されます。
コネクション = (送信元IP:送信元ポート, 宛先IP:宛先ポート)
例: (192.168.1.10:52431, 93.184.216.34:443)
パケットキャプチャの基礎
tcpdump
# Capture packets on eth0
sudo tcpdump -i eth0
# Capture only TCP packets on port 80
sudo tcpdump -i eth0 tcp port 80
# Capture packets and save to file
sudo tcpdump -i eth0 -w capture.pcap
# Show packet details (verbose)
sudo tcpdump -i eth0 -v
# Capture 3-way handshake (SYN packets)
sudo tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0'
Wireshark
WiresharkはGUIベースのパケットアナライザです。tcpdumpで取得したpcapファイルを読み込んで詳細に分析できます。
主な表示フィルタ:
| フィルタ | 説明 |
|---|---|
tcp |
TCPパケットのみ表示 |
udp |
UDPパケットのみ表示 |
ip.addr == 192.168.1.1 |
特定IPアドレスのパケット |
tcp.port == 80 |
TCP ポート80のパケット |
http |
HTTPトラフィック |
tcp.flags.syn == 1 |
SYNフラグが立っているパケット |
tcp.analysis.retransmission |
TCP再送パケット |
TCPハンドシェイクのキャプチャ例
# Capture a TCP 3-way handshake to example.com
sudo tcpdump -i eth0 -c 3 host example.com and tcp
# Expected output:
# 1. SYN: client > server [S] seq 12345
# 2. SYN+ACK: server > client [S.] seq 67890 ack 12346
# 3. ACK: client > server [.] ack 67891
まとめ
本日の学習内容
| トピック | ポイント |
|---|---|
| TCP/IP 4層モデル | アプリケーション、トランスポート、インターネット、ネットワークアクセス |
| IPv4ヘッダ | 20バイトの最小ヘッダ。TTL、プロトコル、送信元/宛先IPが重要 |
| TCP | コネクション型。3ウェイハンドシェイク、フロー制御、輻輳制御 |
| UDP | コネクションレス。8バイトヘッダ。リアルタイム通信に最適 |
| ポートとソケット | ポート番号でアプリケーションを識別。IP+ポート=ソケット |
| パケットキャプチャ | tcpdumpとWiresharkで通信を可視化・分析 |
キーポイント
- IPはベストエフォート: 信頼性はTCPが担保する
- 3ウェイハンドシェイク: SYN → SYN+ACK → ACK でTCP接続を確立
- TCP vs UDP: 信頼性が必要ならTCP、リアルタイム性が必要ならUDP
- ウェルノウンポート: HTTP=80、HTTPS=443、DNS=53、SSH=22 を最低限覚える
- tcpdump/Wireshark: ネットワーク障害調査に不可欠なツール
練習問題
基礎レベル
- TCPの3ウェイハンドシェイクの3つのステップを説明してください。
- TCP と UDP の違いを3つ挙げてください。
- 以下のポート番号に対応するサービスを答えてください:80、443、22、53。
中級レベル
- IPv4ヘッダのTTLフィールドの役割と、なぜ必要なのかを説明してください。
- Webブラウザで
https://example.comにアクセスする際、使用されるプロトコルとポート番号をトランスポート層とアプリケーション層それぞれで答えてください。 - TCPのスライディングウィンドウ方式がなぜ効率的なのか、Stop-and-Wait方式と比較して説明してください。
チャレンジレベル
- TCPの輻輳制御において、「スロースタート」と「輻輳回避」の動作を具体的な数値例を使って説明してください。輻輳ウィンドウの初期値を1 MSS、閾値を16 MSSとします。
- 以下のtcpdump出力を解析し、何が起きているか説明してください。
10:00:00.000 192.168.1.10.52431 > 93.184.216.34.443: Flags [S], seq 1000 10:00:00.050 93.184.216.34.443 > 192.168.1.10.52431: Flags [S.], seq 2000, ack 1001 10:00:00.051 192.168.1.10.52431 > 93.184.216.34.443: Flags [.], ack 2001 - DNSが主にUDPを使用する理由と、TCPを使用するケースを説明してください。
参考リンク
- RFC 793 - Transmission Control Protocol
- RFC 768 - User Datagram Protocol
- RFC 791 - Internet Protocol
- Wireshark Documentation
次回予告
Day 4: IPアドレス、NAT、DHCP では、IPv4のクラスとCIDR表記、サブネットの計算方法、NAT(ネットワークアドレス変換)の仕組み、DHCPによる自動アドレス割り当て、そしてIPv6の概要を学びます。