【備忘録】JAWS-UG CLI専門支部のIAM編をまとめて振り返ってみる

ゴールデンウィークは皆さんいかがお過ごしでしたでしょうか
10連休で存分にリフレッシュした人、ゴールデンウィークなんて関係なく働いていた人、引きこもってNetflix三昧だった人、色々だと思います

私はJAWS-UG CLI専門支部のメンバーの一員として、ゴールデンウィーク特別講座を受けておりました

https://jawsug-cli.connpass.com/

2022/4/29～5/8の間一日も欠かさず（！）、CLI専門支部ではハンズオンが開催されていました
内容としては、AWSで欠かすことのできないサービスであるSNS、SQS、S3、IAMに関する座学とハンズオンです

今回はその中でも一番比重が高かったIAMについて、学んだことを振り返ろうと思います

※私は全参加できなかったので、一部自習のみ行った部分もあります
※この記事でIAMを網羅しているわけではありません。個人的な備忘録として残しています。

# IAM全般知識

## IAMの位置づけ
- AWSリソースに対するリクエストの認証・認可を行うサービス

- ほぼすべて(*)のAWS APIリクエストはIAMを介して実行される
    - 2021年5月現在で4億リクエスト/秒を処理している！
    - (*)rootアカウントの場合、APIはIAMを介さずに実行される
        - 認証・認可なしでの操作なので要注意

↓　IAM誕生10周年を祝うブログで、4億リクエスト/秒を処理していることが明かされた　↓

https://aws.amazon.com/jp/blogs/aws/happy-10th-birthday-aws-identity-and-access-management/

## IAMの要素：認証
プリンシパルとIAMエンティティによって認証処理が成り立つ
- プリンシパル
    - AWSリソースに対して操作をしようとしている人（ユーザー）やリソースのこと
    例：AWSを利用するユーザー、EC2やS3などのAWSリソース、外部のIDプロバイダー

- IAMエンティティ
    - プリンシパルからのリクエストを認証するためのラベル
    - プリンシパルがAWSリソースに対してアクセスする場合、AWS内部ではIAMエンティティとして認証を行う
    例：IAMユーザー、IAMロール

## IAMの要素：認可
- IAMアイディンティ
    - IAMエンティティとIAMポリシーを紐づけるためのラベル
    - IAMエンティティをグループ化することができる
    例：IAMグループ

- IAMポリシー
    - IAMアイデンティティに対して、何を許可/禁止するのかを定義する
        - 何のAPIアクションを許可/禁止するのか
        - どのリソースに対する操作を許可/禁止するのか
        - その他許可/禁止の判断に用いられる条件
        などを管理する

↓　IAMの仕組みについて機能ごとに説明されている　↓

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/intro-structure.html

# IAMユーザー/グループ
## IAMユーザーを使ったログイン方法

- マネジメントコンソールでのパスワードログイン
    - 裏ではログインプロファイルというオブジェクトによって認証が行われている

- CLI/SDKからのログイン
    - 認証ファイルに格納されたアクセスキーを用いた認証

- **上記いずれも、認証情報を外部と共有するため漏洩リスクが高い**
    - よほどのことがない限りは、IAMロールを使用することを推奨
    理由：AWS内部で認証が自動で行われるため、認証情報を保持する必要がない

- Datadogはアカウント作成時にIAMロールの作成を強要される
    - IAMユーザー利用による漏洩事故を防ぐため


## Tips
- CLIでIAMユーザーを削除する場合は、まずはアタッチされているポリシーやMFAデバイスなどをすべて削除する

- 認可要素（IAMポリシー）を作成してから、認証要素（IAMユーザー）を作成するのが推奨される
    理由：逆だと、緩い認可を設定してしまった場合に危険。認可をしっかり設計・作成してから認証を実装するのが最もセキュア。

# IAMロール

## IAMロールの仕組み

- IAMロールの認証の裏ではSTSが動いている
    - STSによって一時認証情報が発行され、その一時認証情報を使ってAWSリソースを利用する
    - 一時認証情報の実態は、有効期限が短いアクセスキー、シークレットアクセスキー、セッショントークン
    - AWS内部で認証が自動で行われる

↓　仕組みを直感的に理解するのに最もわかりやすい（主観）記事です　↓

https://dev.classmethod.jp/articles/iam-role-passrole-assumerole/

## IAMロールの信頼ポリシー
- 信頼ポリシーとは
    - 「どのプリンシパルがそのロールを果たすことができるかを定義するロールにアタッチされるリソースベースのポリシー」（公式ドキュメント引用）
    - 要するに、IAMロールが持っている権限の使用を、どのプリンシパルに対して許可するのかを指定するポリシー
    - 「信頼関係」と呼ばれることもある

- 基本的なロールであれば、信頼ポリシーは以下のテンプレートでOK
    - 以下はLambdaと信頼関係を結ぶ場合の例
    - "Principal"をプリンシパルごとに書き換える必要がある
```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
```

↓　IAMロールの信頼ポリシーについての説明がわかりやすかったです　↓

https://dev.classmethod.jp/articles/aws-iam-policy/

↓　公式ドキュメントでの信頼ポリシーの説明はこちら　↓

https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html#principal-services

## IAMロールの認証・認可
IAMロールには認証・認可、2つの側面がある

1. 認証（信頼ポリシー）
アクセスしてくるAWSリソース（プリンシパル）を管理するためのラベル

2. 認可（IAMポリシー）
アクセスしてくるAWSリソース（プリンシパル）に与える権限を紐づけるためのラベル

## AssumedRoleとAssumRole
- AssumedRole：引き受けられたロールそのものを指す名詞

- AssumRole：ロールを引き受ける動作を指す。スイッチロールは裏でAssumeRoleが動いている。
    - 「スイッチロール」はマネジメントコンソール上の操作をわかりやすくするための表現ととらえるとわかりやすい
    - マネジメントコンソール上では文字通り、ロールを「スイッチ」するような操作になる。しかし実際には、AssumeRoleが行われているだけ。

## Tips
- 個人的おすすめ書籍
    - IAMロールとSTSの関係を最初に知ったのはこの本でした。全体的に初心者でも理解しやすい本なのでおすすめしたい。

https://www.amazon.co.jp/%E8%A6%81%E7%82%B9%E6%95%B4%E7%90%86%E3%81%8B%E3%82%89%E6%94%BB%E7%95%A5%E3%81%99%E3%82%8B%E3%80%8EAWS%E8%AA%8D%E5%AE%9A-%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3-%E5%B0%82%E9%96%80%E7%9F%A5%E8%AD%98%E3%80%8F-Compass-Books%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-NRI%E3%83%8D%E3%83%83%E3%83%88%E3%82%B3%E3%83%A0%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE-ebook/dp/B08DCLRHC7/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=3RCCWVIIJDP4G&keywords=aws+%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3&qid=1651907810&sprefix=aws+%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%2Caps%2C196&sr=8-1

# IAMポリシー

## 4種類のポリシーの違い
IAMで使えるポリシーは4種類あり、IAMエンティティとの関係性が若干違う

1. AWS管理ポリシー、カスタマー管理ポリシー
    - 複数のエンティティにまたがって設定ができる
    - いずれもIAMエンティティの外部リソースとして存在する
　→「IAMロールにアタッチ・デタッチする」の表現が適切

2. インラインポリシー、アクセス許可境界
    - 一つのエンティティ固有の設定
    - いずれもIAMエンティティの属性（内部リソース）として存在する
　→「作成・削除（Put,Delete）」の表現が適切


- AWS全体を見ると、ポリシーは全部で6種類ある

↓　6種類のポリシーについての説明　↓

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies.html#access_policy-types

## SCPとアクセス許可境界
二つとも似た役割を持つが、対象範囲が異なる
- SCPは複数アカウントにまたがった設定ができる
- アクセス許可境界はIAMエンティティ固有の設定ができる

↓　講師の波多野さんの説明ツイート　↓

https://twitter.com/tcsh/status/1522427520628719616?s=20&t=VVKR1WEsjXn3Wim3Jt9g2Q

## ポリシーの評価順序
講師の波多野さんが作成してくださった図がとても分かりやすいです
- AWSで使われる6つのポリシーのうち、IAMとの関係性が特に強い5つのポリシーがどのように評価されるのかが書かれています
    - Organiations SCP
    - リソースベースのポリシー
    - アイディンティベースのポリシー
    - アクセス許可境界
    - セッションポリシー

https://twitter.com/tcsh/status/1522107952936620032?s=20&t=VWaMUwCb3ljTVPV_2cmgTg

# インスタンスプロファイル

## インスタンスプロファイルとは
- EC2インスタンスとIAMロールをくっつける、接着剤の役割を持つオブジェクト

- EC2特有の機能、かつEC2にIAMロールをアタッチするために必須のオブジェクト
    - なぜEC2にのみあるのかは不明、公式発表もないらしい
    - 推測して楽しみましょう

↓　インスタンスプロファイルについての説明　↓

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html


## 注意点
- GUIでIAMロールを作成すると自動作成されるが、CLIやSDKでは自動作成されない

- **利用するときはIMDSv2にすることを強く推奨（デフォルトはv1）**
    - proxyサーバーで公開されたEC2インスタンスでIMDSv1を利用している場合、SSRF攻撃によって認証情報を抜かれてしまうため
- IMDSとは
    - Instance Metadata Serviceの略で、EC2からIMDSにアクセスするとインスタンスのメタデータを取得できる

↓　IMDSv1,v2の違い、具体的にどこがセキュアなのかの説明　↓

https://blog.serverworks.co.jp/tech/2019/11/27/imdsv2/

↓　セキュリティといえばこの方、徳丸さんがIMDSv2について言及している記事です　↓

https://blog.tokumaru.org/2019/12/defense-ssrf-amazon-ec2-imdsv2.html

↓　SSRF攻撃が何なのかわからない方のための説明記事　↓

https://blog.tokumaru.org/2018/12/introduction-to-ssrf-server-side-request-forgery.html

↓　実際にIMDSv1の脆弱性を突かれてしまった事故事例　↓

https://piyolog.hatenadiary.jp/entry/2019/08/06/062154

## Tips
- 現在は後付け可能だが、以前は後付け不可だった
    - 当時は、空でもいいからインスタンスプロファイルをアタッチしておくのがベストプラクティスだった

- サブコマンド"list-instance-profiles"で確認可だが、"list-roles"では確認不可
    - インスタンスプロファイルからIAMロールを見に行く仕組みになっているため
    - IAMロールからインスタンスプロファイルを見に行く仕組みではない。だから"list-roles"では見えないと思われる。

# その他Tips
## AWS CLI でサポートされている環境変数
- AWS_SHARED_CREDENTIALS_FILE
    - AWS CLI がアクセスキーを保存するために使用するファイルの場所

- AWS_PROFILE
    - 使用する認証情報およびオプションと共に AWS CLI プロファイルの名前。プロファイル名は、iniファイル内で[プロファイル名]と表現する

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-envvars.html


## AWSで使われるポリシーの文法
- SCP、セッションポリシー、VPCエンドポイントのポリシー、信頼ポリシー、IAMポリシーなどは同じ文法

- ACLのポリシーの文法は異なる（AWSが公式に公表）