こんにちは!SREとして日夜クラウドとコンテナの海を泳いでいる筆者です。
インフラの世界へ足を踏み入れたばかりの頃、「パケットが海を渡るように通信している」と言われても、なんだかピンとこないことってありませんか?特に、インターネットの裏側でこっそり行われている「NAT(Network Address Translation)」の仕組みや、そこにエラーメッセージが絡んくると、途端に頭が真っ白になってしまうものです。
今回は、パブリックサブネットとプライベートサブネットの境界線で、NATゲートウェイが「ICMP(エラーメッセージ)」をどのように受け取り、そしていかに華麗に(かつ泥臭く)宛先を書き換えてプライベートインスタンスへ届けているのか。そのドラマチックな裏側を、身近な例えを交えながら一歩ずつ紐解いていきましょう!
—
1. そもそもプライベートサブネットとは?(現実世界での「マンションのコンシェルジュ」)
まずは、舞台設定からおさらいしていきましょう。AWSやGCPなどのクラウド環境では、サーバーを置く場所として「パブリックサブネット」と「プライベートサブネット」を使い分けます。
- パブリックサブネット:インターネットという「大通り」に直接面している場所。グローバルIPアドレスを持っており、世界中からアクセスできます。
- プライベートサブネット:大通りからは直接見えない、セキュリティが守られた「マンションの奥まった部屋」。ここにあるサーバーたちは、自分専用のグローバルIPアドレスを持っていません。
ここで疑問が湧きますよね。「プライベートサブネットにいるサーバー(例えばデータベースやバックエンドのAPIサーバー)は、どうやってインターネット側へソフトウェアのアップデートをダウンロードしに行ったりするのでしょうか?」
ここで登場するのが、NATゲートウェイという名の「マンションの管理人さん(またはコンシェルジュ)」です。
プライベートな部屋にいるサーバー(例:10.0.1.100)が外の世界へ手紙(パケット)を出したいとき、宛先をそのままにして外に出すことはできません。外の世界には 10.0. から始まるプライベートな住所なんて存在しないからです。
そこで、管理人さんであるNATゲートウェイが、手紙の差出人を自分の住所(パブリックIPアドレス)に書き換えて、大通りへと送り出してくれます。そして、外から返事が返ってきたら、管理人さんがちゃんとメモ(変換テーブル)を見比べて、元の部屋の住人へ手紙をそっと手渡してあげるのです。この仕組みのおかげで、プライベートなサーバーも安全に外と通信できるわけですね。
—
2. 順調なときはいいけれど…「エラー」が返ってきたときの難問
さて、ここからが今回の本題です。
プライベートサブネットのサーバーが、NATゲートウェイを介してインターネット上のどこかへ通信を試みたものの、何らかの理由で「そんな宛先は存在しないよ!」あるいは「途中のルーターで通せんぼされたよ!」という悲しいお知らせ――これがネットワークの世界で言う ICMPエラー(Destination Unreachable:宛先到達不能など) です。
郵便配達に例えてみましょう。
あなたの部屋(10.0.1.100)から、NATゲートウェイさん(パブリックIP 203.0.113.5)を経由して、遠くの街の宛先へ手紙を出しました。ところが、その途中の道が工事中で通行止めになっており、途中の意地悪な交通整理のおじさん(ルーター)が、こんな怒りの手紙を返してきました。
> 「おい、そこの 203.0.113.5(NATゲートウェイ)! お前が出したその手紙、宛先のビルがもう取り壊されていて届かなかったぞ!」
ここで大きな問題が発生します。
交通整理のおじさんが送ってきた怒りの手紙(ICMPパケット)の宛先は、外から見た代表者である NATゲートウェイ になっています。さらに、その封筒の中身には「どの手紙が失敗したのか」を証明するために、あなたが最初に送った手紙のヘッダー(一部)が同封されているのですが、そこには差出人として NATゲートウェイに書き換えられる前のプライベートIP (10.0.1.100) がひっそり書かれているのです。
「あれ? このエラー通知、一体どの部屋の誰宛てのものだっけ……?」
NATゲートウェイさんはパニックになってしまいます。外のルーターから届いたエラーメッセージを、そのままの宛先(NATゲートウェイ自身)で受け取っただけでは、内部のどのプライベートインスタンスがその通信をしていたのか、判断がつかないのです。
—
3. NATゲートウェイの大奮闘:ICMPパケットの「翻訳」と経路制御
さあ、ここで優秀なクラウドのネットワークエンジン(NATゲートウェイ)の出番です。
パケットが海を渡る裏側で、NATゲートウェイは次のような驚くべき「翻訳作業」を瞬時に行っています。
1. エラー通知の受信
外部のルーターから、NATゲートウェイのパブリックIP宛てに「ICMP Destination Unreachable」が届きます。
2. 中身の検視(デバッグ)
NATゲートウェイは、ICMPパケットの「おまけ(ペイロード)」として含まれている、エラーの原因となった元のIPパケットのヘッダーを覗き見ます。「おっ、これはさっき我が家の 10.0.1.100 が送ったUDP/TCPの通信だな」と、自分の記憶(NATセッションテーブル)と照らし合わせます。
3. 宛先と差出人のスマートな書き換え
- 外向きのIPヘッダー:宛先をNATゲートウェイ自身から、元のプライベートインスタンス (
10.0.1.100) に書き換えます。 - 内包されている元のパケットヘッダー:ここが一番重要です! 外部に見せた仮の姿(パブリックIPとポート)から、内部の本当の姿(プライベートIPとポート)へと、綺麗に逆変換(デNAT)します。
4. 内部への転送
こうして綺麗に翻訳されたICMPエラーパケットは、プライベートサブネットのルートテーブルに従って、無事に元のプライベートインスタンスへと届けられます。
これによって、プライベートインスタンス側は「あ、自分が送ったあのリクエスト、途中で拒絶されたんだな」と正確に知ることができるのです。一歩ずつ見ていくと、いかに緻密にパケットが組み替えられているかが分かりますよね。
—
4. 実務で役立つ!インフラ構築と検証のポイント
ここからは、実際にクラウド環境(AWSのVPCを想定)でこのネットワークの挙動を意識・検証するための実践的なアプローチを見ていきましょう。
設定の基本構成イメージ(Terraform風)
プライベートサブネットからインターネット(およびそこからのICMP応答)を正しくハンドリングするためには、ルートテーブルのルーティングが命綱になります。
# プライベートサブネット用のルートテーブル
resource "aws_route_table" "private" {
vpc_id = aws_vpc.main.id
# 0.0.0.0/0(すべてのインターネット向け通信)の宛先をNATゲートウェイに向ける
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.main.id
}
tags = {
Name = "sample-private-route-table"
}
}
この設定によって、プライベートインスタンスから発信されたすべての外向きパケット(および返ってくる正常なパケット・ICMPエラー)が、必ずNATゲートウェイを通過するように強制されます。
トラブルシューティング:パケットが届かないときの確認手順
もし「プライベートサブネットから外部へ接続テスト(ping や curl)をしたのに、エラーの理由が返ってこなくてタイムアウトしてしまう」という壁にぶぶつかったら、以下のポイントを上から順に疑ってみましょう。
1. セキュリティグループとネットワークACLの確認
ICMPパケット(特にType 3:Destination Unreachableや、Type 4:Source Quenchなど)は、ステートフルなファイアウォールであっても、ルールが漏れているとブロックされがちです。
- 特にプライベートサブネット側のネットワークACLで、
ICMPトラフィック(タイプ3など)がインバウンド(受信)を許可されているか確認しましょう。
2. パスMTUディスカバリー(PMTUD)のブラックホール問題
大きなパケットを送った際に、途中のルーターが「大きすぎて通せないよ!」というICMPエラー(Fragmentation Needed)を返してくることがあります。もしこのICMPメッセージがNATゲートウェイやセキュリティグループで途中でドロップ(破棄)されてしまうと、通信が完全に固まる「PMTUDブラックホール現象」が発生します。
- クラウド上のインスタンスやコンテナ(KubernetesのPodなど)で、
mss-clamping(MSSの自動調整)が有効になっているか、あるいはネットワークインターフェースのMTUサイズが適切(標準的な1500、もしくはJumbo Frame対応環境での適切な値)に設定されているかを確認することが、現場での泥臭いトラブルシューティングの大きな鍵となります。
—
5. まとめ
今回は、少し難しく感じられがちな「NATゲートウェイにおけるICMPエラーパケットの変換と経路制御」について、郵便配達の例えを交えながら解説しました。
- プライベートサブネットのサーバーが発した通信に対するエラーは、外の世界からはNATゲートウェイの姿で見えている。
- NATゲートウェイは、賢くセッションテーブルを参照しながら、届いたICMPエラーの宛先だけでなく内包されている元のパケット情報まで丁寧に翻訳(デNAT)して内部へ戻している。
- ネットワークのトラブルシューティングでは、ICMPエラーが途中でドロップされていないか(セキュリティグループやACL、MTU設定)を疑うことが解決への近道である。
クラウドやコンテナネットワークの裏側では、こうしたパケットの「翻訳劇」が毎秒何万回も行われています。仕組みを一つひとつ紐解いていけば、決して魔法の箱ではなく、非常に論理的で美しいエンジニアリングの塊であることが分かりますよね。
それでは、また次回のインフラ探訪でお会いしましょう!快適なクラウドライフを!
コメント