Dome9で管理操作を一時的に許可する

2018.10.17

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

中山(順)です

皆さんのAWSアカウントでは管理権限をどのように付与していますか?

IAMを含む完全な管理権限を付与しているということは、あらゆるサービスの管理権限を他のIAM Userに付与することが可能ということです。 また、IAMの管理権限は持たないまでも特定のサービスの管理権限を持っていればそのサービス内では(やろうと思えば)やりたい放題です。

管理者も人です。出来心で何かやってしまいかもしれません。ミスをすることもあるでしょう。 管理者に対する監査ができるようにしておくのは当然として、何かしら権限を制限したくなるはずです。 そのため、管理者は少数のメンバーにとどめ、それ以外の運用担当者や開発メンバーに対しては一部のサービス/リソースに対して必要最小限度のアクションを許可する、というアプローチを取ることになります。

また、その管理権限は常に必要なわけではありません。 時間軸でも制限することでより厳格な運用が可能です。それが必要かは、その組織やビジネス次第ですが。

ちなみ、Systems Managerで実装する場合には以下のようになります。あくまでも一例です。

IAMユーザーに特権を一時的に付与する簡易承認ワークフローをSystems Manager (Automation) で実装してみた

しかし、この方法ではアカウント毎にSSM Documentを作成する必要があるなど手間がかかります。 マルチアカウント戦略も一長一短ですよね、現状はメリットの方が多い印象ですが。

Dome9にはIAM Safetyという機能があり、一時的に特権を付与することが可能です。 また、複数のAWSアカウントを1つのDome9アカウントで管理できます。 ということで実際に使ってみました。

機能紹介

IAM Safety

仕組みをざっくりと説明します。

まず、制限したいサービス/リソースへのアクションを拒否する(Deny)ポリシーをDome9上で定義します。 次に管理操作を制限したいIAM UserをDome9のコンソールから指定します。これで、指定されたIAM Userには最初に定義したDenyポリシーがIAM Userに割り当てられます。 これにより、指定されたIAM Userは管理操作を制限されます。 ちなみに、(AWSの)Management Consoleでポリシーを外してもDome9によってロールバックされます。

管理操作を実施したい時には、Dome9のコンソールもしくはスマホアプリから昇格作業を行います。 すると、制限が解除されて管理操作を実行できるようになります。 ただし、昇格時に指定した時間が経過すると制限が復活します。

詳細はドキュメントをご確認ください。

Dome9 Help Center // Documentation // IAM Safety

前提条件

Dome9にAWSアカウントを追加する際に"Full-Protection"モードで登録しておく必要があります。

(2019年6月4日追記)こちらの記載は誤りでした。IAM Safetyに必要な権限はIAM Safetyの初期設定時に別途付与します。

やってみた

実際に動作を確認します。

Dome9にAWSアカウントを追加する手順は以下の記事を参照してください。

Dome9でSecurityGroupを可視化してみた

IAM PolicyおよびIAM Groupの作成

まずは、IAM Safetyのメニューを開きます。 「IAM Safety」 > 「アカウントとIAMユーザー」をクリックします。

未設定の場合は以下の画面が表示されます。「開始」をクリックし、ウィザードを開始します。

最初に何やらポリシーを作成するような画面が表示されます。 ここでは、「通常はIAM Userに実施されたくないこと」をポリシーとして定義します。

何種類かテンプレートも用意されていますし、アクションを個別に選択することも可能です。また、JSONで直接ポリシーを書くことも可能です。

"Compute"というテンプレートは以下のようになっています。作成/変更/削除系のアクションが含まれていることがわかります。

ポリシーを定義したら「次へ」をクリックして先に進みます。

次に、IAM Safetyを利用したいAWSアカウントでIAM GroupとIAM Policyを作成します。併せて、PolicyをGroupにアタッチします。

まずはポリシーを作成します。

POLICY_FILE="policy.json"

cat << EOF > ${POLICY_FILE}
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Dome9IamSafe",
            "Effect": "Deny",
            "Action": [
                "autoscaling:Delete*",
                "autoscaling:Terminate*",
                "autoscaling:Update*",
                "ec2:CreateNetworkAcl",
                "ec2:CreateNetworkAclEntry",
                "ec2:CreateNetworkInterface",
                "ec2:CreateSecurityGroup",
                "ec2:Delete*",
                "ec2:DetachInternetGateway",
                "ec2:DetachNetworkInterface",
                "ec2:DetachVolume",
                "ec2:DisassociateAddress",
                "ec2:GetPasswordData",
                "ec2:ImportKeyPair",
                "ec2:ReplaceNetworkAclAssociation",
                "ec2:ReplaceNetworkAclEntry",
                "ec2:ReplaceRoute",
                "ec2:ReplaceRouteTableAssociation",
                "ec2:Stop*",
                "ec2:Terminate*",
                "ecs:Delete*",
                "elasticbeanstalk:Delete*",
                "elasticbeanstalk:Terminate*",
                "elasticloadbalancing:CreateLoadBalancer",
                "elasticloadbalancing:CreateLoadBalancer",
                "elasticloadbalancing:CreateLoadBalancerListeners",
                "elasticloadbalancing:CreateLoadBalancerPolicy",
                "elasticloadbalancing:Delete*",
                "elasticloadbalancing:Delete*",
                "elasticloadbalancing:Deregister*",
                "elasticloadbalancing:Detach*",
                "elasticloadbalancing:Disable*",
                "elasticloadbalancing:Enable*",
                "elasticloadbalancing:RegisterInstancesWithLoadBalancer",
                "lambda:Add*",
                "lambda:CreateEventSourceMapping",
                "lambda:CreateFunction",
                "lambda:Delete*",
                "lambda:Re*",
                "lambda:UpdateFunctionCode",
                "lambda:UpdateFunctionConfiguration",
                "ssm:CreateAssociation",
                "ssm:CreateDocument",
                "ssm:Delete*"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "Dome9IamSafeMandatory",
            "Effect": "Deny",
            "Action": [
                "iam:Add*",
                "iam:Attach*",
                "iam:Create*",
                "iam:Deactivate*",
                "iam:Delete*",
                "iam:Detach*",
                "iam:Put*",
                "iam:Remove*",
                "iam:Set*",
                "iam:Update*",
                "iam:Upload*"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
EOF

aws iam create-policy \
    --policy-name Dome9-Restricted-Policy \
    --policy-document file://${POLICY_FILE}
{
    "Policy": {
        "PolicyName": "Dome9-Restricted-Policy",
        "PermissionsBoundaryUsageCount": 0,
        "CreateDate": "2018-09-28T09:49:37Z",
        "AttachmentCount": 0,
        "IsAttachable": true,
        "PolicyId": "ANPAI5CNC26Q6IEGPTGPO",
        "DefaultVersionId": "v1",
        "Path": "/",
        "Arn": "arn:aws:iam::XXXXXXXXXXXX:policy/Dome9-Restricted-Policy",
        "UpdateDate": "2018-09-28T09:49:37Z"
    }
}

次にGroupを作成します。

aws iam create-group \
    --group-name Dome9-Restricted-Group
{
    "Group": {
        "Path": "/",
        "CreateDate": "2018-09-28T10:15:07Z",
        "GroupId": "AGPAJE2IYSETQXTIQXWDW",
        "Arn": "arn:aws:iam::XXXXXXXXXXXX:group/Dome9-Restricted-Group",
        "GroupName": "Dome9-Restricted-Group"
    }
}

次に、PolicyをGroupにアタッチします。

aws iam attach-group-policy \
    --group-name Dome9-Restricted-Group \
    --policy-arn arn:aws:iam::XXXXXXXXXXXX:policy/Dome9-Restricted-Policy

最後に、GroupとPolicyのARNを入力して次に進みます。

次に、IAM Safetyを利用したいAWSアカウントを選択します。

次に、Dome9へAWSアカウントを登録したときに作成したIAM Roleにアタッチするポリシーを作成・アタッチします。 この権限を利用してIAM Safetyを実行します。

まず、Policyを作成します。

POLICY_FILE="policy.json"

cat << EOF > ${POLICY_FILE}
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Dome9IAMConnectRead",
            "Action": [
                "iam:Get*",
                "iam:List*"
            ],
            "Effect": "Allow",
            "Resource": "*"
        },
        {
            "Sid": "Dome9IAMConnectRoles",
            "Effect": "Allow",
            "Action": [
                "iam:AttachRolePolicy",
                "iam:DetachRolePolicy"
            ],
            "Condition": {
                "ArnEquals": {
                    "iam:PolicyArn": "arn:aws:iam::XXXXXXXXXXXX:policy/Dome9-Restricted-Policy"
                }
            },
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "Dome9IAMConnectUserGroup",
            "Effect": "Allow",
            "Action": [
                "iam:AddUserToGroup",
                "iam:RemoveUserFromGroup"
            ],
            "Resource": [
                "arn:aws:iam::XXXXXXXXXXXX:group/Dome9-Restricted-Group"
            ]
        }
    ]
}
EOF

aws iam create-policy \
    --policy-name Dome9-IAM-Policy \
    --policy-document file://${POLICY_FILE}
{
    "Policy": {
        "PolicyName": "Dome9-IAM-Policy",
        "PermissionsBoundaryUsageCount": 0,
        "CreateDate": "2018-09-28T10:20:08Z",
        "AttachmentCount": 0,
        "IsAttachable": true,
        "PolicyId": "ANPAIY7IHO3CLW3RFOA36",
        "DefaultVersionId": "v1",
        "Path": "/",
        "Arn": "arn:aws:iam::XXXXXXXXXXXX:policy/Dome9-IAM-Policy",
        "UpdateDate": "2018-09-28T10:20:08Z"
    }
}

作成したらPolicyをRoleにアタッチします。

aws iam attach-role-policy /
    --role-name Dome9-Connect \
    --policy-arn arn:aws:iam::XXXXXXXXXXXX:policy/Dome9-IAM-Policy

アタッチしたら次に進みます。

これで準備は完了です。

「IAM Safety」 > 「アカウントとIAMユーザー」をクリックします。

すると、アカウントが登録されたことが確認できます。

Dome9 Userの追加とIAM Userとの関連付け

次に、権限の付与を実施できるDome9ユーザーの招待と、招待したDome9ユーザーがどのIAM Userの権限を昇格できるようにするかを指定します。 AWSアカウントの登録を実施したDome9ユーザーは招待済みのため、このDome9ユーザーにIAM Userを割り当てます。

「IAM Safety」 > 「IAM Safetyの設定」をクリックします。

AWSアカウントをIAM Safetyに登録したら"PROTECT"をクリックして保護を有効化します。

制限したいIAM UserもしくはIAM Roleを指定します。 今回はIAM Userを設定します。

設定するとステータスが有効になっていることが確認できます。

これで、IAM Userが最初に作成したIAM Groupのメンバーになっているはずです。 以下の通り確認することができました。

aws iam list-groups-for-user --user-name cm-nakayama.nobuhiro
{
    "Groups": [
        {
            "Path": "/",
            "CreateDate": "2017-09-26T01:16:57Z",
            "GroupId": "AGPAI3GMRGLPSRIYNDSJ2",
            "Arn": "arn:aws:iam::XXXXXXXXXXXX:group/cm-xxxxxxx",
            "GroupName": "cm-xxxxxxx"
        },
        {
            "Path": "/",
            "CreateDate": "2018-09-28T10:15:07Z",
            "GroupId": "AGPAJE2IYSETQXTIQXWDW",
            "Arn": "arn:aws:iam::XXXXXXXXXXXX:group/Dome9-Restricted-Group",
            "GroupName": "Dome9-Restricted-Group"
        }
    ]
}

動作確認

それでは動作確認として、IAM Userを「昇格」させます。

以下の画面の通り、制限されたIAM Userの横に"ELEVATE"をクリックします。

成功すると画面上部にメッセージが表示されます。

昇格されたIAM Userはコンソールで確認することも可能です。

それでは、IAM UserがどのIAM Groupのメンバーになっているか確認してみましょう。 最初に作成したIAM Groupのメンバーになっていなければ成功です。

aws iam list-groups-for-user \
    --user-name cm-nakayama.nobuhiro
{
    "Groups": [
        {
            "Path": "/",
            "CreateDate": "2017-09-26T01:16:57Z",
            "GroupId": "AGPAI3GMRGLPSRIYNDSJ2",
            "Arn": "arn:aws:iam::XXXXXXXXXXXX:group/cm-awsteam",
            "GroupName": "cm-awsteam"
        }
    ]
}

成功です!

おまけ

昇格はスマホアプリから実行することも可能です。

まず、事前にActivation Codeを確認します。

アプリをインストールし、User NameとActivation Codeを入力してログインします。

IAM Safetyのメニューを開くと、そのDome9 Userが昇格させることができるIAM User / IAM Roleが表示されます。

再生ボタンをタップすると、昇格できます。昇格の取り消しも可能です。

また、昇格可能な時間は調整可能です。

まとめ

IAM Safetyによって一時的に特権の付与を行うことができるようになります。 しかも、複数のAWSアカウントを運用しているようなケースでも負担は比較的抑えることができそうです。

セキュリティ要件が厳しいような状況にマッチする機能なんじゃないかなって思いましたので、気になった方は試してみてはどうでしょうか?

現場からは以上です。