仕事で通信要件の変更に伴いNLBに紐づくEC2インスタンスに設定していたセキュリティグループを変更しました。
その際、別EC2から通信確認をしたところ通信が出来ない事象が発生。
EC2からEC2の通信は出来るのにEC2からNLBを通ってEC2だと通信が出来なくなり焦りました。
NLBを経由するとセキュリティグループのソースでセキュリティグループIDを設定した通信が出来なくなる
まずは構成図。
接続テストの構成は以下の感じです。
・接続元のEC2と接続先のEC2は別VPCとしており、お互いVPC Peeringで疎通できるようにしている
・InstanceAは疎通テスト用のEC2、InstanceBはサービス提供をしているEC2
・ClientからはNLBを経由しInstanceBに接続
・InstanceBで設定してるセキュリティグループではClientのIPアドレスと、接続テスト用のEC2となるInstanceAで設定しているセキュリティグループのセキュリティグループIDからの通信を許可
セキュリティグループはInstanceBのセキュリティグループが有効になります。
これはNLBはALBと異なりセキュリティグループがアタッチ出来ないので、NLBのターゲットグループとして設定しているEC2側で制御する必要があるためです。
この構成図の赤線の通信が通信が出来ないものとなります。
黒線で書かれている
・Client→NLB→InstanceB
・InstanceA→InstanceB
のどちらも通信可能で、赤線で書かれている
・InstanceA→NLB→InstanceB
のみ通信が出来ませんでした。
最初はなぜかわからず考え込みました。
EC2同士だと通信が出来たのがさらに悩ませるものとなり、EC2同士は出来るのにNLBを経由するとなぜか通信が落ちる。
同僚の方に相談してみたところ、同僚の方はこの事象を知っていて、InstanceAのIPをInstanceBで設定しているセキュリティグループに書いてみなとアドバイスをもらいました。
そこでInstanceBのセキュリティグループにInstanceAのIPを記載。
やってみたところ無事疎通出来ました。
ここで分かったのは、NLB経由だとセキュリティグループIDをソースとして通信許可をしているものは通信が出来ないということ。
理屈が分かりません…。なぜだろう。
インターネットに一度通信が出るのであれば理解できます。というのも、セキュリティグループIDというのはAWS内でのみ利用できる話でインターネットの世界で共通のものではないからです。
でも、今回のNLBはInternalで作成しているのでVPC内の話ですし、EC2同士は通信できるので関係がないです。
何かしらの仕様なのかなぁと漠然と考えました。
ALBだと同じ問題は起きない
ここでふと考えました。ALBだとどうなるんだろう。
結論から言うとALBだとセキュリティグループのソースをセキュリティグループIDとした通信は出来ました。
ALBの場合、セキュリティグループをALBにアタッチできるので、ALBにアタッチするセキュリティグループにClientのIPアドレスと、接続テスト用のEC2となるInstanceAで設定しているセキュリティグループのセキュリティグループIDからの通信を許可する設定を入れて試したところ無事通信可能でした。
結論
NLBを経由するとセキュリティグループのソースでセキュリティグループIDを設定した通信が出来ない
という仮定のもと、AWS公開のドキュメントを探しました。こんなことがあるなら絶対にどこかに書いてあるだろうと…。
そして見つけました。
docs.aws.amazon.com
・クライアントのセキュリティグループを、ターゲットのセキュリティグループのソースとして使用することはできません。したがって、ターゲットのセキュリティグループは、トラフィックを許可するためにクライアントの IP アドレスを使用する必要があります。
やっぱそうなんだ。NLBの場合はセキュリティグループのソースでセキュリティグループIDを設定するのはダメでIPで許可設定しないといけないんだ。
仮定はあっているところで皆さんもご注意ください。
いや、書いてあるけどさぁ…。
書くとこ、ここで合ってます…?
他にどこに書けばいいんだって話も分かりますが、これは辿り着かない。。。