1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

AWSをTerraformで触るハンズオンをやっていて、ロードバランサの説明で「ALBはL7、NLBはL4」という一文に出くわしました。L7、L4——見覚えはあります。基礎情報の資格勉強でOSI参照モデルの7層を丸暗記した、あれです。でも正直に言うと、暗記して以来、実務でこの7層を使った記憶がほとんどありませんでした。

7層、暗記したのに使ってなくないですか? 少なくとも自分はそうでした。この記事は、その「暗記して終わったOSI」を「デバッグで毎日使える地図」に読み替えるまでの整理です。7層を空で言えるかどうかはどうでもよくて、価値は別のところにあった、という話をします。

※私はコンピュータサイエンス専攻ではないので、CS的な厳密さは今回は理解のためにある程度許容いただきたいです。

忙しい人向けの結論

問い 答え
7層の暗記は役に立つ? 名前を暗記すること自体はほぼ役に立たない
じゃあ何が価値なの? 「この不具合はどの層の話か」を切り分ける地図として使えること
具体的にどう効く? 「つながらない」を下の層から順に潰していける。当てずっぽうが消える
TCP/IPとは別物? 考え方は同じ。層を7個から4個にまとめただけ

対象読者はこのあたりを想定しています。

  • OSIの7層を暗記したが、実務での使いどころがピンときていない人
  • 「つながらない」「なぜか動かない」の調査で、いつも手当たり次第になってしまう人
  • AWSのSGやALB/NLBの説明に出てくる「L4」「L7」を雰囲気で読み流している人

参考リンク

OSI7層は「暗記するもの」ではなく「切り分けの地図」

まず7層のおさらいだけ、ざっと置いておきます。ここは読者も一度は見たはずなので、表を眺めるだけで十分です。

# 役割 代表例
7 アプリケーション アプリが使う通信サービスそのもの HTTP, DNS, SMTP
6 プレゼンテーション 表現形式の変換(文字コード・暗号化) TLS/SSL
5 セッション 通信の開始〜終了の管理 セッション管理
4 トランスポート 端点間の信頼性・ポートの振り分け TCP, UDP
3 ネットワーク ネットワーク間の経路制御(住所=IP) IP, ICMP
2 データリンク 同一ネットワーク内の隣接ノード間転送 Ethernet
1 物理 電気信号・光・電波で物理的に伝送 ケーブル

で、ここからが本題です。この表を暗記しても、実務では一度も「第5層は何でしょう?」とは聞かれません。効いてくるのは、通信を 層のスタックとして眺める視点 のほうでした。「つながらない」という漠然とした症状を、「これはL3の話? L4? それともL7?」と切り分けるための座標軸。地図だと思うと、急に使いどころが見えてきます。

通信は「送信は降りる・受信は昇る」──途中の機器はてっぺんまで昇らない

地図として使う前に、通信がこの層をどう通るかだけ押さえます。ここを誤解している人が多い(自分もそうでした)ので、図にしました。

image.png

ポイントは2つです。

ひとつ目。同じ1台の中で「L1からL7へ昇って、また降りる」わけではありません。送信側は上から下へ降りるだけ、受信側は下から上へ昇るだけ。降りるときに各層が自分のヘッダを付け足し(これをカプセル化と呼びます)、昇るときに剥がしていきます。「通信が行って戻ってくる」の正体は、リクエストとレスポンスという逆向きの2つの旅であって、1台の中の往復ではないんですね。

ふたつ目。通常のルータやスイッチは、てっぺんまで昇りません。ルータは宛先を決めるのに必要なIP(L3)まで昇ったらすぐ折り返し、スイッチはMAC(L2)までしか見ない。ただし例外があって、ALB・WAF・プロキシ・CDNのような「L7の中間機器」は、あえてL7まで開いて中身を見ます(この話は最後のAWS節で戻ってきます)。この「機器ごとに開ける層が違う」がわかると、次のロードバランサの話がスッと入ってきます。

カプセル化のイメージは、荷物を段ボールに入れて、それをさらに大きな箱に入れて…と包んでいく感じです。受け取った側は外側から順に開けていく。中身(アプリのデータ)は変えずに、各層が自分用の宛名ラベルを外側に貼っていく、と考えると腑に落ちます。

TCP/IPは別物じゃない──同じ思想を4層にまとめただけ

「じゃあ実際のインターネットもこの7層で動いてるの?」というと、そこは少しややこしい。現実に動いているのはTCP/IPモデルという4層の分け方です。ただ、これはOSIと敵対する別の考え方ではありません。層で積み上げるという思想はまったく同じで、分け方の粒度が違うだけ です。

image.png

OSIがL7・L6・L5と3つに分けたアプリ周りを、TCP/IPは「アプリケーション層」ひとつにまとめています。実装上、HTTPやTLSはアプリがまとめて面倒を見るので、細かく分ける実益が薄いんですね。物理まわり(L1・L2)も「リンク層」にまとめられています。

面白いのは、現場でよく聞く「L4ロードバランサ」「L7ロードバランサ」という言い方です。この番号はOSI由来なのに、指している中身のTCP(L4)やHTTP(L7)はTCP/IPの現実。つまり実務では、OSIの番号を借りてTCP/IPの実物を語っているわけです。両方を知っておくと、この混ざり方に戸惑わずに済みます。

なお歴史的には、TCP/IPのほうが先に普及して事実上の標準になり、OSIは後から整備された理論モデルという立ち位置です。試験ではOSIで問われ、現場ではTCP/IPで動いている——このねじれを頭の隅に置いておくと混乱しません。TCP/IPの層構成はRFC 1122で定義されています。

層で切り分けるデバッグ──下から順に土台を潰す

ここが、自分がこの記事で一番伝えたかったところです。「地図として使う」の具体がこれ。

Webアプリで「APIにつながらない」とき、原因は複数の層に散らばっています。ありがちなのは、いきなりアプリのコードを疑って延々とログを読む、でも実はSG(セキュリティグループ)でポートが閉じていただけ、みたいなやつ。自分も何度かやりました。恥ずかしい話ですが、原因が下の層にあるのに上の層をいじり続けると、時間だけが溶けていきます。

これを防ぐのが「下から順に土台を潰す」やり方です。

image.png

具体的なコマンドで追うと、こんな順番になります。

# ① 名前解決できる?(DNS = L7)
nslookup api.example.com
#   → IPが返らないなら DNS の問題。ここで止まる

# ② 相手に届く?(L3 ネットワーク)
ping api.example.com
#   → 応答なしなら経路 or ファイアウォールで遮断されている可能性

# ③ ポートは開いてる?(L4 トランスポート)
nc -zv api.example.com 443
#   → refused: ホストまでは到達、待ち受けプロセスがない(TCP RSTが返る)
#   → timed out: SG/NACL/FW/経路のどこかで破棄されている(refusedとは別物!)

# ④ TLSは成立する?(L6 プレゼンテーション)
openssl s_client -connect api.example.com:443 -servername api.example.com </dev/null
#   → 証明書エラーなら期限切れ or ドメイン不一致

# ⑤ HTTPは正しく返る?(L7 アプリケーション)
curl -v https://api.example.com
#   → 502/503: LBまでは到達、後ろのターゲットが応答していない
#   → curlは通るのにブラウザだけ失敗するなら CORS など「ブラウザ側の制約」を疑う

この順で追うと、①〜④が全部OKなら、L3・L4・TLSまでは概ね成立している と言えます。あとはHTTP層——アプリのコード、LBやWAFのルール、ブラウザ側の制約——に絞って見ればいい。逆に②で止まれば、アプリのコードをいくら読んでも無駄で、経路かファイアウォールを見に行くべきだとわかる。切り分けができると、調べる場所が一気に絞れるんです。

ICMPを塞いでいるサーバは珍しくないので、「pingが通らない = 到達不可」とは限りません。②が失敗しても、③のポート確認まではやってから経路の問題と判断するのが安全です。層で切り分けるときも、1つの結果だけで断定せず、隣の層と突き合わせるのが実戦のコツです。

エラーメッセージは「どの層で失敗したか」を教えてくれる

切り分けの視点を持つと、エラーメッセージの解像度も上がります。あの無味乾燥なメッセージたちは、実は「どの層で失敗したか」を教えてくれていました。

エラー 失敗している層 意味
Connection refused L4 ポートまで届いたが、誰も待ち受けていない
Connection timed out L3/L4 そもそも届いていない(経路 or FWで遮断)
TLS handshake failed L6 暗号化のネゴシエーションで失敗
502 Bad Gateway L7 LBまでは到達、後ろのターゲットが応答しない
CORS error L7 通信は成功、ブラウザが同一オリジンポリシーで結果をブロック

個人的に一番効いたのは、refusedtimed out は別の層の症状だと腹落ちしたことでした。refusedは「ポートまでは届いている」、timed outは「そもそも届いていない」。届いているかどうかが違うので、次に見る場所がまったく変わります。ここを混同していると、ファイアウォールを疑うべき場面でアプリの設定をいじってしまう。

AWSに引きつける──SG・ALB・NLBはどの層の話か

最後に、この地図をAWSに重ねてみます。冒頭の「ALBはL7、NLBはL4」に戻ってくる話です。

  • ALB(Application Load Balancer)は L7で動きます。HTTP/HTTPSの中身——URLのパスやホスト名、ヘッダ——を見て振り分けられる。だから「/api はこっち、/img はあっち」ができる
  • NLB(Network Load Balancer)はL4で動きます。TCP/UDPのレベルでIPとポートだけを見て高速に捌く。中身は見ない
  • セキュリティグループはL3(IP)とL4(プロトコル・ポート)の条件で許可ルールを定義します。明示的なdenyは書けず、ルールに一致しない通信は暗黙的に拒否。ステートフルなので、許可した通信の戻りは自動で通る
  • WAF(Web Application Firewall)はL7で、リクエストの中身を見て防御します

この対応がわかると、設計判断が理由つきでできるようになります。たとえば「特定のURLパスだけブロックしたい」と思っても、それはSGでは不可能です。SGはL3/L4までしか見ないので、URL(L7の情報)を条件にできない。だからL7を見るWAFが必要になる——と論理的にたどり着けます。「なんとなくWAF」ではなく「層が足りないからWAF」。この差は地味に大きいです。

おわりに

OSIの7層を暗記していたときの自分は、正直この知識に何の意味があるのかわかっていませんでした。でも「暗記するもの」ではなく「切り分けの地図」だと読み替えた瞬間に、急に手に馴染む道具になった感覚があります。

7層をそらで言える必要はないと思っています。大事なのは、目の前の「つながらない」を層にマッピングして、下から順に潰していけること。それだけで、推測と再起動の繰り返しから、根拠のある切り分けに変わります。

みなさんは最近どんな「つながらない」で溶かした時間がありますか。もしそれが下の層の見落としだったなら、次は下から順に潰してみてください。自分は今のところ、これで調査時間がだいぶ短くなっています。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?