AWS Networking

NAT ゲートウェイの
タイムアウト動作

350秒のアイドルタイムアウト、RSTパケットによる強制切断、
TCP Keepaliveによる対策を「喫茶店のたとえ」で完全理解

最初に押さえるポイント

Point 1
350秒ルール
NAT ゲートウェイは350秒以上アイドル状態の接続を自動的にタイムアウトさせる
Point 2
RSTパケットで強制切断
タイムアウト後は FIN(正常終了)ではなく RST(強制リセット)を送信し、接続を再利用できなくする
Point 3
デフォルトでは防げない
Linux の TCP Keepalive 初期値は7200秒(2時間)で、350秒のタイムアウトよりはるかに長い
Point 4
Keepalive間隔を300秒以下に
TCP Keepalive 間隔を350秒未満(推奨300秒)に設定すれば、接続を維持できる

喫茶店のたとえで理解する

NAT ゲートウェイのタイムアウトは「喫茶店の席管理」にそっくりです。席に座ったまま何も注文せず放置すると、店員が強制的に席を片付ける仕組みです。

喫茶店のたとえ AWS の実際
喫茶店の店員(席管理係) NAT ゲートウェイ
お客さん(席に座っている人) TCP 接続(クライアント)
注文や会話がない放置時間 アイドル状態(データ転送なし)
「5分50秒ルール」(放置制限時間) 350秒のアイドルタイムアウト
「お会計をどうぞ」(丁寧に退店を促す) FIN パケット(正常切断)
「退店してください!」(強制的に追い出す) RST パケット(強制リセット)
定期的にコーヒーを追加注文する TCP Keepalive(定期的な生存確認パケット)

NAT ゲートウェイのタイムアウト動作

NAT ゲートウェイは、プライベートサブネットのリソースがインターネットに通信する際の出口となるサービスです。内部的に接続の追跡テーブル(コネクショントラッキング)を維持しますが、リソース管理のために350秒間データ転送がない接続を自動的に終了させます。

重要:タイムアウト後に外部サーバーが返すレスポンスは、NATゲートウェイの接続テーブルに該当エントリがないため破棄されます。これにより長時間実行クエリ(DBの大量集計処理など)の結果がクライアントに届かなくなります。

FIN パケット vs RST パケット

TCP 接続の終了には2種類の方法があります。喫茶店のたとえに置き換えると、その違いが明確になります。

FIN(正常終了)

「お会計をどうぞ」

店員がお客さんに丁寧にお会計を促す。お客さんは荷物をまとめ、支払いを済ませてから退店。双方合意のうえで接続を閉じる、正常な手順。

RST(強制リセット)

「退店してください!」

店員がテーブルを片付けてお客さんを強制退店させる。お客さんは荷物を取りに戻ることもできない。NATゲートウェイのタイムアウト後はこちらが送信される。

TCP 接続のライフサイクル

TCP 接続は4つの段階を経て進行します。NAT ゲートウェイのタイムアウトは「③ アイドル状態」で発生します。

1
接続確立
TCP 3ウェイハンドシェイク(SYN → SYN-ACK → ACK)で接続を確立
2
データ転送
アプリケーションデータの送受信。NATゲートウェイが通信を中継
3
アイドル状態
データ転送がない状態。350秒を超えるとNATゲートウェイがタイムアウト
4
切断
FIN(正常)またはRST(強制)で接続終了。タイムアウト後はRSTが送信される
よくある落とし穴:長時間実行のDBクエリを送信後、クエリの処理中にクライアント側は「データ転送なし」の状態が続きます。サーバー側では処理が進行中でも、NAT ゲートウェイ側から見ると「アイドル状態」と判定されるのがこの問題のポイントです。

TCP Keepalive で接続を維持する

TCP Keepalive は、アイドル状態の接続を維持するためにTCPプロトコルに組み込まれた仕組みです。一定間隔で小さな「生存確認」パケットを送信し、ネットワーク機器に「この接続はまだ使っています」と伝えます。

数値で見る問題と対策

7,200秒
Linux デフォルト Keepalive
約2時間(長すぎる!)
350秒
NAT GW タイムアウト
約5分50秒(固定値)
300秒
推奨 Keepalive 設定
350秒よりも短く設定
ポイント:Keepalive パケットは非常に小さな「ping」のようなパケットです。アプリケーションデータは含まれませんが、NAT ゲートウェイの接続トラッキングテーブル上のアイドルタイマーをリセットする効果があります。

具体的な対策と設定方法

1

TCP Keepalive を有効化

一定間隔でKeepaliveパケットを送信し、NATゲートウェイに対して接続がアクティブであることを通知します。

2

間隔を300秒以下に設定

NAT GW のタイムアウト(350秒)よりも短い間隔に設定することで、タイムアウト前にアイドルタイマーをリセットします。

Linux(sysctl)での設定

Linux — sysctl.conf
# TCP Keepalive を300秒で有効化(NAT GW 350秒タイムアウト対策)

# アイドル状態からKeepaliveを送信するまでの時間
net.ipv4.tcp_keepalive_time = 300

# Keepalive応答がない場合の再送間隔(秒)
net.ipv4.tcp_keepalive_intvl = 60

# 応答がない場合に諦めるまでの再送回数
net.ipv4.tcp_keepalive_probes = 5
即時反映コマンド
# 即時反映する場合
sudo sysctl -w net.ipv4.tcp_keepalive_time=300
sudo sysctl -w net.ipv4.tcp_keepalive_intvl=60
sudo sysctl -w net.ipv4.tcp_keepalive_probes=5

# 永続化する場合は /etc/sysctl.conf に追記して
sudo sysctl -p

アプリケーションレベルでの設定(Python / boto3)

Python — ソケットレベルの Keepalive 設定
import socket

# ソケットを作成してKeepaliveを有効化
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# TCP Keepalive を有効にする
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)

# Keepalive 送信開始までのアイドル時間(秒)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 300)

# Keepalive パケットの再送間隔(秒)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 60)

# 応答なしで切断するまでの再送回数
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 5)
設定のまとめ:tcp_keepalive_time = 300 を設定すれば、300秒ごとにKeepaliveが送信され、NAT GW の350秒タイムアウトに達する前にアイドルタイマーがリセットされます。長時間実行クエリ中も接続が維持され、レスポンスが確実にクライアントに届きます。

よくある質問

いいえ、NAT ゲートウェイのアイドルタイムアウト(350秒)はAWSによって固定されており、ユーザーが変更することはできません。そのため、クライアント側で TCP Keepalive を有効にしてタイムアウトを回避する必要があります。

Amazon CloudWatch の「NATGateway」名前空間で確認できます。IdleTimeoutCount メトリクスが上昇している場合、タイムアウトが発生していることを示しています。CloudWatch アラームを設定して監視することを推奨します。

はい。EC2 からプライベートサブネット経由で RDS に接続しており、NAT ゲートウェイを経由する構成の場合、長時間実行クエリ中にタイムアウトが発生する可能性があります。ただし、VPC内の通信(同一VPC内のRDS接続など)はNATゲートウェイを通らないため、影響を受けないケースも多いです。外部DB接続時に特に注意が必要です。

はい。NAT ゲートウェイは UDP の場合は120秒のアイドルタイムアウトが適用されます。TCPの350秒よりも短いため、UDP通信ではさらに注意が必要です。

ALB(Application Load Balancer)にもアイドルタイムアウト(デフォルト60秒、変更可能)がありますが、こちらはユーザーが値を調整できます。NLB(Network Load Balancer)は350秒の固定タイムアウトです。NATゲートウェイと同様に、NLBではクライアント側でのKeepalive設定が重要になります。

まとめ

項目 内容
タイムアウト値 350秒(固定・変更不可)
タイムアウト時の挙動 RST パケットを送信(接続の再利用不可)
監視メトリクス CloudWatch の IdleTimeoutCount
対策 TCP Keepalive を 350秒未満に設定
推奨 Keepalive 間隔 300秒(tcp_keepalive_time = 300)
Linux デフォルト値 7200秒(そのままでは対策にならない)
喫茶店のたとえに戻ると:NATゲートウェイは「5分50秒放置で強制退店させる店員」です。追い出されないためには、300秒ごとに「追加注文」(Keepalive)すればOK。これだけで、長時間クエリの応答がクライアントに確実に届くようになります。

Created by SSuzuki1063

AWS SAP Learning Resources