AWS IAM PowerUser Scoped to Specific Region - amazon-web-services

I'm trying to create an AWS IAM Policy that gives access to everything that a Power User has (arn:aws:iam::aws:policy/PowerUserAccess) but only in a specific region.
I started with the existing Power User policy and found this article: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_ec2_region.html
So I added the "condition" to the Power User Policy and the result is:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Resource": "*",
"NotAction": [
"iam:*",
"organizations:*",
"account:*"
],
"Condition": {
"StringEquals": {
"ec2:Region": "us-east-2"
}
}
},
{
"Effect": "Allow",
"Action": [
"iam:CreateServiceLinkedRole",
"iam:DeleteServiceLinkedRole",
"iam:ListRoles",
"organizations:DescribeOrganization",
"account:ListRegions"
],
"Resource": "*"
}
]
}
This does not seem to be working as I can create EC2 instances only in the specified region... but other services are not available:

When you use the ec2:Region in the Condition key, that's EC2 specific
You'll want to try the aws:RequestedRegion for the condition key.
Beware though,
Some global services, such as IAM, have a single endpoint. Because this endpoint is physically located in the US East (N. Virginia) Region, IAM calls are always made to the us-east-1 Region
Give it a try with
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Resource": "*",
"NotAction": [
"iam:*",
"organizations:*",
"account:*"
],
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "us-east-2"
}
}
},
{
"Effect": "Allow",
"Action": [
"iam:CreateServiceLinkedRole",
"iam:DeleteServiceLinkedRole",
"iam:ListRoles",
"organizations:DescribeOrganization",
"account:ListRegions"
],
"Resource": "*"
}
]
}

Related

AWS S3 Bucket Policy: How to grant access to EC2 instance?

I am really struggling with this and the AWS Official Docs simply does not help!
I have an S3 bucket set up and it is allowing public access from a few specified ip addresses. This is the custom policy that is working:
{
"Version": "2012-10-17",
"Id": "Policy1111111111",
"Statement": [
{
"Sid": "Stmt111111111",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::myapp-local-test/*",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": [
"12.122.123.111",
"121.217.73.153"
]
}
}
},
{
"Sid": "Stmt1111111111",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::myapp-local-test/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"12.122.123.111",
"121.217.73.153"
]
}
}
},
]
}
Now, instead of only allowing the above 2 ip addresses to access resources in the bucket, I also want my EC2 instance to access it.
I followed this doc: https://aws.amazon.com/premiumsupport/knowledge-center/ec2-instance-access-s3-bucket/
I followed the exact steps.
I have created a new IAM role, (arn: "arn:aws:iam::1223123156:role/EC2-to-S3")
I have also attached the role to my EC2 instance.
But in step 6:
6. In your bucket policy, edit or remove any Effect: Deny
statements that are denying the IAM instance profile access to
your bucket. For instructions on editing policies,
see Editing IAM policies.
How exactly do I do it? It directs me to another doc about Editing IAM policies, BUT IT DOES NOT HELP !!!
How do I remove any "Effect: Deny" statements that are denying the IAM instance profile access to my bucket?
What keyword should I use?
Here is what I tried:
{
"Version": "2012-10-17",
"Id": "Policy1111111111",
"Statement": [
{
"Sid": "Stmt111111111",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::myapp-local-test/*",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": [
"12.122.123.111",
"121.217.73.153"
]
},
"StringNotEquals": {
"aws:SourceArn": "arn:aws:iam::1223123156:role/EC2-to-S3"
}
},
{
"Sid": "Stmt1111112222",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::myapp-local-test/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"12.122.123.111",
"121.217.73.153"
]
}
}
},
{
"Sid": "Stmt1639460338435",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::myapp-local-test/*",
"Condition": {
"StringEquals": {
"aws:SourceArn": "arn:aws:iam::1223123156:role/EC2-to-S3"
}
}
}
]
}
which does not work. I still had an "Access Denied" error.
Can the docs be a little bit more specific?
Why is it so hard to get such a basic task done with aws docs??
This finally worked:
{
"Version": "2012-10-17",
"Id": "Policy1111111",
"Statement": [
{
"Sid": "Stmt11111",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::myapp-local-test/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"12.122.123.111",
"121.217.73.153"
]
}
}
},
{
"Sid": "Stmt1222222222",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1234556:role/EC2-to-S3"
},
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::myapp-local-test/*"
}
]
}
So the trick is to drop the deny statement completely since by default everything is denied access.
And my edits earlier:
"Statement": [
{
"Sid": "Stmt111111111",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::myapp-local-test/*",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": [
"12.122.123.111",
"121.217.73.153"
]
},
"StringNotEquals": {
"aws:SourceArn": "arn:aws:iam::1223123156:role/EC2-to-S3"
}
},
the StringNotEquals part does not drop the default deny for the iam role.
If possible, you should avoid using Deny statements, since they override any Allow statements.
Your first bucket policy is saying:
Deny access to the bucket if requests are not coming from the given IP addresses
Allow access to the bucket if requests are coming from the given IP addresses
Unfortunately, the Deny will prohibit access from the EC2 instance, since it is not one of the listed IP addresses.
Instead of using Deny, just grant Allow access when needed. Access to S3 is denied by default, so users can only gain access if there is an Allow policy that grants them access.
To grant access to instance create iam instance profile and attach it your EC2 instance.
https://aws.amazon.com/premiumsupport/knowledge-center/ec2-instance-access-s3-bucket/

IAM policy with ec2 full access not allowing to create EC2 instances

An IAM user created with policy EC2fullaccess is not allowed to create ec2 instances in any other region except N.virginia . What could be the reason ?
Policy attached to the user :
"Version": "2012-10-17",
"Statement": [
{
"Action": "ec2:*",
"Effect": "Allow",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "elasticloadbalancing:*",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "cloudwatch:*",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "autoscaling:*",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "iam:CreateServiceLinkedRole",
"Resource": "*",
"Condition": {
"StringEquals": {
"iam:AWSServiceName": [
"autoscaling.amazonaws.com",
"ec2scheduled.amazonaws.com",
"elasticloadbalancing.amazonaws.com",
"spot.amazonaws.com",
"spotfleet.amazonaws.com",
"transitgateway.amazonaws.com"
]
}
}
}
]
Do you know what privileges your superuser/root account has? While I don't know of any accounts being limited to us-east-1 by default, I can see someone setting that up for security reasons - in fact, if it's possible I might do so myself.
The other possibility, while I don't see it in that JSON snippet, is that your entire account is limited to us-east-1, and that that rule trumps the EC2 permission outside of N. Virginia.

How to limit access to an S3 bucket to a specific VPC while allowing console access

I am setting up a selection of S3 buckets and wish to restrict access to them to a VPC while still allowing access to the buckets from the AWS console.
As proposed here I have created an S3 endpoint and also added it to the main routing table. The policy on the endpoint allows full access to all resources.
I have created an S3 policy (see below) and added it to the bucket. As soon as I save the policy, access to the bucket from the console is no longer possible.
I have also tried to specifically add a user to the condition "StringNotEquals" in the form of "aws:username": "user1", to no avail.
{
"Version": "2012-10-17",
"Id": "Policy-S3-Bucket-myBucket",
"Statement": [
{
"Sid": "Access-via-VPC-only",
"Principal": "*",
"Action": "s3:*",
"Effect": "Deny",
"Resource": [
"arn:aws:s3:::myBucket",
"arn:aws:s3:::myBucket/*"
],
"Condition": {
"StringNotEquals": {
"aws:sourceVpc": "vpc-01c9d66c12345"
}
}
},
{
"Sid": "Allow-console-access",
"Action": [
"s3:*"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::myBucket",
"arn:aws:s3:::myBucket/*"
],
"Principal": {
"AWS": [
"arn:aws:iam::<account-id>:user/user1", "arn:aws:iam::<account-id>:user/user2"
]
}
}
]
}
The expected result would be that the S3 bucket is only accessible by the aforementioned VPC and via the AWS console.
The actual result is:
The bucket overview shows an "Error: Access Denied" and the permissions page(public access settings) shows: "You don't have access to view this configuration. Contact your account administrator to request access."
I have to login using the root user and delete the policy to regain access to the bucket.
I found a solution which seems to work. I have tested it in the policy simulator and it also appears to work correctly in the live environment. The following policy does the trick:
{
"Version": "2012-10-17",
"Id": "Policy-S3-Bucket-myBucket",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListAllMyBuckets"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:username": ["user1", "user2"]
}
}
},
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::myBucket"],
"Condition": {
"StringEquals": {
"aws:sourceVpc": "vpc-01c9d66c12345"
}
}
},
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::myBucket"],
"Condition": {
"StringEquals": {
"aws:username": ["user1", "user2"]
}
}
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": ["arn:aws:s3:::myBucket/*"],
"Condition": {
"StringEquals": {
"aws:sourceVpc": "vpc-01c9d66c12345"
}
}
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": ["arn:aws:s3:::myBucket/*"],
"Condition": {
"StringEquals": {
"aws:username": ["user1", "user2"]
}
}
}
]
}
The policy requires for either the sourceVpc string OR the username to be as listed in the condition.
Admittedly, the policy is verbose and there is a substantial amount of replication. If anyone has an idea to solve this more efficiently, I'm all ears.
This policy was tested and gives exactly what you need:
Statement": {
"Sid": "Allow-anonymous-access-from-specific-VPC",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket_name/*",
"Condition": {
"StringEquals": {
"aws:SourceVpc": "some-vpc-id"
}
}
}
This will allow anonymous access from requests coming from "some-vpc-id", while yet allowing access from AWS console.
Your VPC has to have S3 endpoint configured for it to work.
The trick seems to be on denying everything except if it comes from the user or from the VPC but it has to be in the same condition. The way policies work is that Deny rules precede over every other rule, so if you deny, you can't then allow on a subsequent rule; it's already denied and that's it.
By the way, the aws:userid of the root user is the Account Id. Probably a bad practice to use this user but oh well :P
So my bucket now only accepts traffic from the VPC and from the user I log into via the AWS web console (so I don't get access denied errors in the web console)
{
"Version": "2012-10-17",
"Id": "Policy154336817545456388",
"Statement": [
{
"Sid": "Block-if-not-from-VPC-or-Me",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::bucket-name",
"arn:aws:s3:::bucket-name/*"
],
"Condition": {
"StringNotEquals": {
"aws:SourceVpce": "vpce-4598ujfjrhc",
"aws:userid": "576767373466"
}
}
}
]
}

Can not add AWS Resource level permissions to an Particular EC2 Instance

Referring to this Doc
I have created IAM policy which allows accessing only one EC2 Instance.And I have created an IAM user with the policy with that policy. But when I logged in with that user into my AWS account I got the Error "An error occurred fetching instance data: You are not authorized to perform this operation."
Policy document:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ec2:*"
],
"Condition": {
"StringEquals": {
"ec2:ResourceTag/test": "test"
}
},
"Resource": [
"arn:aws:ec2:us-east-1:AccountNumber:instance/*
],
"Effect": "Allow"
}
]
}
You must add EC2 describe to describe all EC2 resources, then base on other statement to filter resource by tag.
But with this policy, other IAM account still viewable other EC2 instances without any permission.
Here is what you need.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1507182214000",
"Effect": "Allow",
"Action": [
"ec2:*"
],
"Condition": {
"StringEquals": {
"ec2:ResourceTag/TAG_NAME": "TAG_VALUE"
}
},
"Resource": [
"arn:aws:ec2:AWS_REGION:AWS_ACCOUNT:instance/*"
]
},
{
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"ec2:DescribeTags"
],
"Resource": "*"
},
{
"Effect": "Deny",
"Action": [
"ec2:CreateTags",
"ec2:DeleteTags"
],
"Resource": "*"
}
]
}

Add multiple domain access policy to AWS Elasticsearch Service (Static IP and Lambda ARN)

After setting up AWS Elasticsearch, I installed Logstash and Kibana proxy on a static IP server, and added this domain access policy on ES and it's working fine:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "es:*",
"Resource": "arn:aws:es:ap-southeast-1:323137313233:domain/sg-es-logs/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"192.192.192.192"
]
}
}
}
]
}
Now I need to allow Lambda function to execute es:ESHttpDelete action on AWS ES, so I created the function with the existing role service-role/Elasticsearch then copied the relevent ARN from IAM Managment console to add it to AWS ES access policy, to come up with this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam:: 323137313233:role/service-role/Elasticsearch"
]
},
"Action": [
"es:*"
],
"Resource": "arn:aws:es:ap-southeast-1:323137313233:domain/sg-es-logs/*"
}
]
}
The problem is on ES I should either choose domain access policy for Static IP or ARN but not both. When I tried to merge them manually not by using the console it didn't work. I checked AWS documentation but they didn't mention if is that possible or not.
You can add multiple policy statements inside the Statement array in the JSON format of policy. So, your final policy would be something like:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "es:*",
"Resource": "arn:aws:es:ap-southeast-1:323137313233:domain/sg-es-logs/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"192.192.192.192"
]
}
}
},
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam:: 323137313233:role/service-role/Elasticsearch"
]
},
"Action": [
"es:*"
],
"Resource": "arn:aws:es:ap-southeast-1:323137313233:domain/sg-es-logs/*"
}
]
}