セッショントークンを利用して新しめのリージョンにAPIリクエストする際は、STSの設定に注意する
概要
あるシステムで、AssumeRoleによって取得した一時トークンを使ってバーレーンリージョンのリソースに対してGETリクエストを送ると、認証周りでエラーとなったため調べてみると、STSの設定を変更する必要があるとわかった。その際に調べたことや検証したことをまとめる。
STS エンドポイントの種類によってトークンの有効範囲が違う
AssumeRole等によって一時セッショントークンを発行する際はSTS用のエンドポイントを経由する。そのエンドポイントは大きくわけて以下の2種類ある
- グローバルエンドポイント
-
https://sts.amazonaws.com
の単一のエンドポイント
-
- リージョンエンドポイント
-
https://sts.{region名}.amazonaws.com
の形のエンドポイント - リージョンごとに存在し、こちらを使うことが推奨されている。
-
どちらを選んでも同じようにセッショントークンを取得することができるが、新しめのリージョンに対するリクエスト時の認証を行う場合は注意が必要。
リージョンエンドポイントを経由して取得したセッショントークンは、全てのリージョンに対して認証が有効なトークンとなっている。
ただし、グローバエンドポイントを経由して取得したセッショントークンは、デフォルトでは、新しめのリージョン (=2019年3月20日以降に設けられたリージョンで、明示的に有効化が必要となるもの) に対するリクエストは無効となっており、以下のリージョン (現時点のもの) に対するリクエストは認証エラーとなる。
- アフリカ (ケープタウン)
- アジアパシフィック (香港)
- ヨーロッパ (ミラノ)
- 中東 (バーレーン)
参考: https://docs.aws.amazon.com/ja_jp/general/latest/gr/rande-manage.html#rande-manage-enable
デフォルトではこのような設定となっているが、グローバルエンドポイントを使う場合でも全てのリージョンで有効となるトークンを発行できるよう設定ができる。
デフォルト値の場合
設定確認
設定の状態は、IAMのコンソール画面の「アクセス管理>アカウント設定>Security Token Service (STS)」の「STS エンドポイントからのセッショントークン」で確認可能。
以下のように、エンドポイントごとにどのリージョン範囲で有効なのかが表示されており、図のようにグローバルエンドポイントで「デフォルトで有効になっているAWSリージョンでのみ有効」となっている。
APIリクエストしてみる
この状態で、グローバルエンドポイント経由でセッショントークンを取得して、バーレーンリージョンのEC2インスタンスのリストを取得してみる。
AssumeRoleでセッショントークンの取得
regionを指定して実行すると、そのリージョンのリージョンエンドポイントが利用される。
region未指定または --region aws-global
をつけて実行すると、グローバルエンドポイントが利用される (※ 環境変数やconfig等にリージョンが指定されていた場合はそのリージョンとなる)
aws sts assume-role --role-arn arn:aws:iam::xxxxxxxxxxxx:role/my-role --role-session-name testsession --region aws-global
どのエンドポイントが利用されたのかは、--debug
フラグをつけることでログに表示されるため、それで確認ができる。
セッショントークンを取得後は、必要な認証情報を環境変数に設定しておく
参考: https://aws.amazon.com/jp/premiumsupport/knowledge-center/iam-assume-role-cli/
バーレーンリージョンのEC2インスタンスのリストを取得
セッショントークンの取得および環境変数への設定後、バーレーンリージョンのEC2インスタンスのリストを取得してみる。
aws ec2 describe-instances --region me-south-1
An error occurred (AuthFailure) when calling the DescribeInstances operation: AWS was not able to validate the provided access credentials
出力内容の通り、AuthFailure
というように認証でエラーとなる。
どのようなエラーになるのかはAPIによって異なり、例えば UnrecognizedClientException
となるものもあった。
設定の変更方法
「すべての AWS リージョンで有効」を選択し「変更の保存」をする。
保存後、以下のように、グローバルエンドポイントについても互換性が「すべてのAWSリージョンで有効」となる。
参考: https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html
全てのリージョンで有効化されている状態でリクエスト
上と同じAssumeRoleのコマンドを使って再度一時トークンを取得し、同じAPIを実行。
そのままのトークンでは、有効範囲が前の設定に沿ったもののままとなる。
aws ec2 describe-instances --region me-south-1
{
"Reservations": [
{
"Groups": [],
"Instances": [
{
....
エラーも出ず、バーレーンリージョンのインスタンスリストが取得できた。
切り替えの影響
反映速度は体感は即時だった。
また影響についてはドキュメントでは、
この設定を変更すると、一時的にトークンを保存する既存のシステムに影響する可能性があります。
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html#sts-regions-manage-tokens
となっているので、慎重にする場合は検証用の別環境で試してから切り替えることを推奨する。
まとめ
今回もそうだったが、AssumeRoleして複数リージョンに対して何かしらリクエストを送るようなシステムで発生しうる症状。
リージョンエンドポイントの利用が推奨となっているため、今後はリージョンを指定してAssumeRoleをするようにしたいが、意図的に or 恣意的にグローバルエンドポイントが使われていることも少なくない (そもそもIAMがグローバルリソース) と思うため、もしその時に新しめのリージョンに対してのリクエストで認証周りのエラーが出た場合は、とりあえずこの対応で解消できる
Author And Source
この問題について(セッショントークンを利用して新しめのリージョンにAPIリクエストする際は、STSの設定に注意する), 我々は、より多くの情報をここで見つけました https://qiita.com/mmclsntr/items/4d0e81b0386f0bc5cb01著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .