gokigenmaruのブログ

40から始めるクラウドエンジニア

IPフィルターで接続が拒否されたときの挙動とAPIGWで接続が拒否されたときの挙動

こんにちわ、ごきげんまるです。

今日もAPIGWのIPフィルター関連の話です。

セキュリティグループのIPフィルターで弾かれた時の挙動

セキュリティグループは皆さんご存じだと思います。AWSでの一般的なアクセス制御機能です。
インバウンド・アウトバウンドともに設定が可能で、プロトコル・ポート番号でトラフィックをフィルターできます。
NetworkACLとの大きな違いはステートフルなためインバウンドの通信のフィルタを実施したときにインバウンドの戻りの通信を意識する必要がありません。仮にアウトバウンド通信を全部拒否してもインバウンド通信が許可されていれば戻りの通信は通ります。
また、セキュリティグループはAllowのみの設定です。Deny設定は出来ません。Allowした通信以外はDenyされます。

このセキュリティグループですが、通信がセキュリティグループにより拒否された場合、どのようになるかというと、通信はタイムアウトします。
これは、セキュリティグループでパケットが落とされ、クライアント側に戻りの通信が発生しないことで、クライアント側は戻りの通信をタイムアウトまで待つためです。

curlで接続を試すとこんな感じになります。

$ curl -k -vvv https://example.com
* About to connect() to example.com port 443 (#0)
*   Trying xx.xx.xx.xx...
* Connection timed out
*   Trying xx.xx.xx.xx...
* After 86306ms connect time, move on!
* Failed connect to example.com:443; Operation now in progress
* Closing connection 0
curl: (7) Failed connect to example.com:443; Operation now in progress

APIGWのIPフィルターで弾かれた時の挙動

続いて、APIGWのIPフィルターで弾かれた時の挙動です。
APIGWのIPフィルターで弾かれた時は、クライアント側にHTTPステータスコード403が返ります。
つまり、接続自体は一度受け付けたうえで、認証によって拒否されたとなります。
イメージするIPフィルターとはちょっと違います。おそらくですが、APIGWにとってIPフィルターは認証の設定の1つであると思われるためです。IAMのポリシーとかと同様に、そのユーザ(クライアント)は接続できる権利を持っていないという判断の仕方なんだと思います。

curlで接続を試すとこんな感じになります。

$ curl -v -H "x-api-key: xxxxxxxxxxx" https://example.com/test/
~中略~
< HTTP/2 403
~中略~
< x-amzn-ErrorType: AccessDeniedException
~中略~
* Connection #0 to host example.com left intact
{"Message":"User: anonymous is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:ap-northeast-1:********xxx:xxxxxxxxxx/test/ with an explicit deny"}

APIGWから、ErrorTypeとして「AccessDeniedException」、メッセージとして、「User: anonymous is not authorized to perform: ~ with an explicit deny」が返されているのが分かります。
つまり、上記ErrorTypeとメッセージが来ている場合はAPIGWのIPフィルターで弾かれたんだなということが分かります。

APIGWのオーソライザーで弾かれた時の挙動

ついでなので、APIGWの認証機能であるオーソライザーでアクセスが拒否された時の挙動です。
APIGWのオーソライザーで弾かれた時は、クライアント側にHTTPステータスコード403が返ります。
IPフィルターの時と同様、接続自体は一度受け付けたうえで、認証によって拒否されたとなります。
これはイメージ湧きやすいですね。オーソライザー(承認)の意味の挙動通りかと思います。

curlで接続を試すとこんな感じになります。

$ curl -v -H "x-api-key: xxxxxxxxxxx" https://example.com/test/
~中略~
< HTTP/2 403
~中略~
< x-amzn-errortype: ForbiddenException
~中略~
* Connection #0 to host example.com left intact
{"message":"Forbidden"}

APIGWから、ErrorTypeとして「ForbiddenException」、メッセージとして、「Forbidden」が返されているのが分かります。
つまり、上記ErrorTypeとメッセージが来ている場合はAPIGWのオーソライザーで弾かれたんだなということが分かります。
ちなみに、こちらはカスタムオーソライザー(Lambdaオーソライザー)でもAPIGWの機能であるオーソライザーでも同じ結果になりました。

まとめ

セキュリティグループで接続拒否:タイムアウト (Connection timeout)
APIGWのIPフィルターで接続拒否:403 (AccessDeniedException / User: anonymous is not authorized to perform: ~ with an explicit deny)
APIGWのオーソライザーで接続拒否:403 (ForbiddenException / Forbidden)