Skip to content

AWS NLB は Source IP/Port を維持するが DSR 動作はしない

AWS Black Belt Online Seminar は毎回、素晴らしい内容です。 2017 年公開の資料なので、最新の情報ではありませんが NLB の基本的動作については ELB Update - Network Load Balancer (NLB) と関連サービス に分かりやすく、且つ、丁寧にかかれています。 この資料の P.20 に下記の記載があります。

  • クライアントの Source IP と Port が、そのまま Target まで届く
    • Target はクライアントと直接通信しているかの様に見える
    • 実際は、行きも帰りも NLB を通っている (DSR ではない)
    • IP Target (後述) の場合は保持されず、NLB からの通信となる
      • Direct Connect は接続されている VPC からのみ通信可能なので、こちらで回避

Instance Target で NLB を設定すると分散対象のサーバでは送信元パケットで「クライアントのアドレス」が確認出来る為、一見すると「NLB は DSR 動作している」ように見えますが、上述の Black Belt 資料に記載がある通り、実は DSR 動作をしていないそうです。 今回は検証環境で実際のトラフィックフローを確認してみました。

DSR した場合のトラフィックフロー (※ NLB はこの動作をしない)

NLB が「DSR 動作をしている」と仮定すると、トラフィックフローは下図のようになっているはずです。 後述しますが、実際にパケットをキャプチャしてみると Black Belt 資料に記載がある通り、この動作 (DSR 動作) はしていませんでした。

file

NLB を利用した場合のトラフィックフロー

結果から述べると、NLB を経由した場合は以下のトラフィックフローになっていました。

file

実際のパケットキャプチャ

実際にテスト環境で NLB 環境で動作確認し、パケットをキャプチャしてみます。

クライアント側でのパケットキャプチャ結果

クライアント (PC-11) から NLB に対して curl で HTTP GET リクエストを実行してみます。

1
2
[root@ip-10-0-1-11 ~]# curl http://10.0.1.100/
Hello, Web-101!

クライアント側でのパケットキャプチャ結果は以下の通りです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
01:59:17.857688 IP 10.0.1.11.38366 > 10.0.1.100.http: Flags [S], seq 1619515716, win 26883, options [mss 8961,sackOK,TS val 114241761 ecr 0,nop,wscale 7], length 0
01:59:17.858472 IP 10.0.1.100.http > 10.0.1.11.38366: Flags [S.], seq 1698624790, ack 1619515717, win 26847, options [mss 8653,sackOK,TS val 3307127713 ecr 114241761,nop,wscale 7], length 0
01:59:17.858485 IP 10.0.1.11.38366 > 10.0.1.100.http: Flags [.], ack 1, win 211, options [nop,nop,TS val 114241762 ecr 3307127713], length 0
01:59:17.858627 IP 10.0.1.11.38366 > 10.0.1.100.http: Flags [P.], seq 1:75, ack 1, win 211, options [nop,nop,TS val 114241762 ecr 3307127713], length 74: HTTP: GET / HTTP/1.1
01:59:17.858944 IP 10.0.1.100.http > 10.0.1.11.38366: Flags [.], ack 75, win 210, options [nop,nop,TS val 3307127714 ecr 114241762], length 0
01:59:17.859184 IP 10.0.1.100.http > 10.0.1.11.38366: Flags [P.], seq 1:291, ack 75, win 210, options [nop,nop,TS val 3307127714 ecr 114241762], length 290: HTTP: HTTP/1.1 200 OK
01:59:17.859190 IP 10.0.1.11.38366 > 10.0.1.100.http: Flags [.], ack 291, win 219, options [nop,nop,TS val 114241763 ecr 3307127714], length 0
01:59:17.859409 IP 10.0.1.11.38366 > 10.0.1.100.http: Flags [F.], seq 75, ack 291, win 219, options [nop,nop,TS val 114241763 ecr 3307127714], length 0
01:59:17.859709 IP 10.0.1.100.http > 10.0.1.11.38366: Flags [F.], seq 291, ack 76, win 210, options [nop,nop,TS val 3307127714 ecr 114241763], length 0
01:59:17.859717 IP 10.0.1.11.38366 > 10.0.1.100.http: Flags [.], ack 292, win 219, options [nop,nop,TS val 114241763 ecr 3307127714], length 0

以下の事柄が分かります。

  • NLB (10.0.1.100) からのパケットのみ、受信していること
  • Web-101 (10.0.1.101) からのパケットは 受信していない こと

Web サーバ側でのパケットキャプチャ結果

Web サーバ側でのパケットキャプチャ結果は以下の通りです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
01:59:17.858057 IP 10.0.1.11.38366 > 10.0.1.101.http: Flags [S], seq 1619515716, win 26883, options [mss 8653,sackOK,TS val 114241761 ecr 0,nop,wscale 7], length 0
01:59:17.858089 ARP, Request who-has 10.0.1.11 tell 10.0.1.101, length 28
01:59:17.858198 ARP, Reply 10.0.1.11 is-at 02:9d:7d:56:1d:aa, length 42
01:59:17.858215 IP 10.0.1.101.http > 10.0.1.11.38366: Flags [S.], seq 1698624790, ack 1619515717, win 26847, options [mss 8961,sackOK,TS val 3307127713 ecr 114241761,nop,wscale 7], length 0
01:59:17.858623 IP 10.0.1.11.38366 > 10.0.1.101.http: Flags [.], ack 1, win 211, options [nop,nop,TS val 114241762 ecr 3307127713], length 0
01:59:17.858774 IP 10.0.1.11.38366 > 10.0.1.101.http: Flags [P.], seq 1:75, ack 1, win 211, options [nop,nop,TS val 114241762 ecr 3307127713], length 74: HTTP: GET / HTTP/1.1
01:59:17.858790 IP 10.0.1.101.http > 10.0.1.11.38366: Flags [.], ack 75, win 210, options [nop,nop,TS val 3307127714 ecr 114241762], length 0
01:59:17.859005 IP 10.0.1.101.http > 10.0.1.11.38366: Flags [P.], seq 1:291, ack 75, win 210, options [nop,nop,TS val 3307127714 ecr 114241762], length 290: HTTP: HTTP/1.1 200 OK
01:59:17.859303 IP 10.0.1.11.38366 > 10.0.1.101.http: Flags [.], ack 291, win 219, options [nop,nop,TS val 114241763 ecr 3307127714], length 0
01:59:17.859520 IP 10.0.1.11.38366 > 10.0.1.101.http: Flags [F.], seq 75, ack 291, win 219, options [nop,nop,TS val 114241763 ecr 3307127714], length 0
01:59:17.859542 IP 10.0.1.101.http > 10.0.1.11.38366: Flags [F.], seq 291, ack 76, win 210, options [nop,nop,TS val 3307127714 ecr 114241763], length 0
01:59:17.859841 IP 10.0.1.11.38366 > 10.0.1.101.http: Flags [.], ack 292, win 219, options [nop,nop,TS val 114241763 ecr 3307127714], length 0

以下の事柄が分かります。

  • クライアント (10.0.1.11) からのパケットのみ、受信していること
  • NLB (10.0.1.100) からのパケットは 受信していない こと
  • つまり、NLB を経由していても送信元アドレスが維持されている

「従来の DSR」と「AWS NLB」の比較

「従来の DSR」と「AWS NLB」を比較してみます。

DSR の特徴

DSR 構成には一般的に以下のような特徴があると思います。

  1. 以下のトラフィックフローになる
    • 行きのトラフィックは LB を経由する
    • 戻りのトラフィックは LB を経由しない (LB では Source NAT しない)
    • つまり、往復で非対称トラフィックフローになる (非対称トラフィックフローに対する配慮が必要になる)
  2. LB で戻りトラフィックを処理する必要が無い為、パフォーマンスが改善する
  3. トラフィックが往復ともに LB を経由することが前提である機能が使えない (例. SSL/TLS オフロード等)
  4. 負荷分散対象となるサーバで、戻りパケットの送信元アドレスを LB の VIP にする必要がある

AWS NLB では負荷分散対象サーバ側での DSR 用設定が不要

DSR 構成では Windows サーバにしろ、Linux サーバにしろ、上記 4. の設定が必要でした。 しかし、AWS NLB では恰も DSR のように「Source IP/Port は維持されている」にも関わらず、クライアントに通信を戻す際は「NLB のアドレスから戻ってくる」為に上記 4. の対処が不要です。 これは大きなメリットだと思います。

AWS NLB であれば、そもそも十分なパフォーマンスが期待出来る

また、NLB は AWS インフラで提供され、しかも AWS ALB とは違い「暖機運転」が不要なので突発的なバーストトラフィックにも強い、という特性があります。 従来の DSR には上記 2. の「パフォーマンスの優位性」がありましたが、AWS NLB は往復のパケットが経由しているとしても、「NLB がボトルネックになる」というケースは考えづらいのでは無いかと思われます。

他サービス同様、NLB はメンテナンスが不要

NLB も他のサービス同様、AWS のサービスなので「脆弱性対応」などのメンテナンスを意識してユーザが実施する必要がありません。「敢えて AWS インフラ内部に Linux/Windows で DSR な LB を構築する」という構成は手間が面倒で "敢えて自前で LVS を作ろう!" といったケースは少ないと思いますが…