NLB (Network Load Balancer) が Proxy Protocol に対応しました
現地時間の 11/17、NLB (Network Load Balancer) の Proxy Protocol サポートが発表されました。
- Elastic Load Balancing: Network Load Balancer adds support for Proxy Protocol
- Proxy Protocol - Target Groups for Your Network Load Balancers (※11/22時点で英語のみ)
CLB の頃は Proxy Protocol v1 だったんですが、NLB は v2 のみになります。
また CLB の頃と違い、実装時からマネジメントコンソールで手軽に設定できるようになっています。動作含め検証してみました。
はじめに : Proxy Protocol とは
すごく乱暴にいえば、「HTTP でいうところの X-Forwarded-for を HTTP 以外で使いたい」時のためのプロトコルです。
例えばこんな構成を考えます。
通常ロードバランサ (LB) やリバースプロキシが間にはいると、その裏側のサービスはクライアント IP アドレスを知ることが出来ません。通信相手は LB になるからです。
ただそれだと、アクセス元(クライアント)の IP アドレスによってアクセス制御したり、動作を変えたりすることが出来ません。
NLB はその動作の特性上、ターゲットをインスタンス ID で指定した場合は、直接クライアントの IP アドレスがターゲット(EC2 インスタンス)に伝わります。しかし IP アドレスで指定した場合は一般的な LB と同じように、NLB のプライベート側の IP アドレスが通知されてしまうので、そのような際には必要になる機能・プロトコルかと思われます。
IPアドレスによるターゲット指定が必要なケースとしては、例えば VPN 経由でオンプレミスサーバを指定したりといったものが考えられます。下記の記事を参照いただくのがはやいかと思いますので、あわせてご覧下さい。
なお、CLB での Proxy Protocol v1 対応についての記事はこちらになります。
動作検証
EC2 インスタンスを1台建て、NLB を二つ作ってターゲットに指定します。
NLB名 | ターゲットグループ名 | ターゲットの種類 |
---|---|---|
nlb-ip | t2-ip | IPアドレス |
nlb-instance | t2-instance | インスタンスID |
nlb-ip
が検証の本命ですが、比較のためにインスタンス ID でターゲット指定した nlb-instance
も用意しました。
IPアドレス | |
---|---|
サーバ側(Private IP) | 172.31.xxx.160 |
クライアント側(AWS 外) | 59.nnn.nnn.152 |
検証 1 : Proxy Protocol が無効(OFF)の場合
まずこれまでの場合を試してみます。
ターゲットの EC2 インスタンス上で nc
で簡易的にサーバを立てて、クライアントから送信された通信内容を確認してみます。Proxy Protocol v2 は v1 と違ってバイナリデータになるので、od
を使ってダンプします。
$ echo '何かしらのメッセージ' | nc <NLBのDNS名> 8081
$ nc -l 172.31.xxx.160 8081 | od -tx1 -ta
また同時に、サーバ側では tcpdump
でキャプチャもしておきました。届いた IP パケットの source / destination がどうなっているかを見るためです。
$ sudo tcpdump -nn port 8081
nlb-ip
の場合
Proxy Protocol が無効の場合、入力したメッセージがそのまま届きます。
$ echo 'ip, no ppv2' | nc nlb-ip-NNNNNNNN.elb.ap-northeast-1.amazonaws.com 8081
0000000 69 70 2c 20 6e 6f 20 70 70 76 32 0a i p , sp n o sp p p v 2 nl
ただし、アクセス元はクライアントの IP アドレスではなく、NLB の内側の IP アドレスになります。
06:53:42.596603 IP 172.31.xxx.153.32457 > 172.31.xxx.160.8081: Flags [SEW], ... 06:53:42.596617 IP 172.31.xxx.160.8081 > 172.31.xxx.153.32457: Flags [S.E], ... :
nlb-instance
の場合
ターゲットをインスタンス ID で指定した場合も、届くメッセージは同様。ただしアクセス元 IP アドレスにはクライアントのものになります。
$ echo 'instance, no ppv2' | nc nlb-instance-XXXXXXXX.elb.ap-northeast-1.amazonaws.com 8081
0000000 69 6e 73 74 61 6e 63 65 2c 20 6e 6f 20 70 70 76 i n s t a n c e , sp n o sp p p v 0000020 32 0a 2 nl
06:54:30.791103 IP 59.nnn.nnn.152.61062 > 172.31.xxx.160.8081: ... 06:54:30.791124 IP 172.31.xxx.160.8081 > 59.nnn.nnn.152.61062: ... :
検証 2 : Proxy Protocol が有効(ON)の場合
Proxy Protocol の有効化は、ターゲットグループのほうで行います。
有効化したあと実際に反映されるまで、すこし(十数秒程度)かかるようです。
nlb-ip
の場合
$ echo 'ip, with ppv2' | nc nlb-ip-NNNNNNNN.elb.ap-northeast-1.amazonaws.com 8081
メッセージの前にバイナリデータが挿入されているのがわかるでしょうか。
最初の 0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a
が Proxy Protocol v2 の protocol signature になり、2行目の冒頭から 4 バイトがクライアント IP アドレス(の 16進数表示)になります。
(0x3b = 59、 0x98 = 152 )
tcpdump
の結果ですと、相変わらず通信相手は NLB です。
07:19:51.405220 IP 172.31.xxx.153.17273 > 172.31.xxx.160.8081: ... 07:19:51.405237 IP 172.31.xxx.160.8081 > 172.31.xxx.153.17273: ... :
つまり Proxy Protocol を認識できるサーバソフトウェアであれば、クライアントの IP アドレスが何なのか、このプロトコル経由で知ることができるわけです。
nlb-instance
の場合
$ echo 'instance, with ppv2' | nc nlb-instance-XXXXXXXX.elb.ap-northeast-1.amazonaws.com 8081
0000000 0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a 21 11 00 54 cr nl cr nl nul cr nl Q U I T nl ! dc1 nul T 0000020 3b ** ** 98 ac 1f 18 c6 f9 aa 1f 91 03 00 04 ad ; *** *** can , us can F y * us dc1 etx nul eot - 0000040 fa 2f 5f 04 00 3e 00 00 00 00 00 00 00 00 00 00 z / _ eot nul > nul nul nul nul nul nul nul nul nul nul 0000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 nul nul nul nul nul nul nul nul nul nul nul nul nul nul nul nul * 0000140 00 00 00 00 69 6e 73 74 61 6e 63 65 2c 20 77 69 nul nul nul nul i n s t a n c e , sp w i 0000160 74 68 20 70 70 76 32 0a t h sp p p v 2 nl
07:20:24.616730 IP 59.nnn.nnn.152.61078 > 172.31.xxx.160.8081: ... 07:20:24.616745 IP 172.31.xxx.160.8081 > 59.nnn.nnn.152.61078: ...
こちらの場合も同様に Protocol Proxy のバイナリデータが挿入されています。クライアント IP アドレスが分かっているので重複ではあるのですが、同じ I/F で値が取れるのはいいですね。
まとめ
NLB も着々と機能が増えていきます。外部と完全に切り離した EC2 インスタンスや、VPN接続されたオンプレミス環境と組み合わせた場合でも、NLB の利用が選択肢に入ってくるかと思います。
参考
- 新しいNetwork Load Balancer – 秒間数百万リクエストに簡単にスケーリング | Amazon Web Services ブログ
- NLBでプライベートなAuto Scaling GroupのEC2をIPアドレスで登録する | Developers.IO
- gRPCアプリをNetwork Load Balancerで負荷分散してみた | Developers.IO
- 試してわかった NLB の細かいお作法 | Developers.IO
- ネットワーク視点で見るAWS ELB(Elastic Load Balancing)のタイプ別比較[NLB対応] | Developers.IO
- od(1): dump files in octal/other formats - Linux man page
- nc(1): arbitrary TCP/UDP connections/listens - Linux man page
- Manpage of TCPDUMP