はじめに
前回の記事でご紹介した内容ですが、運用して判明した事があります。 具体的にはkinesisにログ転送をする処理を追加したときに起こった事象です。 同様の構成にした場合には 注意が必要ですのでご参考までに。
起こった事象
2パターンありました。
Unable to load AWS credentials from any provider in the chain
User: arn:aws:sts::xxxxxxxxxxxx:assumed-role/role-hogehoge/i-xxxxxxxx
is not authorized to perform: sts:AssumeRole on resource:
arn:aws:iam::yyyyyyyyyyyy:role/role_hogehogehoge Service: AWSSecurityTokenService;
Status Code: 403; Error Code: AccessDenied;
Request ID: 12345676-abcd-11e6-b11c-aaaaaaaaaaaaa)
kinesisへの送信時にAWS SDK内で行われている処理
- 自インスタンスのロール名を取得するために http://169.254.169.254 へアクセス
- 再度http://169.254.169.254へアクセスし、取得したロールのAccessKeyId, SecretAccessKeyを取得
- AssumeRoleを取得するためにhttp://sts.amazonaws.comへアクセス
- kinesis送信
【特記事項】
AWS SDKでは通常、http通信にはApache HttpComponentsを使用しているが、1.と2.に関してはJavaに組み込まれているhttp通信ライブラリを使用している。 決済システムで、このJavaのhttp通信ライブラリを使用するときは、localhost以外は必ずプロキシを経由する設定になっている。 また、このライブラリではプロキシへのアクセスに失敗するとリトライを試みるが、リトライ時はプロキシを経由せずダイレクトに通信する。
つまりリトライすると通信経路が変わってしまう!!!!!!!!
余談ですが、Javaのバージョンによってプロキシとの通信エラー時の挙動が異なり、決済システムで使用している1.8.0_51では、先に説明した挙動となりますが、1,8.0_65ではダイレクト通信は行いません。(リトライも行わない)
WHY?????
エラーパターン推測
- 正常時の動作
- ロール取得時にプロキシを経由するため、プロキシのロールが返される。
- プロキシのAccessKeyId, SecretAccessKeyを取得
- プロキシに対しAssumeRoleを取得
- エラーパターン1:
“1.”でプロキシとの通信エラーが起き、プロキシを経由せず直接通信が行われたとき
- プロキシを経由しないため、webサーバのロールが返される。
- ロール一致しないためエラー
- エラーパターン2:
“1.2.”でプロキシとの通信エラーが起き、プロキシを経由せず直接通信が行われたとき
- プロキシを経由しないため、webサーバのロールが返される。
- webサーバのロールのAccessKeyId, SecretAccessKeyを取得
- AssumeRoleを取得しようとするがロールが間違っているためエラー
- エラーパターン3:
“2.”でプロキシとの通信エラーが起き、プロキシを経由せず直接通信が行われたとき
- ロール取得時にプロキシを経由するためプロキシサーバのロールが返される。
- ロールが不正なためエラー
解決策
プロキシサーバと同様のpolicyをWebサーバにも付与することにします。。
近藤 圭太
酒好き。 貝類、特に牡蠣に目がない。
釣り始めました。