本文へスキップ
hdknr blog
戻る

AWS の NAT ゲートウェイとは何か — 「唯一の出口」を消して本番が止まった話から考える

AWS で Web アプリを組むと、たいてい構成図の片隅に「NAT Gateway」が描かれています。 月数十ドルかかるわりに何をしているのか見えにくく、コスト削減やリソース整理のときに 「これ、要るの?」と真っ先に疑われがちなリソースです。

本記事では、NAT ゲートウェイの役割と一般的な使われ方を整理したうえで、 Auto Scaling 配下の Web サーバーがプライベートサブネットにいる構成で NAT ゲートウェイを使う利点を解説します。 後半では、整理の過程で NAT ゲートウェイが削除され、本番の外向き通信が全停止した事例を紹介します(匿名化しています)。 そこから得た教訓もまとめます。


1. NAT ゲートウェイとは

NAT(Network Address Translation)ゲートウェイ(以下、文脈によって単に「NAT」とも書きます)は、 プライベートサブネットにあるリソースが、インターネットへ「出ていく」ための出口です。

プライベートサブネットの EC2 からルートテーブルの 0.0.0.0/0 経路で、パブリックサブネットの NAT ゲートウェイ(EIP)、インターネットゲートウェイを経てインターネットへ出ていく流れ。内から外へは通れるが、外から内への接続開始は通れない

ポイントは 一方通行 であることです。

方向NAT ゲートウェイ経由で可能か
内 → 外(インスタンスから外部 API を呼ぶ)できる
外 → 内(インターネットからインスタンスへ接続を開始する)できない

つまり「外には出られるが、外からは入られない」状態を作るための部品です。

マネージドであること

NAT の機能自体は EC2 インスタンス 1 台(NAT インスタンス)でも作れますが、 NAT ゲートウェイは AWS のマネージドサービスです。


2. 一般的な使われ方

2-1. 典型的な 3 層構成

典型的な 3 層構成。パブリックサブネットに入口の ALB と出口の NAT ゲートウェイを置き、プライベートサブネットの Web・アプリサーバーはリクエストを ALB から受け、外向き通信は NAT ゲートウェイ経由で行い、さらに奥のプライベートサブネットの DB に接続する

2-2. 「外に出たい」場面はけっこう多い

アプリサーバーが外へ出る用途は、思っているより多いものです。

2-3. 送信元 IP を固定する

NAT ゲートウェイのもう一つの重要な役割が 送信元 IP の固定 です。 プライベートサブネットのインスタンスが何台あっても、外から見える送信元 IP は NAT ゲートウェイの EIP 1 つに揃います。

このため、相手側で 接続元 IP 制限(IP アローリスト) をかけるケースで重宝されます。

2-4. 冗長化の考え方

NAT ゲートウェイは AZ 単位のリソースです。

小規模なシステムでは後者の 1 本構成もよく見かけます。


3. 事例:Auto Scaling 配下の Web アプリ

ここからは、ある申し込み受付システム(以下「申し込みシステム」)の構成を例にします。

申し込みシステムの構成。インターネットから CDN と ALB を経て、パブリック IP のないプライベートサブネットにある Auto Scaling グループ配下の Web 用 EC2 へ届く。EC2 は RDS(Multi-AZ)に直接接続し、S3 や外部 API・SaaS へは EIP 1 つの NAT ゲートウェイを唯一の出口として通信する

アプリサーバーが NAT ゲートウェイ経由で通信している相手は次のとおりです。

通信先用途相手側の接続元 IP 制限
決済代行 APIカード登録・照会なし
CRM SaaS申し込み・お問い合わせの連携あり
Amazon SESメール送信あり(IAM の aws:SourceIp)
Amazon S3書類・画像の保存と表示あり(IAM の aws:SourceIp)
SMS 配信サービス通知—
GitHubデプロイ時の git pull—

つまりこの NAT ゲートウェイは、アプリサーバーにとって 唯一の外向きの出口 であり、 同時に 複数の IP アローリストに登録された「身元」 でもあります。


4. この構成で NAT ゲートウェイを使う利点

利点 1:アプリサーバーをインターネットに晒さない

アプリサーバーにパブリック IP を付けずに済むので、 入口は ALB(とその前段の CDN / WAF)だけ に絞れます。

もし NAT をやめて、アプリサーバーをパブリックサブネットに置き EIP を付けたとします。 するとセキュリティグループの設定次第では、CDN・ALB・WAF を迂回して インスタンスに直接アクセスできてしまいます。 NAT 構成なら、仮にセキュリティグループが緩くても、 インターネットから直接到達する経路そのものがありません(多層防御)。

利点 2:Auto Scaling でインスタンスが入れ替わっても送信元 IP が変わらない

Auto Scaling グループ配下のインスタンスは、ヘルスチェックの失敗やスケールアウトで いつでも作り直されます。インスタンスに EIP を直接付ける構成だと、

という問題が出ます。NAT ゲートウェイを使えば、何台に増えても、何度入れ替わっても、 外から見える送信元 IP は EIP 1 つのまま です。

利点 3:IP アローリストの管理が 1 か所で済む

利点 2 の裏返しですが、外部 SaaS・IAM ポリシー・SPF などに登録する IP が 1 つ で済みます。

インスタンスごとに EIP を持たせると、最大 2 台にスケールする構成なら 2 つの IP を すべてのアローリストに登録しておく必要があります。 ふだんは 1 台で動いていて、負荷が上がってスケールしたときだけ 2 台目の IP で外に出る、 という状況は、登録漏れがあっても平常時には気づけず、 「ピーク時だけメールが送れない」「たまに画像が表示されない」という 非常に見つけにくい障害になります。

利点 4:運用の手間が少ない

NAT インスタンスと違い、OS 更新・監視・冗長化の面倒を自分で見る必要がありません。 小規模なチームで本番を運用する場合、月数十ドルでこの手間を AWS に任せられるのは大きな利点です。

コスト比較の目安

以上の利点を、費用と比べてみます。

構成月額の目安主な課題
NAT ゲートウェイ 1 本約 $49(NAT 本体 約 $45 + EIP 約 $3.6)+ 処理量費用
インスタンスごとに EIP1 個あたり約 $3.6 × 台数利点 1〜3 をすべて失う
NAT インスタンス(小さい EC2)数ドル〜パッチ・監視・冗長化を自前で

インスタンスごとに EIP を付ける構成に変えても、Web 1〜2 台なら削減できるのは月 $40〜45 程度です。 その削減と引き換えに、「外に出る経路」と「1 つに揃った送信元 IP」という NAT ゲートウェイが担っている 2 つの役割を別の仕組みで用意し直すのは、割に合わないことが多いでしょう。


5. 事例:NAT ゲートウェイが消えた日

この申し込みシステムでは、AWS アカウント内のリソース整理の過程で、 NAT ゲートウェイと、それに付いていた EIP が削除 されました。

棚卸しの時点で、その NAT ゲートウェイは次のように見えていました。

使われていない VPC の 1 本と並べると、本番側の NAT も「消してよさそう」に見えました。 しかし実際には、こちらが本番の唯一の出口でした。

何が起きたか

フェーズ事象
NAT 削除直後外向き通信が全停止。外部 API を待つリクエストがタイムアウトし、ALB が 504 を返す
削除〜再構築応答待ちのリクエストで PHP-FPM(PHP を実行するワーカープロセス群)の同時処理枠が埋まり、ヘルスチェックが失敗。Auto Scaling がインスタンスを何度も作り直した(入れ替わるたびにローカルのログも消える)
NAT 再構築後外には出られるようになったが、EIP が新しい IP に変わった(元の IP は取り戻せなかった)
再構築後〜数時間IP アローリストに引っかかる症状が順に表面化(下記)

再構築後に出た症状は次のとおりです。

NAT の再構築で「出口」は戻っても、IP アローリストに登録されていた「身元」は戻らなかった のです。 しかも IAM の aws:SourceIp 条件は構成ドキュメントに書かれておらず、 症状が出るたびに 1 つずつ見つけて直すことになりました。

教訓

  1. NAT ゲートウェイの EIP は「誰にも割り当てられていない」ように見えるが、実は使われている。 EIP の棚卸しでは、割り当て先が NAT かどうかを必ず確認する。

  2. 削除前にルートテーブルを見る。 そのサブネットの 0.0.0.0/0 が NAT を指していて、 かつそのサブネットに稼働中のインスタンスがあるなら、それは使われている。 データ処理量の少なさは「使われていない」根拠にならない。

  3. 解放した EIP が戻ってくる保証はない。 他の AWS アカウントに割り当てられていなければ aws ec2 allocate-address --domain vpc --address <解放した IP> で取り戻せる場合もあるが、確実ではない。 削除の前に、その IP を登録しているアローリストを洗い出す。

  4. IP 依存はドキュメントに書く。 外部 SaaS の許可設定、IAM の aws:SourceIp、SPF レコードなど、 「NAT の EIP が変わったら直す箇所」の一覧を持っておく。IAM の条件は、次のように総当たりで探せる(要 jq)。

    # aws:SourceIp を含むポリシーを探す(インラインポリシーとカスタマー管理ポリシー)
    aws iam get-account-authorization-details --output json \
      --filter User Role Group LocalManagedPolicy \
      | jq '.. | objects | select(has("Condition")) | select(.Condition | tostring | test("SourceIp"))'

    --filter を外すと AWS 管理ポリシーまで出力されて大量になります。 また test("SourceIp") は部分一致なので aws:VpcSourceIp なども拾い、 出力はステートメント単位なのでどのポリシーのものかは前後を見て判断します。 S3 のバケットポリシーなど、リソース側に付くポリシーはこのコマンドの対象外なので別途確認が必要です。

  5. 外向き通信の詰まりがヘルスチェックの失敗に連鎖しないようにする。 ヘルスチェックは PHP などを通さない静的ファイルにする、外部通信のタイムアウトを短くする、など。


6. NAT ゲートウェイへの依存を減らす選択肢

NAT ゲートウェイは便利ですが、上の事例のように「1 つの IP に多くのものがぶら下がる」と、 変更に弱くなります。NAT を残したまま、IP への依存を減らす 方向の改善が効果的です。

施策効果注意点
S3 の ゲートウェイ型 VPC エンドポイント(無料)を作るS3 への通信が NAT を通らなくなるエンドポイント経由のリクエストには aws:SourceIp が含まれず(送信元は VPC 内のプライベート IP になる)、IP 条件に一致しなくなる。条件を aws:SourceVpce / aws:SourceVpc(またはプライベート IP を見る aws:VpcSourceIp)に変える作業とセットで行う
IAM ユーザー(アクセスキー)をやめて インスタンスロール にする長期のアクセスキーがなくなり、キー漏えいに備えて IP 条件で縛る必要性が下がるアプリ側の認証情報の読み方を変える必要がある
SES などの インターフェース型 VPC エンドポイント を作るAWS API を NAT 経由にしないエンドポイントごとに時間課金がかかる。S3 と同様に aws:SourceIp 条件の見直しが要る。SES の SMTP エンドポイントは一部の AZ で使えない
企業の共通基盤が提供する 出口プロキシ を使う外向き通信を組織として一元管理できる接続先ごとに申請が必要になることが多い。送信元 IP がどうなるかを基盤側に確認する

こうして AWS API への依存を NAT から外していくと、最後まで固定 IP が必要なのは 「接続元 IP 制限をかけている外部 SaaS」だけになります。 そこは NAT ゲートウェイの EIP 1 つで受けるのが、いちばん単純で壊れにくい構成です。


まとめ

削除の前にルートテーブルとアローリストを確認し、IP 依存をドキュメントに残し、 VPC エンドポイントやインスタンスロールで依存そのものを減らしていくのがおすすめです。



前の記事
知識表現とエキスパートシステムをやさしく解説 — Microsoft AI-For-Beginners レッスン 02
次の記事
パーセプトロン入門 — 単純パーセプトロンの仕組みから多層パーセプトロン(MLP)まで