Slide 1

Slide 1 text

Copyright © 2017. All rights reserved. ハンズラボ株式会社 田村龍太郎 IAMロールはどこから来て どこへ行くのか JAWS FESTA 2017

Slide 2

Slide 2 text

1 自己紹介 • 名前:田村 龍太郎 • 所属:ハンズラボ株式会社 • 入社:2017年3月 • 出身地:徳島県 • AWS歴:8ヶ月 • 初登壇で緊張してます

Slide 3

Slide 3 text

2 まえおき サポーターセッションなのにIAMの話? ハンズラボ関係なくない?

Slide 4

Slide 4 text

3 まえおき ハンズラボ四国代表として登壇が決まるものの

Slide 5

Slide 5 text

4 まえおき 15分も喋ることが思いつかなかった

Slide 6

Slide 6 text

5 まえおき この人→ 会社の取り組みは、弊社CEOが色んな所で喋ってるので

Slide 7

Slide 7 text

6 まえおき 今日は、社内勉強会こんな感じでやってるよ というご紹介も兼ねて、10分ぐらいのお話をします

Slide 8

Slide 8 text

7 はじめに AWSを使いはじめてからずっと気になっていたこと

Slide 9

Slide 9 text

8 はじめに IAMロールが何なのかよくわからない

Slide 10

Slide 10 text

9 何がわからないのか • ドキュメントを読めば、設定方法や使い方はわかる • 実装レベルで何が起きてるのかわからない • もやもやする → 調べよう!

Slide 11

Slide 11 text

10 よくあるユースケース EC2 Lambda S3 DynamoDB ロール • EC2のインスタンス等にロールを設定することで、 権限に応じたAWS リソースを呼び出し可能 • 例: S3のバケットにファイルをアップロード • リソースの利用権限はロールにアタッチされたポリシーによって決まる ポリシー リソースを 呼び出し アタッチ ロール

Slide 12

Slide 12 text

11 疑問その1 どうやってリソースの利用権限を取得しているのか

Slide 13

Slide 13 text

12 IAMユーザーの場合 • マネジメントコンソールでアクセスキーを生成 • AWS CLIの場合は aws configure を実行してキー情報を入力 • デフォルトだと ~/.aws/credentials に記録される • IAMユーザーが持つ権限通りにリソースが利用ができる • ではIAMロールは?

Slide 14

Slide 14 text

13 EC2インスタンスで追ってみた • ロールの設定はEC2インスタンスに対して行う。 • インスタンス内で自身の情報を取ってる方法は? • インスタンスメタデータ (http://169.254.169.254)にリクエスト • ロールの情報もあるはず! • 設定されているロールを取得できた $ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ sample-role

Slide 15

Slide 15 text

14 EC2インスタンスで追ってみた • ロール名を指定してリクエストするとCredentialがJSONで返ってくる • 見覚えのある文字が • 何が行われたのか? $ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/sample-role { "Code" : "Success", "LastUpdated" : "2017-10-30T06:54:40Z", "Type" : "AWS-HMAC", "AccessKeyId" : "ASIAXXXXXXXXXXXXXXXX", "SecretAccessKey" : "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "Token" : "xxxxx...", "Expiration" : "2017-10-30T13:04:40Z" }

Slide 16

Slide 16 text

EC2インスタンス EC2サービス STS IAM ① ⑤ ② ④ ③ 15 メタデータの動作イメージ AssumeRole 実行 一時的なCredential メタデータを リクエスト アタッチ メタデータの レスポンス AssumeRolePolicy 確認 IAMポリシー

Slide 17

Slide 17 text

16 AssumeRoleとは • AWS Security Token Service(STS)に用意されているAPI • 指定したIAMロールの持つ権限を、一時的に引き受ける(Assume)機能 • AssumeRoleという動作の主体になるのは権限を必要とする側 • 今回の例では、EC2がSTSに「オレにそのロールの権限使わせてよ」 と伝える感じ ① 権限ください ③ あげる ② Credential生成

Slide 18

Slide 18 text

17 AssumeRoleとは • 権限を要求する主体は、ロールと同じAWSアカウント内に限定されない • 別のAWSアカウントにいるIAMユーザー • Amazon, Facebook, Google, Cognito で認証されたユーザー • 任意のOpenID ConnectおよびSAMLのIDプロバイダで認証されたユーザー ① 認証 ⑥ あげる ⑤ Credential生成 ② トークン取得 ③ ください(トークン付) ④ 検証

Slide 19

Slide 19 text

18 AssumeRoleとは • STSが誰にでもホイホイ権限を渡してしまうとセキュリティに問題がある • 渡しても良い相手(Trusted entity)をIAMロールで事前に設定しておく • これがAssumeRolePolicyになる(IAMポリシーとは別に存在) ください ください AssumeRolePolicy IAMポリシー Trusted entity確認

Slide 20

Slide 20 text

19 AssumeRolePolicyの設定画面

Slide 21

Slide 21 text

20 回答その1 どうやってリソースの利用権限を取得しているのか STSのAssumeRoleを通して 一時的なCredentialを取得している

Slide 22

Slide 22 text

21 余談 • わざわざメタデータにリクエスト送らなくても、インスタンス内のCLIで 直接AssumeRoleを実行すればいいのでは? $ aws sts assume-role --role-arn arn:aws:iam::111122223333:role/sample-role --role-session-name "hogehoge" • できない (aws configureなどを行っていない状態) • ロールのAssumeRolePolicyでは • 特定のEC2インスタンスを信頼しているのではない • EC2サービス(マネージドな部分)を信頼している • インスタンスにロールを設定するということは • AssumeRoleを行う権限を与えているのではない • メタデータの該当ロールのURIへリクエストを送る権限を与えている • EC2サービス(メタデータ)を経由する必要がある

Slide 23

Slide 23 text

22 疑問その2 Credentialが取得できるのはわかったけど これどうするの?

Slide 24

Slide 24 text

23 回答? CLIとかSDKがうまいこと使ってくれます

Slide 25

Slide 25 text

24 もうちょっと詳しく • AWSの各サービスにはリソースにアクセスするためのAPIと、リクエ ストを送るエンドポイントが用意されている • CLIやSDKでも、内部ではエンドポイントへのHTTPリクエストが行わ れている • 下の画像はIAMのユーザー一覧を取得するリクエスト 引用元: https://docs.aws.amazon.com/ja_jp/general/latest/gr/sigv4_signing.html

Slide 26

Slide 26 text

引用元: https://docs.aws.amazon.com/ja_jp/general/latest/gr/sigv4_signing.html 25 もうちょっと詳しく ここ重要 • AWSの各サービスにはリソースにアクセスするためのAPIと、リクエ ストを送るエンドポイントが用意されている • CLIやSDKでも、内部ではエンドポイントへのHTTPリクエストが行わ れている • 下の画像はIAMのユーザー一覧を取得するリクエスト

Slide 27

Slide 27 text

26 Authorizationヘッダの全体 はみ出てる部分を項目ごとに改行すると大きく4つに分かれる AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/iam/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=5d672d79c15b13162d9279b0855cfba6789a8edb4c82c400e06b59 24a6f2b5d7 • アクセスキーID:Credentialの項目に含まれる(AKI〜) • シークレットアクセスキー:Signatureのハッシュ値計算に使用される

Slide 28

Slide 28 text

27 回答その2 Credentialが取れるのはわかったけど これどうするの? Credentialを使用して、(CLIとかSDKが) APIへのリクエストにAuthorizationヘッダを付与している

Slide 29

Slide 29 text

28 余談: Authorizationヘッダの各項目 • AWS4-HMAC-SHA256 • 署名に使用したアルゴリズム • 2017/11/04時点で推奨される署名バージョン4では HMAC-SHA256 • Credential (AKIDEXAMPLE/20150830/us-east-1/iam/aws4_request) • アクセスキーID • タイムスタンプ (yyyymmdd) • 対象リージョン • 対象サービス名 • 固定文字列 (aws4_request) • SignedHeaders (content-type;host;x-amz-date) • 署名されたHTTPリクエストのヘッダ一覧(Authorizationヘッダは除く) • 「署名された」というのは後述のSignature内に含まれるという意味

Slide 30

Slide 30 text

29 余談: Authorizationヘッダの各項目 • Signature (5d672d79c15b13162d9279b0855cfba6789a8edb4c82c400e06b5924a6f2b5d7) • シークレットアクセスキー • タイムスタンプ • 固定文字列 (AWS-HMAC-SHA256) • CredentialString (AKIDEXAMPLE/20150830/us-east-1/iam/aws4_request) • HTTPリクエストの中身 (CanonicalStringと呼ぶらしい) • メソッド • URI • クエリ文字列 • 元のHTTPリクエストに含まれる全ヘッダ名 (content-type;host;x-amz-date) • BodyのSHA256ハッシュ値 • 以上の文字列をHMAC-SHA256で複数回計算してハッシュ値にしている • 詳細な実装を追いたい場合は、SDKなどを参考にしてください • GolangのSDKだとこの辺に書いてます • https://github.com/aws/aws-sdk-go/blob/master/aws/signer/v4/v4.go

Slide 31

Slide 31 text

30 さいごに IAMロールはどこから来て、どこへ行くのか AssumeRoleによるCredential取得から来て、 AuthorizationヘッダとしてAPIエンドポイントに行く

Slide 32

Slide 32 text

Thank you!