【入門編】 TCP RSTパケットの送受信によるNATゲートウェイのセッション早期強制切断メカニズム – クラウド&コンテナネットワーク実践ガイド

皆さん、こんにちは!AWS/GCPなどのメガクラウドとKubernetesネットワークを知り尽くしたSRE兼クラウドアーキテクトの筆者が、今回はクラウドのネットワークの奥深い世界へ皆さんをご案内します。

「クラウドのネットワークって、なんだか複雑そう…」そう思っていませんか?大丈夫です!この記事を読めば、そのモヤモヤがきっとスッキリしますよ。特に今回は、クラウド環境でよく耳にする「NATゲートウェイ」というものと、ちょっと耳慣れない「TCP RSTパケット」という「緊急停止信号」が、どう連携してネットワークの安定性を支えているのかを、とっても分かりやすく紐解いていきましょう!

—

パケットの緊急停止信号!NATゲートウェイがTCP RSTをどう捌くか

🌐 クラウドのネットワーク、まずは「おうちの構造」から理解しよう!

クラウドの世界には、大きく分けて「プライベートサブネット」と「パブリックサブネット」というものがあります。これ、会社の建物に例えると分かりやすいかもしれません。

  • プライベートサブネット: 会社の「内部」です。従業員が日々の業務を行う執務室や、重要な書類を保管する倉庫のような場所。外部から直接アクセスされることはなく、セキュリティがしっかり守られています。
  • パブリックサブネット: 会社の「受付」や「玄関」です。外部からのお客様が最初に訪れる場所で、インターネットと直接通信できます。

さて、この「会社の内部(プライベートサブネット)」にいる従業員が、インターネット(外部の世界)に何か情報を送りたくなったり、インターネットから何か情報を受け取りたくなったりする時がありますよね?例えば、クラウド上のサーバー(EC2インスタンスなど)が、ソフトウェアのアップデートのためにインターネット上のリポジトリにアクセスする、といったケースです。

ここで登場するのが、今回の主役の一人「NATゲートウェイ」です!

📮 NATゲートウェイは「賢い郵便局の私書箱」!

NATゲートウェイは、例えるなら「会社の受付」であり、同時に「郵便局の私書箱」のような役割を果たします。

会社の内部(プライベートサブネット)にいるサーバーは、インターネットに直接アクセスできません。そこで、NATゲートウェイという「私書箱」を通してインターネットとやり取りをするんです。

1. 内部から外部へ: プライベートサブネットのサーバーがインターネットにアクセスしたい時、まずNATゲートウェイに「インターネットに送りたい手紙」を渡します。NATゲートウェイは、その手紙の「送り主」を自分自身(NATゲートウェイ)として書き換え、インターネットに送ります。
2. 外部から内部へ: インターネットからの返事がNATゲートウェイ(私書箱)に届いたら、NATゲートウェイは「この返事は誰宛だったかな?」と思い出し、プライベートサブネットの元のサーバーに手紙を転送します。

この「誰が誰に手紙を送っているか」という情報をNATゲートウェイが一時的に覚えておくことを「セッション」と呼びます。NATゲートウェイは、たくさんのセッション情報を管理することで、内部のサーバーが安全にインターネットと通信できるようにしているんですね。

🚨 TCP RSTパケット:「緊急停止!通信をすぐにやめるぞ!」のサイン

通常、インターネット上の通信(特にTCP通信という種類)は、電話の会話のように丁寧に行われます。

  • 「もしもし?(SYN)」
  • 「はい、もしもし。どちら様ですか?(SYN-ACK)」
  • 「〇〇です。今お話できますか?(ACK)」
  • …会話…
  • 「では、そろそろ失礼しますね(FIN)」
  • 「はい、ありがとうございました(FIN-ACK)」
  • 「(電話を切る)ガチャン(ACK)」

このように、丁寧に挨拶して始まり、丁寧に「さようなら」をして終わるのが基本です。

しかし、世の中には緊急事態もありますよね?

  • 電話をかけても、相手がもう電話を置いてしまっている。
  • 話している途中で、急に相手の電波が悪くなってブツッと切れてしまった。

こんな時、「TCP RSTパケット」が登場します!RSTは「Reset(リセット)」の略。これは、「ごめん!この通信はもう急にやめるね!」という、非常に強い「緊急停止信号」なんです。電話で例えるなら、一方的に「ガチャン!」と切ってしまうようなものです。

じゃあ、どんな時にこんな荒っぽい「緊急停止信号」が使われるのでしょうか?

  • 存在しないポートへのアクセス: 例えば、あるサーバーの「電話番号(IPアドレス)」は知っていても、「どの部署の電話(ポート番号)」にかけていいか分からないまま適当にかけてしまった場合。サーバーは「そんな部署はないよ!」とRSTで即座に通信を拒否します。
  • タイムアウトしたセッションへのパケット: 古い通信の続きのパケットが、もうとっくに終わっているセッションに届いてしまった場合。
  • 異常終了したアプリケーション: アプリケーションがクラッシュしたり、強制終了されたりして、通常の終了処理ができなかった場合。
  • ファイアウォールによる拒否: セキュリティルールによって、問答無用で通信がブロックされた場合。

✂️ NATゲートウェイとRSTパケット:セッションの早期強制切断メカニズム

さて、ここでNATゲートウェイとTCP RSTパケットがどう連携するのかが、今回の記事の核心です。

NATゲートウェイは、先ほど説明したように「誰が誰と通信しているか」というセッション情報を一時的に覚えておくとお話ししましたよね。このセッション情報には、それぞれ「アイドルタイムアウト」というタイマーが設定されています。例えば、AWSのNATゲートウェイでは、TCPセッションのアイドルタイムアウトは350秒(約5分50秒)です。これは「もし5分50秒間、このセッションで何の通信もなかったら、このセッションはもう終わったものとして、記録を消去しよう」というルールです。

しかし、もし通信の途中で先ほどの「緊急停止信号」であるTCP RSTパケットがNATゲートウェイを通過したらどうなるでしょう?

NATゲートウェイは、このRSTパケットを受け取ると、こう考えます。
「おっと!この通信、もう終わったんだな!しかも、緊急停止だって!?じゃあ、アイドルタイムアウトを待つ必要はないな!」

そして、該当するセッション情報を、即座に、問答無用で、記録から消去します! アイドルタイムアウトのカウントダウンタイマーも即座にクリアされます。

郵便局の私書箱の例で言うと、私書箱の利用者が「もうこの私書箱は使わないから、契約をすぐに解除して!」と連絡してきたら、郵便局はすぐに契約解除の手続きをして、その私書箱を別の人が使えるようにしますよね。それと同じです。

なぜこれが重要なのか?

この「RSTパケットによるセッションの早期強制切断」は、クラウド環境のネットワークの安定性と効率性にとって、とてつもなく重要な仕組みなんです。

1. リソースの解放: NATゲートウェイも有限なリソース(メモリや処理能力)で動いています。無駄なセッション情報をいつまでも持ち続けると、新しいセッションを受け入れられなくなったり、パフォーマンスが低下したりします。RSTによって不要なセッションをすぐに片付けることで、リソースを効率的に使い、常にスムーズな通信を維持できます。
2. 迅速な問題解決: アプリケーションがクラッシュして通信が切れた場合など、RSTが飛ぶことで、古いセッション情報がすぐに消え、新しいクリーンな接続を迅速に確立できるようになります。
3. ネットワークの健全性: 不要なセッションが残存しないことで、ネットワーク全体の健全性が保たれ、意図しない挙動や障害のリスクを低減できます。

🕵️‍♀️ 現場でのRSTパケットとNATゲートウェイの挙動を確認しよう!

では、実際にクラウド環境でRSTパケットがどのように発生し、NATゲートウェイがどのように処理しているのか、どうやって確認できるのでしょうか?

一番分かりやすいのは、AWSの「VPC Flow Logs」という機能を使うことです。これは、VPC内のネットワークトラフィックをキャプチャし、ログとして保存してくれるサービスです。

1. VPC Flow Logsの設定

まず、NATゲートウェイが存在するVPCに対して、VPC Flow Logsを有効にします。

# VPC Flow LogsをS3バケットに保存する場合の例 (AWS CLI)

# 1. Flow Logを保存するS3バケットを作成(すでに存在する場合はスキップ)
#    バケット名はグローバルにユニークである必要があります。
aws s3 mb s3://my-vpc-flow-logs-bucket-20231027 --region ap-northeast-1

# 2. Flow LogをVPCにアタッチするためのIAMロールを作成
#    IAMロールの信頼ポリシー(trust-policy.json)を作成
#    このポリシーは、Flow LogsサービスがCloudWatch Logsにログを書き込むことを許可します。
#    (S3に直接書き込む場合は不要ですが、今回はS3への書き込みも許可するポリシーの例を記載)
cat << EOF > flow-logs-trust-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "vpc-flow-logs.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF

# IAMロールを作成
aws iam create-role --role-name FlowLogRole --assume-role-policy-document file://flow-logs-trust-policy.json

# IAMポリシー(flow-logs-policy.json)を作成
# このポリシーは、Flow LogsがS3バケットに書き込むことを許可します。
cat << EOF > flow-logs-policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:PutObject",
                "s3:ListBucket"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::my-vpc-flow-logs-bucket-20231027",
                "arn:aws:s3:::my-vpc-flow-logs-bucket-20231027/*"
            ]
        }
    ]
}
EOF

# 作成したロールにポリシーをアタッチ
aws iam put-role-policy --role-name FlowLogRole --policy-name S3FlowLogsPolicy --policy-document file://flow-logs-policy.json

# 3. VPC Flow Logsを作成し、S3バケットに出力するように設定
#    'vpc-id'はご自身のVPC IDに置き換えてください。
#    'LogDestinationType'を's3'に、'LogDestination'をS3バケットのARNに設定します。
#    'TrafficType'を'ALL'に設定すると、すべてのトラフィックが記録されます。
#    'MaxAggregationInterval'はログの集約間隔(60秒または600秒)
#    'tags'はFlow Logに任意のタグを付与
aws ec2 create-flow-logs \
    --resource-ids vpc-0abcdef1234567890 \
    --resource-type VPC \
    --traffic-type ALL \
    --log-destination-type s3 \
    --log-destination arn:aws:s3:::my-vpc-flow-logs-bucket-20231027 \
    --max-aggregation-interval 60 \
    --tags Key=Name,Value=MyVPCFlowLog

2. RSTパケットを発生させてみる

プライベートサブネット内のEC2インスタンスから、インターネット上の「存在しないポート」や「応答しないサーバー」に対してcurlなどのコマンドでアクセスを試みます。

例えば、example.comというドメインの、通常使われないような高いポート番号(例えば9999番ポート)に対してアクセスしてみましょう。ほとんどの場合、そのポートでは何もサービスが動いていないため、通信先のサーバーからRSTパケットが返ってくる可能性が高いです。

# プライベートサブネット内のEC2インスタンスから実行
# 存在しないポート(例: 9999)へのアクセスを試みる
curl -v example.com:9999

このコマンドを実行すると、curlは接続に失敗するでしょう。そして、この通信がNATゲートウェイを通過します。

3. VPC Flow LogsでRSTフラグを確認する

S3バケットに保存されたFlow Logsのファイルを開いてみてください。RSTパケットを含むログエントリを探します。

Flow Logsのレコードは、以下のような形式で記録されます(一部抜粋)。
version account-id interface-id srcaddr dstaddr srcport dstport protocol packets bytes start end action log-status **tcp-flags** type pkt-srcaddr pkt-dstaddr

注目すべきは tcp-flags の部分です。

  • 2 は SYN
  • 18 は SYN-ACK
  • 16 は ACK
  • 4 は RST
  • 1 は FIN

もし tcp-flags の値に 4 が含まれていたら、それはRSTパケットが流れたことを示しています。例えば、20 (16 + 4) であれば ACK と RST が同時に設定されていることを意味します。

先ほどのcurlの例で、もしexample.comの9999番ポートが閉じられていた場合、Flow LogsにはNATゲートウェイを通過したRSTパケットの記録が残っているはずです。これにより、NATゲートウェイがRSTパケットを検知し、そのセッションを即座に終了したことが確認できます。

🚀 まとめ:NATゲートウェイは縁の下の力持ち!

いかがでしたでしょうか?

  • NATゲートウェイは、プライベートな場所にあるサーバーが、安全にインターネットと通信するための「賢い交通整理役」であり、「郵便局の私書箱」のような存在でした。
  • そして、TCP RSTパケットは、「緊急停止!通信をすぐにやめるぞ!」と伝える「緊急停止信号」です。

この二つが連携することで、NATゲートウェイは無駄なセッション情報を抱え込むことなく、必要なリソースを効率的に使い、常にスムーズで安定したネットワーク通信を提供しているんですね。

普段は意識することのない、パケットが行き交うネットワークの裏側で、こんなにも賢く、そして力強く動いている仕組みがあることを知っていただけたなら幸いです。

今日の学びが、皆さんのクラウドインフラやネットワークの理解をさらに深める一助となれば嬉しいです。一歩ずつ、クラウドの奥深さを一緒に探求していきましょう!

コメント

タイトルとURLをコピーしました