hashicorp / packer

Packer is a tool for creating identical machine images for multiple platforms from a single source configuration.
http://www.packer.io
Other
15.05k stars 3.32k forks source link

A more complete AWS IAM policy sample for the docs #1928

Closed vacri closed 7 years ago

vacri commented 9 years ago

One for the documentation staffers. This was a little lengthy to obtain, but it's a more complete IAM policy that should suit the documentation - just swap out the ALL_CAPS for the right terms. I thought it would be good to put in the docs, given there's some non-intuitive IAM stuff in there.

The policy is intended to limit the packer user to a single subnet in a VPC, and limit the destruction to things packer creates itself.

Notes

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "NonResourceLevelPermissions",
            "Action": [
                "ec2:Describe*",
                "ec2:CreateVolume",
                "ec2:CreateKeypair",
                "ec2:DeleteKeypair",
                "ec2:CreateSecurityGroup",
                "ec2:AuthorizeSecurityGroupIngress",
                "ec2:CreateImage",
                "ec2:CreateSnapshot",
                "ec2:DeleteSnapshot",
                "ec2:RegisterImage",
                "ec2:CreateTags",
                "ec2:ModifyImageAttribute"
            ],
            "Effect": "Allow",
            "Resource": "*"
        },
        {
            "Sid": "AllowInstanceActions",
            "Effect": "Allow",
            "Action": [
                "ec2:StopInstances",
                "ec2:TerminateInstances",
                "ec2:AttachVolume",
                "ec2:DetachVolume",
                "ec2:DeleteVolume"
            ],
            "Resource": [
                "arn:aws:ec2:us-east-1:ACCOUNT_ID:instance/*",
                "arn:aws:ec2:us-east-1:ACCOUNT_ID:volume/*",
                "arn:aws:ec2:us-east-1:ACCOUNT_ID:security-group/*"
            ],
            "Condition": {
                "StringEquals": {
                    "ec2:ResourceTag/Name": "Packer Builder"
                }
            }
        },
        {
            "Sid": "EC2RunInstancesSubnet",
            "Effect": "Allow",
            "Action": [
                "ec2:RunInstances"
            ],
            "Resource": [
                "arn:aws:ec2:us-east-1::image/*",
                "arn:aws:ec2:us-east-1:ACCOUNT_ID:key-pair/*",
                "arn:aws:ec2:us-east-1:ACCOUNT_ID:network-interface/*",
                "arn:aws:ec2:us-east-1:ACCOUNT_ID:security-group/*",
                "arn:aws:ec2:us-east-1:ACCOUNT_ID:volume/*",
                "arn:aws:ec2:us-east-1:ACCOUNT_ID:instance/*",
                "arn:aws:ec2:us-east-1:ACCOUNT_ID:subnet/SUBNET_ID",
                "arn:aws:ec2:us-east-1:ACCOUNT_ID:vpc/vpc-*"
            ]
        },
        {
            "Sid": "SGVPCDelete",
            "Effect": "Allow",
            "Action": [
                "ec2:DeleteSecurityGroup"
            ],
            "Resource": [
                "*"
            ],
            "Condition": {
                "StringEquals": {
                    "ec2:vpc": [
                        "arn:aws:ec2:us-east-1:ACCOUNT_ID:vpc/VPC_ID"
                    ]
                }
            }
        }
    ]
}
bruno commented 9 years ago

:+1: and for those that use a different region, also just replace us-east-1 with your region ... Thanks @vacri :smile:

gdhaworth commented 9 years ago

Just noticed this while searching around for docs on how to do something with Packer and IAM and noticed the policy above has a security loophole you might care about (and since I referenced these docs yesterday, people like me would too :smile:).

It allows the ec2:CreateTags action for everything and then restricts dangerous things like ec2:StopInstances and ec2:terminateInstances to instances with a specific tag. Something with malicious intent can just add the right tag and have access to those potentially-dangerous actions. Its frustrating that there's no good way to restrict ec2:CreateTags to specific resources to prevent it. Hope this helps!

vacri commented 9 years ago

Hrm... you may be able to add a Condition to limit stop/terminate to a specific subnet/VPC - similar to the Condition for the DeleteSecurityGroup section - so that it will only work on instances in that subnet? Unfortunately I'm flat-chat at the moment and can't try it out.

I agree that it's not watertight, but it is a lot more restrictive than the MVP policy in the docs. I was initially after something that just prevented me from fat-fingering a config and scribbling over the wrong EC2 resources... and it grew from there. :)

I didn't notice the 'tag hole', though - nice find

gdhaworth commented 9 years ago

You can, I'm doing that in other places. I also use a policy to force it to launch instances with a specific instance profile/IAM role, then restrict stopping and terminating to only instances with that profile. So, for example, if you have an IAM role for Jenkins slaves you force the Jenkins master to launch them with the slave role, and Jenkins is only allowed to terminate instances with that slave role. It's awkward but permanent for the lifetime of the VM so it can't be subverted.

I can't take all the credit for that 'tag hole', I saw it somewhere I can't remember on the Internet and it stuck with me because it would be such a great way to do what we're talking about, if not for the loophole. Oh well. Figuring out how to bend IAM policies to your will gets tedious quickly lol.

On Tue, Aug 4, 2015, 8:08 PM vacri notifications@github.com wrote:

Hrm... you may be able to add a Condition to limit stop/terminate to a specific subnet/VPC - similar to the Condition for the DeleteSecurityGroup section - so that it will only work on instances in that subnet? Unfortunately I'm flat-chat at the moment and can't try it out.

I agree that it's not watertight, but it is a lot more restrictive than the MVP policy in the docs. I was initially after something that just prevented me from fat-fingering a config and scribbling over the wrong EC2 resources... and it grew from there. :)

I didn't notice the 'tag hole', though - nice find

— Reply to this email directly or view it on GitHub https://github.com/mitchellh/packer/issues/1928#issuecomment-127809900.

davidvasandani commented 8 years ago

@gdhaworth mind sharing your policy?

tb3088 commented 8 years ago

Dont' mean to necro-thread but since this is still open... I haven't fully verified the following but I believe this closes the Tagging hole and more closely focuses perms. I'll post the full schema once I've tested it.

    {
        "Sid": "RoleLocked",
        "Action": [
            "ec2:StartInstances",
            "ec2:StopInstances",
            "ec2:RebootInstances",
            "ec2:TerminateInstances",
            "ec2:ModifyInstanceAttribute",
            "ec2:GetPasswordData",
            "ec2:AttachVolume",
            "ec2:DetachVolume",
            "ec2:CreateSnapshot",
            "ec2:DeleteSnaphot",
            "ec2:AuthorizeSecurityGroup*",
            "ec2:RevokeSecurityGroup*",
            "ec2:CreateTags"
        ],
        "Effect": "Allow",
        "Resource": "*",
        "Condition": {
            "ArnEquals": {
                "ec2:InstanceProfile": "arn:aws:iam::ACCOUNT:instance-profile/packer"
            }
        }
    },
    {
        "Sid": "VpcLocked",
        "Action": [
            "ec2:DescribeSecurityGroups",
            "ec2:DescribeSubnets"
        ],
        "Effect": "Allow",
        "Resource": "*",
        "Condition": {
            "ArnEquals": {
                "ec2:vpc": "arn:aws:iam::ACCOUNT:vpc/vpc-ID"
            }
        }
    },
    {
        "Sid": "RegionLocked",
        "Action": [
            "ec2:Describe*",
            "ec2:CreateVolume",
            "ec2:DeleteVolume",
            "ec2:CreateImage",
            "ec2:CreateKeyPair",
            "ec2:DeleteKeyPair",
            "iam:GetInstanceProfiles",
            "iam:ListInstanceProfiles"
        ],
        "Effect": "Allow",
        "Resource": "*",
        "Condition": {
            "StringEquals": {
                "ec2:Region": "us-east-1"
            }
        }
    },
    {
        "Sid": "General",
        "Action": [
            "sts:DecodeAuthorizationMessage"
        ],
        "Effect": "Allow",
        "Resource": "*"
    },
imduffy15 commented 8 years ago

This is what I came up with, its based of https://blogs.aws.amazon.com/security/post/Tx1ZU3LW4LLPQY2/How-to-Help-Lock-Down-a-User-s-Amazon-EC2-Capabilities-to-a-Single-VPC

{
  "Statement": [
    {
      "Action": [
        "ec2:Describe*",
        "ec2:CreateKeyPair",
        "ec2:DeleteKeyPair",
        "ec2:CreateImage",
        "ec2:DescribeKeyPairs",
        "ec2:CreateSecurityGroup",
        "iam:GetInstanceProfiles",
        "iam:ListInstanceProfiles",
        "ec2:CreateTags"
      ],
      "Effect": "Allow",
      "Resource": "*"
    },
    {
      "Action": [
        "iam:PassRole"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:iam::ACCOUNT_ID:role/eu-west-1-inflight_packer_run"
    },
    {
      "Action": [
        "ec2:StartInstances",
        "ec2:StopInstances",
        "ec2:RebootInstances",
        "ec2:TerminateInstances",
        "ec2:ModifyInstanceAttribute",
        "ec2:GetPasswordData",
        "ec2:AttachVolume",
        "ec2:DetachVolume",
        "ec2:CreateSnapshot",
        "ec2:DeleteSnaphot",
        "ec2:AuthorizeSecurityGroup*",
        "ec2:RevokeSecurityGroup*"
      ],
      "Condition": {
        "StringEquals": {
          "ec2:InstanceProfile": "arn:aws:iam::ACCOUNT_ID:instance-profile/eu-west-1-inflight_packer_run"
        }
      },
      "Effect": "Allow",
      "Resource": "arn:aws:ec2:eu-west-1:ACCOUNT_ID:instance/*"
    },
    {
      "Action": "ec2:RunInstances",
      "Condition": {
        "StringEquals": {
          "ec2:InstanceProfile": "arn:aws:iam::ACCOUNT_ID:instance-profile/eu-west-1-inflight_packer_run"
        }
      },
      "Effect": "Allow",
      "Resource": "arn:aws:ec2:eu-west-1:ACCOUNT_ID:instance/*"
    },
    {
      "Action": "ec2:RunInstances",
      "Effect": "Allow",
      "Resource": "arn:aws:ec2:eu-west-1:ACCOUNT_ID:subnet/*"
    },
    {
      "Action": "ec2:RunInstances",
      "Effect": "Allow",
      "Resource": [
        "arn:aws:ec2:eu-west-1:ACCOUNT_ID:volume/*",
        "arn:aws:ec2:eu-west-1::image/*",
        "arn:aws:ec2:eu-west-1::snapshot/*",
        "arn:aws:ec2:eu-west-1:ACCOUNT_ID:network-interface/*",
        "arn:aws:ec2:eu-west-1:ACCOUNT_ID:key-pair/*",
        "arn:aws:ec2:eu-west-1:ACCOUNT_ID:security-group/*"
      ]
    }
  ],
  "Version": "2012-10-17"
}
ogrodnek commented 8 years ago

@imduffy15 thanks for the example and pointer to the blog post! This was a big help.

I think a few of your conditions aren't valid (see http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ec2-api-permissions.html#ec2-api-unsupported-resource-permissions) --

both ec2:DeleteSnapshot, ec2:ModifyInstanceAttribute don't support conditions according to the docs.

Also, it seems like you are missing some of the permissions in the packer docs (https://www.packer.io/docs/builders/amazon.html) ? Like ec2:CreateVolume, ec2:RegisterImage, ec2:ModifyImageAttribute.

FWIW, here is my attempt -- https://gist.github.com/ogrodnek/00419e085d2d915b262e7f1fe42626d0

Agree it would be worth flushing out the official docs a bit more. Also hoping the EC2/IAM support in AWS improves...

imduffy15 commented 8 years ago

@ogrodnek any idea if its possible to restrict CreateKeyPair DeleteKeyPair CreateTags etc.

ogrodnek commented 8 years ago

@imduffy15 unfortunately it looks like it's not currently supported for those keys, see: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ec2-api-permissions.html#ec2-api-unsupported-resource-permissions

specifically: The following Amazon EC2 API actions currently do not support resource-level permissions; therefore, to use these actions in an IAM policy, you must grant users permission to use all resources for the action by using a * wildcard for the Resource element in your statement. You cannot use Amazon EC2 condition keys for these actions

It's really unfortunate. I'm hopeful this is something that will continue to improve. I think we'll have to watch the docs/announcements for if/when restrictions are supported there.

mwhooker commented 7 years ago

I'm glad there's a discussion here, but I think this is more of a power-user feature, and might be best to be documented in github. For now, I think we want to keep the docs as simple as possible.

tedivm commented 6 years ago

I really wish you guys would reopen this. Having a secure environment is not a "power user" feature.

rickard-von-essen commented 6 years ago

@tedivm The problem is that "secure" depends on the context and when IAM get more capabilities this changes. Also one can argue that the most secure way of building AMI's are by using a separate build account and not trying to restrict IAM in an account used for multiple purposes.

tedivm commented 6 years ago

I actually do recommend that, where feasible, people build in separate accounts. However, there are still cases where that isn't really feasible. I don't see any harm in giving people more complete instructions for locking down packer- it can be in an "advanced" section if you're worried about scaring off new users.

ghost commented 4 years ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.