1台のデュアルスタックNLBで、IPv4/IPv6判定するリスナールールを試してみた

1台のデュアルスタックNLBで、IPv4/IPv6判定するリスナールールを試してみた

NLBのリスナールールにIpAddressType条件が追加され、送信元のIPv4/IPv6を判定してターゲットグループを振り分けられるようになりました。デュアルスタックNLB 1台への統合とクライアントIPアドレス保持を実機検証で確認します。
2026.07.23

はじめに

2026年7月22日、Network Load Balancer(NLB)がリスナールールに対応しました。送信元IPアドレスのアドレスファミリー(IPv4/IPv6)を条件に、転送先のターゲットグループを振り分けられます。

https://aws.amazon.com/about-aws/whats-new/2026/07/aws-network-load-balancer-supports-listener-rules/

従来はデュアルスタック環境でクライアントIPアドレスを保持するにはNLBを2台運用する必要がありました(詳細は後述の「アーキテクチャ変遷」を参照)。

本記事ではアーキテクチャ・制約・料金を整理します。リスナールールのCLI操作については前回記事を参照してください。

https://dev.classmethod.jp/articles/nlb-listener-rule-ipaddresstype-ipv4-ipv6-routing/

検証内容

実機検証: クライアントIPアドレス保持の確認

以下の構成で、IPv4/IPv6アクセスの振り分けとクライアントIP保持を検証しました。

Internet(デュアルスタッククライアント)


NLB (dualstack, internet-facing, TCP:80)
  ├─ ルール Priority 1: source-ip IpAddressType=ipv6 → TG-IPv6
  └─ デフォルトアクション                              → TG-IPv4
        │                                                │
        ▼                                                ▼
  EC2 #2 (nginx, IPv6 TG)                        EC2 #1 (nginx, IPv4 TG)
  target_type: ip                                target_type: instance
  ip_address_type: ipv6                          ip_address_type: ipv4
  preserve_client_ip: true                       preserve_client_ip: true

クライアントIP保持のためにポイントとなる設定を挙げます。

  • NLB: EnablePrefixForIpv6SourceNatoff(本検証環境での設定値。IPv6ソースNAT用プレフィックス変換を無効化)
  • TG-IPv4: target_type=instancepreserve_client_ip.enabled=true
  • TG-IPv6: target_type=ipip_address_type=ipv6preserve_client_ip.enabled=true
  • nginx: add_header X-Client-IP $remote_addr always; で送信元IPアドレスをレスポンスヘッダーに出力

クライアントからNLBのDNS名に対して、IPv4とIPv6でそれぞれアクセスしました。

curl -4 http://<NLB-DNS>
curl -6 http://<NLB-DNS>

レスポンスヘッダーの X-Client-IP およびnginxアクセスログの $remote_addr で送信元IPアドレスを確認しました。

テスト1: IPv4アクセス(curl -4)

項目
クライアントIPv4 203.0.113.1
NLBルーティング デフォルトアクション → TG-IPv4
nginx X-Client-IP 203.0.113.1
nginx access.log $remote_addr 203.0.113.1
結果 ✅ クライアントIP保持

テスト2: IPv6アクセス(curl -6)

項目
クライアントIPv6 2001:db8:1:2:7522:3a01:63e3:4232
NLBルーティング ルール(IpAddressType=ipv6) → TG-IPv6
nginx X-Client-IP 2001:db8:1:2:7522:3a01:63e3:4232
nginx access.log $remote_addr 2001:db8:1:2:7522:3a01:63e3:4232
結果 ✅ クライアントIP保持

クライアントIPを保持するには次の設定が必要です。

  • ターゲットグループの preserve_client_ip.enabledtrue であること
  • 同一IPアドレスファミリーのターゲットグループへ転送されること(IPv4→IPv4 TG、IPv6→IPv6 TG)

なお、デュアルスタックNLBでUDP/TCP_UDPリスナーを使用する場合は EnablePrefixForIpv6SourceNaton にする必要があります。本検証(TCPリスナー)では off に設定しています。

アーキテクチャ変遷: 従来構成 vs 新構成

従来のデュアルスタック環境では2つの構成パターンがありました。AWSブログでもこの変遷が紹介されています。

https://aws.amazon.com/blogs/networking-and-content-delivery/consolidate-dual-stack-architectures-with-listener-rules-for-network-load-balancer/

Before パターンA: NLB 2台構成

クライアント


DNS (A → NLB-IPv4, AAAA → NLB-IPv6)
  ├─ A レコード ──→ NLB-IPv4 ──→ TG-IPv4 ──→ EC2
  └─ AAAA レコード → NLB-IPv6(dualstack)──→ TG-IPv6 ──→ EC2

IPv4クライアント向けNLBと、IPv6クライアントをIPv6ターゲットグループへ転送するデュアルスタックNLBを別々に運用し、DNSのA/AAAAレコードで振り分ける方式です。NLBの管理が二重になり、稼働時間の料金も2台分かかります。

Before パターンB: 単一デュアルスタックNLB + IP変換

クライアント


デュアルスタックNLB
  └─ デフォルトアクション → TG(IP変換発生)→ EC2

1台のデュアルスタックNLBで異なるIPファミリーのターゲットグループへ転送すると、IP変換が発生してクライアントIPアドレスをそのままの形では保持できません。クライアントIPの取得にはProxy Protocol v2の解析が必要でした。

After: リスナールールによる統合

クライアント


デュアルスタックNLB
  ├─ ルール(IpAddressType=ipv6)  → TG-IPv6 → EC2
  └─ デフォルトアクション          → TG-IPv4 → EC2

リスナールールでIPアドレスファミリーごとに同一ファミリーのターゲットグループへ転送することで、IP変換が発生せず、preserve_client_ip によるクライアントIPの保持が可能になります。Proxy Protocol v2の解析も不要です。

対応プロトコルと条件

NLBのリスナールールは、次のリスナープロトコルで利用できます。

  • TCP
  • UDP
  • TCP_UDP
  • TLS

NLBのリスナールールで指定できる条件は source-ipIpAddressType のみであり、値は ipv4 または ipv6 です。

ALBの source-ip 条件がCIDR指定であるのに対し、NLBはアドレスファミリーを指定する点が異なります。前回記事で確認したとおり、NLB向けの SourceIpConfig.IpAddressType を指定してALBルールを作成しようとすると ValidationError になります。

制約事項と前提条件

  • デュアルスタックNLB専用の機能です
  • VPCおよびサブネットにIPv6 CIDRブロックの関連付けが必要
  • サブネットのルートテーブルでIPv6ルーティングが可能であること
  • TLSリスナーではTCPターゲットグループとTLSターゲットグループを同一ルールに混在できない
  • デュアルスタックNLBの同一デフォルトアクションではIPv4ターゲットグループとIPv6ターゲットグループを混在できない
  • UDPリスナー(デュアルスタックNLB)ではIPv6ターゲットグループが必要
  • ヘルスチェックは各ターゲットグループのIPアドレスファミリーで実行されるため、ターゲットは所属するターゲットグループに対応するIPファミリーからのヘルスチェック通信を許可する必要がある。同一ターゲットをIPv4/IPv6の両ターゲットグループに登録する場合は、双方からのヘルスチェック通信を許可する
  • ルール評価: 優先度の数値が小さい順に評価され、最初に一致したルールのアクションが実行される。どのルールにも一致しない場合はデフォルトアクションが適用される。カスタムルールのアクションは forward のみ

重み付きターゲットグループ

リスナールールの転送アクションでは、各ターゲットグループに0〜999の重みを設定できます。重みに応じてトラフィックが分配され、重み0を設定したグループには新規接続が送られません。同一アドレスファミリー内での段階的なターゲット移行などに活用できます。

既存NLBへの適用と料金

既存のデュアルスタックNLBを再作成する必要はなく、そのままリスナールールを追加できます。すべてのAWS商用リージョンおよびAWS GovCloud (US) リージョンで利用できます。

NLBの課金は稼働時間とNLCUの2軸です。

  • NLB稼働時間(時間単位)
  • NLCU: 新規接続数・アクティブ接続数・処理バイト数の各ディメンションで消費NLCUを計算し、そのうち最大値が課金対象

リスナールール自体に追加料金はかかりません。NLB 2台構成を1台に統合した場合、2台目のNLB稼働時間(LB-hour)分のコストを削減できます。一方、NLCUは新規接続数・アクティブ接続数・処理バイト数の各ディメンションからNLBごとに算出されます。統合後のNLCUがどの程度変化するかはトラフィック特性に依存するため、削減効果は実際の利用状況に応じて確認してください。

まとめ

NLBリスナールールの IpAddressType 条件により、デュアルスタックNLB 1台でIPv4/IPv6トラフィックを振り分けられるようになりました。同一IPアドレスファミリーのターゲットグループへ転送し、preserve_client_ip.enabled を有効にすれば、クライアントIPアドレスも保持できます。NLB 2台構成の統合、管理負荷の軽減、LB-hour料金の削減を検討する際の選択肢になります。

参考リンク

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事