Help us understand the problem. What is going on with this article?

[JAWS-UG CLI] Amazon KMS 入門 (1) カスタマーマスターキーの作成

More than 3 years have passed since last update.

このハンズオンについて

この手順は、JAWS-UG CLI専門支部 #58 KMS入門で実施したものです。

前提条件

必要な権限

作業にあたっては、以下の権限を有したIAMユーザもしくはIAMロールを利用してください。

  • KMSに対するフルコントロール権限
  • S3に関するフルコントロール権限
  • STSに関するフルコントロール権限
  • IAMに関するフルコントロール権限

0. 準備

0.1. リージョンを指定

コマンド
export AWS_DEFAULT_REGION='ap-northeast-1'

0.2. 資格情報を確認

コマンド
aws configure list

インスタンスプロファイルを設定したEC2インスタンスでアクセスキーを設定せずに実行した場合、以下のようになります。

結果
Name                    Value             Type    Location
----                    -----             ----    --------
profile                <not set>             None    None
access_key     ****************RDPA         iam-role
secret_key     ****************9GA8         iam-role
region           ap-northeast-1              env    AWS_DEFAULT_REGION

0.3. バージョン確認

コマンド
aws --version
結果
aws-cli/1.10.56 Python/2.7.10 Linux/4.4.15-25.57.amzn1.x86_64 botocore/1.4.46

0.4. バージョンアップ(必要に応じて)

コマンド
sudo pip install -U awscli

1. カスタマーマスターキーの作成

1.1. キーの不存在を確認

コマンド
aws kms list-keys
結果
{
    "Keys": []
}

1.2. カスタマーマスターキーの説明を指定

descriptionは必須ではありませんが、運用時にはきちんと設定しましょう。

コマンド
KEY_DESCRIPTION='JAWS-UG CLI 58 KMS at Co-Edo'

1.3. カスタマーマスターキーの作成

変数の確認

コマンド
cat << ETX

    KEY_DESCRIPTION: "${KEY_DESCRIPTION}"

ETX
結果
    KEY_DESCRIPTION: "JAWS-UG CLI 58 KMS at Co-Edo"

カスタマーマスターキーの作成

コマンド
KEY_ID=$(aws kms create-key \
    --description "${KEY_DESCRIPTION}" \
    --query KeyMetadata.KeyId \
    --output text) \
    && echo ${KEY_ID}
結果(例)
********-****-****-****-************

1.4. キーの存在確認

コマンド
aws kms list-keys \
    --query "Keys[?KeyId == \`${KEY_ID}\`]"
結果
{
    "Keys": [
        {
            "KeyArn": "arn:aws:kms:ap-northeast-1:************:key/********-****-****-****-************",
            "KeyId": "********-****-****-****-************"
        }
    ]
}

1.5. キーの確認

コマンド
aws kms describe-key \
    --key-id ${KEY_ID}
結果
{
    "KeyMetadata": {
        "KeyId": "********-****-****-****-************",
        "Description": "JAWS-UG CLI 58 KMS at Co-Edo",
        "Enabled": true,
        "KeyUsage": "ENCRYPT_DECRYPT",
        "KeyState": "Enabled",
        "CreationDate": 1467540748.716,
        "Arn": "arn:aws:kms:ap-northeast-1:************:key/********-****-****-****-************",
        "AWSAccountId": "************"
    }
}

1.6. エイリアス名の指定

CMKを識別する際、KeyIdの以外にAliasを指定することが可能です。

コマンド
ALIAS="alias/cli-handson0800"

1.7. エイリアスの作成

変数の確認

コマンド
cat << ETX

    ALIAS: ${ALIAS}
    KEY_ID: ${KEY_ID}

ETX
結果
    ALIAS: alias/cli-handson08015
    KEY_ID: ********-****-****-****-************

エイリアスの作成

コマンド
aws kms create-alias \
    --alias-name ${ALIAS} \
    --target-key-id ${KEY_ID}
結果
(返値無し)

1.8. エイリアスの確認

コマンド
aws kms list-aliases \
    --query "Aliases[?TargetKeyId == \`${KEY_ID}\`]"
結果
{
    "Aliases": [
        {
            "AliasArn": "arn:aws:kms:ap-northeast-1:************:alias/cli-handson01",
            "AliasName": "alias/cli-handson01",
            "TargetKeyId": "********-****-****-****-************"
        }
    ]
}

2. ユーザの作成

KMSによるユーザ操作を行うためのIAMユーザを定義します。

このシナリオでは、データキーを取り扱う一般ユーザと、CMKの管理を行う管理者ユーザを作成します。

これらのユーザに対し、KMSに関する権限をIAMでは付与せず、KMS側でコントロールします。
(詳細は後述します。)

2.1. 管理ユーザ名の指定

コマンド
ADMIN_NAME='jawsug-cli-admin'

2.2. 管理ユーザの不存在を確認

コマンド
aws iam get-user \
    --user-name ${ADMIN_NAME}
結果
An error occurred (NoSuchEntity) when calling the GetUser operation: The user with name jawsug-cli-admin cannot be found.

2.3. 管理ユーザの作成

変数の確認

コマンド
cat << ETX

    ADMIN_NAME: ${ADMIN_NAME}

ETX
結果
    ADMIN_NAME: jawsug-cli-admin

管理ユーザの作成

コマンド
aws iam create-user \
    --user-name ${ADMIN_NAME}
結果
{
    "User": {
        "UserName": "jawsug-cli-admin",
        "Path": "/",
        "CreateDate": "2016-07-23T06:59:00.482Z",
        "UserId": "A********************",
        "Arn": "arn:aws:iam::************:user/jawsug-cli-admin"
    }
}

2.4. 実行結果の確認

コマンド
aws iam get-user \
    --user-name ${ADMIN_NAME}
結果
{
    "User": {
        "UserName": "jawsug-cli-admin",
        "Path": "/",
        "CreateDate": "2016-08-01T09:22:14Z",
        "UserId": "A********************",
        "Arn": "arn:aws:iam::************:user/jawsug-cli-admin"
    }
}

2.5. 利用ユーザ名の指定

コマンド
USER_NAME='jawsug-cli-user'

2.6. 利用ユーザの不存在を確認

コマンド
aws iam get-user \
    --user-name ${USER_NAME}
結果
An error occurred (NoSuchEntity) when calling the GetUser operation: The user with name jawsug-cli-user cannot be found.

2.7. 利用ユーザの作成

変数の確認

コマンド
cat << ETX

    USER_NAME: ${USER_NAME}

ETX
結果
    USER_NAME: jawsug-cli-user

利用ユーザの作成

コマンド
aws iam create-user \
    --user-name ${USER_NAME}
結果
{
    "User": {
        "UserName": "jawsug-cli-user",
        "Path": "/",
        "CreateDate": "2016-07-23T07:00:59.402Z",
        "UserId": "A********************",
        "Arn": "arn:aws:iam::************:user/jawsug-cli-user"
    }
}

2.8. 実行結果の確認

コマンド
aws iam get-user \
    --user-name ${USER_NAME}
結果
{
    "User": {
        "UserName": "jawsug-cli-user",
        "Path": "/",
        "CreateDate": "2016-08-01T09:24:40Z",
        "UserId": "A********************",
        "Arn": "arn:aws:iam::************:user/jawsug-cli-user"
    }
}

3. ポリシーの定義

KMSで作成するCMK(カスタマーマスターキー)に対して設定するポリシーを定義します。
(IAMユーザに対してではなく、リソースであるCMSに対して付与するポリシーです。)

先に作成したIAMユーザに対する権限付与は、ここで実施します。

3.1. AWSアカウントIDの特定

コマンド
AWS_ID=$(aws sts get-caller-identity \
    --query Account \
    --output text) \
    && echo ${AWS_ID}
結果
************

3.2. ポリシーを生成するファイル名を指定

コマンド
POLICY_FILE='policy.json'

3.3. ポリシーの生成

変数の確認

コマンド
cat << ETX

    POLICY_FILE: ${POLICY_FILE}
    AWS_ID: ${AWS_ID}
    ADMIN_NAME: ${ADMIN_NAME}
    USER_NAME: ${USER_NAME}

ETX
結果
    POLICY_FILE: policy.json
    AWS_ID: ************
    ADMIN_NAME: jawsug-cli-admin
    USER_NAME: jawsug-cli-user

ポリシーの生成

ここでは以下の4つの目的を実現するためのポリシーを記載しています。

  • rootユーザにKMSに関する全ての権限を付与
  • 管理者ユーザにCMKを管理する権限を付与
  • 一般ユーザにCMKを利用する権限を付与
  • 永続化リソースの適用許可

以下の記事が参考になります。

AWS Key Management Serviceでキーの”管理”と”利用”を分離する #reinvent

コマンド
cat << EOF > ${POLICY_FILE}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Enable IAM User Permissions",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::${AWS_ID}:root"
        ]
      },
      "Action": "kms:*",
      "Resource": "*"
    },
    {
      "Sid": "Allow access for Key Administrators",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::${AWS_ID}:user/${ADMIN_NAME}"
        ]
      },
      "Action": [
        "kms:Create*",
        "kms:Describe*",
        "kms:Enable*",
        "kms:List*",
        "kms:Put*",
        "kms:Update*",
        "kms:Revoke*",
        "kms:Disable*",
        "kms:Get*",
        "kms:Delete*",
        "kms:ScheduleKeyDeletion",
        "kms:CancelKeyDeletion"
      ],
      "Resource": "*"
    },
    {
      "Sid": "Allow use of the key",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::${AWS_ID}:user/${USER_NAME}"
        ]
      },
      "Action": [
        "kms:Encrypt",
        "kms:Decrypt",
        "kms:ReEncrypt*",
        "kms:GenerateDataKey*",
        "kms:DescribeKey"
      ],
      "Resource": "*"
    },
    {
      "Sid": "Allow attachment of persistent resources",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::${AWS_ID}:user/${USER_NAME}"
        ]
      },
      "Action": [
        "kms:CreateGrant",
        "kms:ListGrants",
        "kms:RevokeGrant"
      ],
      "Resource": "*",
      "Condition": {
        "Bool": {
          "kms:GrantIsForAWSResource": true
        }
      }
    }
  ]
}
EOF

jsonlint -q ${POLICY_FILE}

3.4. ポリシー名の決定

defaultを使用しなければならないことがドキュメントに明記されています。

コマンド
POLICY_NAME="default"

3.5. ポリシーの設定

変数の確認

コマンド
cat << ETX

    KEY_ID: ${KEY_ID}
    POLICY_NAME: ${POLICY_NAME}
    POLICY_FILE: ${POLICY_FILE}

ETX
結果
    KEY_ID: ********-****-****-****-************
    POLICY_NAME: default
    POLICY_FILE: policy.json

ポリシーの設定

コマンド
aws kms put-key-policy \
    --key-id ${KEY_ID} \
    --policy-name ${POLICY_NAME} \
    --policy file://${POLICY_FILE}
結果
(戻り値なし)

3.6. ポリシーの確認

コマンド
aws kms get-key-policy \
    --key-id ${KEY_ID} \
    --policy-name ${POLICY_NAME}
結果
{
    "Policy": "{\n  \"Version\" : \"2012-10-17\",\n  \"Statement\" : [ {\n    \"Sid\" : \"Enable IAM User Permissions\",\n    \"Effect\" : \"Allow\",\n    \"Principal\" : {\n      \"AWS\" : \"arn:aws:iam::************:root\"\n    },\n    \"Action\" : \"kms:*\",\n    \"Resource\" : \"*\"\n  }, {\n    \"Sid\" : \"Allow access for Key Administrators\",\n    \"Effect\" : \"Allow\",\n    \"Principal\" : {\n      \"AWS\" : \"arn:aws:iam::************:user/jawsug-cli-admin\"\n    },\n    \"Action\" : [ \"kms:Create*\", \"kms:Describe*\", \"kms:Enable*\", \"kms:List*\", \"kms:Put*\", \"kms:Update*\", \"kms:Revoke*\", \"kms:Disable*\", \"kms:Get*\", \"kms:Delete*\", \"kms:ScheduleKeyDeletion\", \"kms:CancelKeyDeletion\" ],\n    \"Resource\" : \"*\"\n  }, {\n    \"Sid\" : \"Allow use of the key\",\n    \"Effect\" : \"Allow\",\n    \"Principal\" : {\n      \"AWS\" : \"arn:aws:iam::************:user/jawsug-cli-user\"\n    },\n    \"Action\" : [ \"kms:Encrypt\", \"kms:Decrypt\", \"kms:ReEncrypt*\", \"kms:GenerateDataKey*\", \"kms:DescribeKey\" ],\n    \"Resource\" : \"*\"\n  }, {\n    \"Sid\" : \"Allow attachment of persistent resources\",\n    \"Effect\" : \"Allow\",\n    \"Principal\" : {\n      \"AWS\" : \"arn:aws:iam::************:user/jawsug-cli-user\"\n    },\n    \"Action\" : [ \"kms:CreateGrant\", \"kms:ListGrants\", \"kms:RevokeGrant\" ],\n    \"Resource\" : \"*\",\n    \"Condition\" : {\n      \"Bool\" : {\n        \"kms:GrantIsForAWSResource\" : \"true\"\n      }\n    }\n  } ]\n}"
}

以上

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away