30
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

IAMベストプラクティスにほぼほぼ準拠したIAMユーザ・グループ作成と、MFA デバイスの自己管理を許可するポリシーの取り扱い注意点

Last updated at Posted at 2020-02-29

1. はじめに

  • AWS マネジメントコンソール作業で使用するIAMグループ や IAMユーザーの設計や作成フローを、IAM ベストプラクティス を参考にして見直してみる。
  • けど、IAMグループ や IAMユーザー の作成に関する IAM ベストプラクティス をすべて採用するのは窮屈なので、採用するものを決めて My IAM プラクティスを作成してみる。
  • そして、My IAM プラクティスに準拠したIAM グループ、IAMユーザーの作成フローを構築してみる。
  • 例として、新規に参画したAWS マネジメントコンソール作業者で、開発チームのAさんの IAM ユーザーを作成してみる。
  • あと、IAMポリシーとIAMグループを Terraform で、IAMユーザーを CloudFormation でコード化する。

    ※ IAMユーザーの Terraform 化は、aws_iam_user_login_profile の pgp_key のところがなんか面倒いので、やむを得ず CloudFormation を使ってる。。

2. My IAM プラクティス

AWSの IAM ベストプラクティスで採用するもの

* [IAM ユーザーへのアクセス許可を割り当てるためにグループを使用する](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html#use-groups-for-permissions) * IAMユーザーにポリシーをアタッチするのはNG。「IAMグループ作成 ⇒ IAMグループにポリシーをアタッチ ⇒ IAMユーザーをIAMグループに割り当てる」という流れでIAMユーザーに権限を与える。 * IAM グループに少なくとも 1 つの IAM ユーザーが存在するかどうかを AWS Config マネージドルール の [iam-group-has-users-check](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/iam-group-has-users-check.html) でチェックすることができる。 * IAM ユーザーが少なくとも 1 つの IAM グループのメンバーであるかどうかを AWS Config マネージドルール の [iam-user-group-membership-check](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/iam-user-group-membership-check.html) でチェックすることができる。 * IAMユーザーにポリシーがアタッチされているかどうかを AWS Config マネージドルール の [iam-user-no-policies-check](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/iam-user-no-policies-check.html) でチェックすることができる。何かしらのポリシーがアタッチされていたら、非準拠となる。

* [AWS 管理ポリシーを使用したアクセス許可の使用開始](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html#bp-use-aws-defined-policies) * 例えば、開発者用ユーザーには 「AWSにより管理」されている [PowerUserAccess](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_job-functions.html#jf_developer-power-user) ポリシー の権限を与える。

* [インラインポリシーではなくカスタマー管理ポリシーを使用する](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html#best-practice-managed-vs-inline) * 「AWSにより管理」されているポリシーリストに適切なポリシーがない場合は、利用者側でポリシーを作成する。 * このとき、インラインポリシーとしてIAMグループにアタッチするのではなく、「カスタマー管理(ユーザーによる管理)」ポリシーとして作成して、IAMグループにアタッチする。

* [ユーザーの強力なパスワードポリシーを設定](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html#configure-strong-password-policy) * IAM ユーザーのアカウントパスワードポリシーが、指定した要件を満たしているかどうかを AWS Config マネージドルール の [iam-password-policy](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/iam-password-policy.html) でチェックすることができる。

* [MFA の有効化](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html#enable-mfa-for-privileged-users) * コンソールパスワードを使用するすべての IAM ユーザーについて MFA が有効になっているかどうかを AWS Config マネージドルール の [mfa-enabled-for-iam-console-access](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/mfa-enabled-for-iam-console-access.html) でチェックすることができる。

AWSの IAM ベストプラクティスで採用しないもの

次も My IAM プラクティスに追加する

  • AWS マネジメントコンソール作業で使用するIAMユーザーには、プログラムによるアクセスを許可しない(アクセスキー ID と シークレットアクセスキー を作成しない)。
  • IAMユーザー 自身が AWS マネジメントコンソール のパスワードを変更できるようにする。
  • IAMユーザー 自身が MFA を設定/変更できるようにする。

3. My IAM プラクティスに準拠したIAMユーザーを作成するフロー

  1. 新規に参画したAWS マネジメントコンソール作業者に与える権限(ポリシー)を決定する。2. へ。

2. 与えるべき権限(ポリシー)を持ったIAMグループがすでにあれば、4.へ。なければ 3. へ。

3. 与えるべき権限(ポリシー)を持ったIAMグループがなければ、IAMグループを作成して適切な AWS管理ポリシー をアタッチする。
もし、適切な AWS管理ポリシーがなければ、ポリシー(インラインポリシーではなく、カスタマー管理ポリシー)を作成してIAMグループにアタッチする。4. へ。

4. IAMユーザーを作成する。
・共有ではなく個々に作る。
・ポリシーはアタッチしない。
・所属するIAMグループを設定する。

4. My IAM プラクティスで開発者AさんのIAMユーザーを作成する例

1. ユーザーの強力なパスワードポリシーを設定する(IAMユーザー全体に影響する設定)

20200229-01.png
20200229-02.png
image.png
こんな感じに設定
image.png

2. ユーザーにパスワード変更を許可する設定(IAMユーザー全体に影響する設定)

パスワードポリシー設定で、「ユーザーにパスワードの変更を許可する」にチェックする。
これにチェックしておけば、AWSによる管理の「IAMUserChangePassword」ポリシーをアタッチしなくても、自身がパスワードを変更できるようになる。

20200229-03.png

3. 開発者Aさんに PowerUserAccess 権限を与えることにする

  • 注意点その1:AdministratorAccess とか、PowerUserAccess ポリシー

  • AWSによる管理の AdministratorAccess ポリシーも、 PowerUserAccess ポリシーも、IAM 操作権限がない。

  • なので、AWS管理者がIAM周りの作業を行うためには、AdministratorAccess ポリシーに加えて、IAMFullAccess ポリシーをアタッチする。

  • 開発者Aが自身のMFAを設定/変更できるようにするためには、PowerUserAccess ポリシーに加えて、MFA デバイスの自己管理を許可する ポリシーをアタッチする。(マネジメントコンソールのパスワード変更は、パスワードポリシーのところで許可してあれば、IAMUserChangePassword ポリシーはアタッチ不要)

  • 注意点その2MFA デバイスの自己管理を許可する ポリシー

  • このポリシーについては、数日前にクラスメソッドに素敵な記事が上がっていたので、説明は省く。

  • 気をつけないといけないのは、次の3点。

    1. MFA認証でサインインしないと、アタッチされているポリシーがすべて無効になる。例えば、PowerUserAccess ポリシーをアタッチしていたとしても、マネジメントコンソールのすべてのAWSサービスのページで権限がないと表示されてしまう。

2. IAMグループに [MFA デバイスの自己管理を許可する](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_iam_mfa-selfmanage.html) ポリシーをアタッチして、そのIAMグループに新規IAMユーザーを割り当てて作成するとき、IAMユーザー作成設定で「パスワードのリセットが必要」にチェックを入れてしまうと、初回サインイン時のパスワード変更が権限不足で変更できなくなる。

3. このポリシーをアタッチしたIAMユーザーが AWS CLI を使うと、Access Denied される
例)
$ aws s3 ls
An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied

次の方法でMFAをパスする必要がある
[MFA トークンを使用して、AWS CLI 経由で AWS リソースへのアクセスを認証する方法を教えてください。](https://aws.amazon.com/jp/premiumsupport/knowledge-center/authenticate-mfa-cli/)
  • 手順例
  • セッショントークンを発行する

$ aws sts get-session-token --serial-number "MFAのarn" --token-code "MFAデバイスから発行される6桁の数字"

必要に応じて --profile オプションを付ける場合


$ aws --profile hogehoge sts get-session-token --serial-number "MFAのarn" --token-code "MFAデバイスから発行される6桁の数字"

MFAのARNは、AWSマネジメントコンソールのIAMから確認できる
20201105.png
  • パスが通ると次のような情報が返ってくる。このSessionTokenにはExpiration(有効期限)がある。
{
    "Credentials": {
        "AccessKeyId": "aaaaaaaaaaaaaaaaaaaa",
        "SecretAccessKey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
        "SessionToken": "cccccccc....",
        "Expiration": "2020-11-05T17:08:48+00:00"
    }
}
  • シェルに環境変数を設定する

$ export AWS_ACCESS_KEY_ID=aaaaaaaaaaaaaaaaaaaa
$ export AWS_SECRET_ACCESS_KEY=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
$ export AWS_SESSION_TOKEN=cccccccc....
  • これで、トークンが有効期間中 AWS CLIが使えるようになった

$ aws --profile hogehoge s3 ls
2020-10-16 19:29:24 AAAA
2020-08-03 22:01:02 BBBB
2020-08-11 17:03:37 CCCC
  • MFA デバイスの自己管理を許可する ポリシーをアタッチしている IAMユーザー の初回サインイン時のパスワード変更エラーの例

  • IAMユーザー作成設定の「パスワードのリセットが必要」にチェック

    20200229-04.png

  • 初回サインイン

    20200229-05.png

  • パスワード変更画面

    アカウントパスワードポリシーに準拠した新しいパスワードを入力

    20200229-06.png

  • パスワード変更できない!

    「ユーザーに iam:ChangePassword を実行する権限がないか、入力されたパスワードが管理者によって設定されたアカウントパスワードポリシーに準拠していません」

    20200229-07.png

4. IAMグループを作成する

5. IAMユーザーを作成する

  • 開発者A用のIAM ユーザー「userA」を作成する。
  • 初回サインイン時にパスワード変更しない設定する。
  • MFA デバイスの自己管理を許可する ポリシーのため、パスワードを変更できない。
  • アカウントパスワードポリシーのルールで90日後には強制的にパスワードを変更させる。
  • IAMグループ「developers」に割り当てる。

6. IAMユーザー作成後の初回のサインイン時にやること

  • 初回サインイン

    20200229-05.png

  • サインイン後にEC2のページにいくと、認証エラー
    20200229-08.png

  • なので、何よりも先に MFA 設定を行う
    20200229-09.png

    20200229-10.png
    ※ MFA設定方法は割愛

  • MFAの設定が終わったら、サインアウトする
    20200229-11.png

  • 再度、サインインする

  • パスワード認証

    20200229-05.png

  • MFA認証

    20200229-12.png

  • 正常サインイン後にEC2のページに行ってみると見えてる

    20200229-13.png

  • マネジメントコンソールのパスワードを変更する
    20200229-14.png

    20200229-15.png
    ※ パスワード設定変更方法は割愛

5. AWS Config ルールでチェック、チェック!

AWS Configの初期設定とマネージドルールを Terraform で設定して、非準拠項目を確認して対処してみる

6. コード化

  • MFA デバイスの自己管理を許可する ポリシー を Terraform で作成する。

    ※ AWS Documentの方は、AWSアカウントIDのところが「*」になっている。
    ※ 下記の Terraform では、実際のアカウントIDが入るようにしている。
policy_enable-mfa-device.tf
data "aws_caller_identity" "current" {
}
data "aws_iam_policy_document" "policy-document_enable-mfa-device" {
  version = "2012-10-17"
  statement {
    effect = "Allow"
    actions = [
      "iam:ListUsers",
      "iam:ListVirtualMFADevices"
    ]
    resources = [
      "*"
    ]
  }
  statement {
    effect = "Allow"
    actions = [
      "iam:ListMFADevices"
    ]
    resources = [
      "arn:aws:iam::${data.aws_caller_identity.current.account_id}:mfa/*",
      "arn:aws:iam::${data.aws_caller_identity.current.account_id}:user/$${aws:username}"
    ]
  }
  statement {
    effect = "Allow"
    actions = [
      "iam:CreateVirtualMFADevice",
      "iam:DeleteVirtualMFADevice",
      "iam:EnableMFADevice",
      "iam:ResyncMFADevice"
    ]
    resources = [
      "arn:aws:iam::${data.aws_caller_identity.current.account_id}:mfa/$${aws:username}",
      "arn:aws:iam::${data.aws_caller_identity.current.account_id}:user/$${aws:username}"
    ]
  }
  statement {
    effect = "Allow"
    actions = [
      "iam:DeactivateMFADevice"
    ]
    resources = [
      "arn:aws:iam::${data.aws_caller_identity.current.account_id}:mfa/$${aws:username}",
      "arn:aws:iam::${data.aws_caller_identity.current.account_id}:user/$${aws:username}"
    ]
    condition {
      test     = "Bool"
      variable = "aws:MultiFactorAuthPresent"
      values   = ["true"]
    }
  }
  statement {
    effect = "Deny"
    not_actions = [
      "iam:CreateVirtualMFADevice",
      "iam:EnableMFADevice",
      "iam:ListMFADevices",
      "iam:ListUsers",
      "iam:ListVirtualMFADevices",
      "iam:ResyncMFADevice"
    ]
    resources = [
      "*"
    ]
    condition {
      test     = "BoolIfExists"
      variable = "aws:MultiFactorAuthPresent"
      values   = ["false"]
    }
  }
}
resource "aws_iam_policy" "policy_enable-mfa-device" {
  name   = "enable-mfa-device"
  policy = data.aws_iam_policy_document.policy-document_enable-mfa-device.json
}
group_developers.tf
resource "aws_iam_group" "developers" {
  name = "developers"
  path = "/"
}
resource "aws_iam_group_policy_attachment" "developers-PowerUserAccess" {
  group      = aws_iam_group.developers.name
  policy_arn = "arn:aws:iam::aws:policy/PowerUserAccess"
}
resource "aws_iam_group_policy_attachment" "developers-enable-mfa-device" {
  group      = aws_iam_group.developers.name
  policy_arn = "arn:aws:iam::************:policy/enable-mfa-device"
}
  • IAMユーザー「userA」を CloudFormation で作成する。
  • Groups は、「developers」を設定する
  • UserNaameは、「userA」を設定する
  • Password は、パスワードポリシーに準拠したもの
  • PasswordResetRequired(パスワードのリセットが必要)は無効にする。
IAMUser-userA.yaml
AWSTemplateFormatVersion: 2010-09-09
Description: IAM User - userA
Resources:
  IAMUser:
    Type: 'AWS::IAM::User'
    Properties:
      Groups:
        - developers
      Path: /
      UserName: userA
      LoginProfile:
        Password: ************
        PasswordResetRequired: false
Outputs:
  IAMUser:
    Description: IAM User Name
    Value: !Ref IAMUser
30
36
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?