We have a few users which basically have access to everything using the following policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
Is there a way to restrict access to selected VPCs?
I have tried creating the following policy and attach it to the user (via a group):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1504660000000",
"Effect": "Deny",
"Action": [
"ec2:*"
],
"Resource": [
"arn:aws:ec2:<REGION>:<ACCOUNT-ID>:vpc/<VPC-ID>"
]
}
]
}
I have replaced <REGION> <ACCOUNT-ID> and <VPC-ID>".
The policy simulator denies access (StartInstances, StopInstances, etc.) correctly. Nevertheless a user with this policy attached can still create EC2 instances within the vpc.
Why does my policy not deny access to the VPC? As far as I know "Deny" overwrites "Allow".
What is the correct way of achieving this? I have read through this and this but don't understand how it would restrict access.
It's a tricky one. You have to refer and include all actions including recources which supports the ec2:Vpc condition and deny the API actions. For other actions, you have to find conditions which are common in API actions and include those actions in separate statement blocks and deny those by other means e.g. using tags or something else.
Also, as the users have AdministratorAccess, you have to make sure that the user's cannot detach this Deny policy and escalate the privilege.
For other service which uses VPC e.g. RDS, it is not possible.
[1] http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-supported-iam-actions-resources.html
Here, you don`t want to give the permission to ec2 inside one VPC. So, you should consider vpc as a condition and resource as ec2.
Look at the code below -
{
"Effect": "Deny",
"Action": "ec2:*",
"Resource": "arn:aws:ec2:region:account:subnet/*",
"Condition": {
"StringEquals": {
"ec2:Vpc": "arn:aws:ec2:region:account:vpc/vpc-1a2b3c4d"
}
}
}
Explanation - Here we are denying the permissions to ec2 which are under a specific vpc. Here I have added subnet in ec2, it is optional. You may add if required.
Related
I am new to AWS and find it unnecessarily disorganized and complicated.
I would like to give a developer access to the account at the AdministratorAccess level but limit that access by not allowing him to create additional users or groups. Without limiting this, he can create a user that has access to billing. I want to make sure no one has access to billing or can create users that can access billing.
How do I do that?
You can create a customer managed IAM policy based on Administrator Access and add an explicit Deny statement similar to the following:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
},
{
"Effect": "Deny",
"Action": [
"iam:CreateGroup",
"iam:CreateUser",
...
],
"Resource": "*"
}
]
}
Note: The above restrictions will not be sufficient, they only demonstrate the general principle. To effectively restrict users you would also have to deny actions that attach managed policies or put inline policies to users or groups and actions that change already attached policies.
In general, it is advisable to follow the Principle of Least Privilege and give users only the permissions that they actually need. Only in rare cases you should start with AdministratorAccess and then incrementally restrict the permissions. It is considered best practice to start with no permissions and then incrementally add what is needed.
P.S.: You could also implement a mechanism that automatically attaches the following policy to all users to effectively deny all cost explorer and billing-related actions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": [
"aws-portal:*Billing",
"aws-portal:*Usage",
"aws-portal:*PaymentMethods",
"ce:UpdatePreferences",
"ce:CreateReport",
"ce:UpdateReport",
"ce:DeleteReport",
"ce:CreateNotificationSubscription",
"ce:UpdateNotificationSubscription",
"ce:DeleteNotificationSubscription",
"cur:DescribeReportDefinitions",
"cur:PutReportDefinition",
"cur:ModifyReportDefinition",
"cur:DeleteReportDefinition",
"purchase-orders:*PurchaseOrders"
],
"Resource": "*"
}
]
}
I am trying to enable access to EC2 for our vendor . So, what I did : I add tag "Vendor" for dedicated EC2 instances .
Then , I add policy below ..
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:ResourceTag/Vendor": "Takamol"
}
}
},
{
"Effect": "Deny",
"Action": [
"ec2:CreateTags",
"ec2:DeleteTags",
"ec2:TerminateInstances"
],
"Resource": "*"
}
]
}
Nevertheless , the user (who belongs to group that attaches) cannot see any EC2 instance even the policy condition restricts by tag "Vendor" (as you notice) .
How can allow user to manage only EC2 instances which has tag : Vendor = Takamol
What you're trying to achieve isn't possible. This is because of a concept called "Resource Level Permissions". Actions that support Resource level permissions allow you to use IAM to allow/deny a user the ability to perform an action on some subset of the resources in question, e.g. EC2 instances with a particular tag, S3 buckets, VPCs etc. Actions that don't support Resource Level Permissions can only be allowed/denied for ALL resources, and can only be allowed to a user in a statement where the resource is * and where there are no conditions.
Unfortunately for you, not all EC2 Actions support Resource Level Permissions. The reason that your user can't see any EC2 instances with the above IAM policy is that the ec2:Describe* API calls (used in the console to list all the instances in the account) do NOT support resource level permissions.
So even though ec2:Describe* falls under ec2:* which you allow for tagged instances in the first statement in the policy, ec2:Describe* with a condition evaluates to DENY all ec2:Describe*.
What people usually end up doing is allowing the vendor access to see all instances in the account and then only allow them the additional permissions they need for a particular set of instances. See the policy below, it will allow the user to see all instances but only start, stop and reboot instances with the required tag.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSeeEverything",
"Effect": "Allow",
"Action": [
"ec2:Describe*"
],
"Resource": [
"*"
]
},
{
"Sid": "ThingsIAllowThemToDoForTaggedEc2s",
"Effect": "Allow",
"Action": [
"ec2:RebootInstances",
"ec2:StartInstances",
"ec2:StopInstances"
],
"Condition": {
"StringEquals": {
"ec2:ResourceTag/Vendor": "Takamol"
}
},
"Resource": [
"*"
]
}
]
}
The list of what EC2 API calls support resource level permissions along with what conditions are supported is documented in Supported Resource-Level Permissions for Amazon EC2 API Actions. I also recommend reading the Demystifying EC2 Resource-Level Permissions
blog post.
I want to be able to apply tags only to instances running in EC2 on a particular VPC (vpc-11111111).
I tried to use the policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EC2TagNonresourceSpecificActions",
"Effect": "Allow",
"Action": [
"ec2:CreateTags",
"ec2:DeleteTags",
"ec2:DescribeTags"
],
"Condition": {
"StringEquals": {
"ec2:vpc": "arn:aws:ec2:<myRegion>:<myCustomerId>:vpc/vpc-11111111"
}
},
"Resource": "*"
}
]
}
but the user with this policy cannot modify the tags unless I remove the condition.
What have I done wrong?
Tags do not support conditions, according to Amazon docs and support.
This is a long standing feature request for several years!
Normally, if given some particular AWS user rights, the Tag rights is inside the policies.
Mistake in your new policies will overwrite those default access. You should try it out using AWS policy simulator.
Try add a principal and try it out.
"Principal": {
"AWS": "arn:aws:iam::<myCustomerId>:user/*"
}
I have created a VPC with the bare minimum of information: the VPC name, CIDR block, and default tenancy type. I then created a policy to administer the VPC and added it to a newly created user. My plan was to then log in as that user and complete the VPC setup, including subnets, EC2 instances, RDS, routing, etc.
The problem is that when I log in the user has no authority at all. They are not authorised for any EC2 or VPC services. I can not even see the VPC that I have created. Presumably there is something wrong with my policy. Here it is:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "arn:aws:ec2:ap-southeast-2:999999999999:vpc/vpc-99999999"
}
]
}
(Obviously that's not the real account number or VPC ID.)
Do I just need an additional permission to the IAM service? If so, what is it? Or is it more complex than that?
It's not clear what permissions you exactly wish to provide. However, the following will give you a large amount of access, localized to the specific VPC you wish to administer.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:Vpc": "arn:aws:ec2:region:account:vpc/vpc-1a2b3c4d"
}
}
}
]
}
(Update region, account, and vpc id in the above)
I am trying to apply the following policy in order to restrict my_bucket's access to a particular VPC.
When I try to apply this as a bucket policy, I get an Policy has an invalid condition key - ec2:Vpc.
How do I correct this?
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "*",
"Resource": "arn:aws:s3:::my_bucket/*",
"Condition":{
"StringNotEquals": {
"ec2:Vpc": "arn:aws:ec2:region:account:vpc/vpc-ccccccc"
}
}
}
]
}
I just got this to work. I had to do two things. 1) Create the bucket policy on the S3 bucket, 2) create a "VPC Endpoint"
My S3 bucket policy looks like this (of course put in your bucket name and VPC identifier):
{
"Version": "2012-10-17",
"Id": "Policy1234567890123",
"Statement": [
{
"Sid": "Stmt1234567890123",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my_bucket/*",
"Condition": {
"StringEquals": {
"aws:sourceVpc": "vpc-12345678"
}
}
}
]
}
The S3 bucket also has some permissions outside the bucket policy to allow access from the AWS Console. Doing the above did not give access. To get access, I also had to go to AWS Console -> VPC -> Endpoints, and then create an endpoint. I attached the newly created endpoint to the only routing policy the account has at the moment (that has all subnets attached to it) and I used the default policy of
{
"Statement": [
{
"Action": "*",
"Effect": "Allow",
"Resource": "*",
"Principal": "*"
}
]
}
Once I created the endpoint, I was able to read from the S3 bucket from any EC2 instance in my VPC simply using wget with the right URL. I am still able to access the bucket from the AWS Console. But if I try to access the URL from outside the VPC, I get 403 forbidden. Thus, access to the S3 bucket is restricted to a single VPC, just like what you are looking for.
This is apparently a new feature. See this AWS blog entry for more information.
Two things that bit me and which might be helpful to add to Eddie's nice answer are:
First, you won't be able to view your bucket (or even modify its policy once you set the policy above) in the S3 AWS console unless you also give your AWS users permissions to manipulate the bucket. To do that, find your AWS account number (displayed in upper-right here), and add this statement to the bucket policy statements list:
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::YOUR_AWS_ACCOUNT_NUMBER:root"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my_bucket",
"arn:aws:s3:::my_bucket/*"
]
},
Second, if you have more than one VPC, say vpc-XXXXXX and vpc-YYYYYY to give access to, the statement in Eddie's answer needs to be tweaked to something like the following (note the "Allow" "StringEquals" and list of sourceVpc values:
...
"Effect": "Allow",
...
"Condition": {
"StringEquals": {
"aws:sourceVpc": [
"vpc-XXXXXXXX",
"vpc-YYYYYYYY"
]
}
No, you can't do that.
Here's another person asking the same: https://forums.aws.amazon.com/thread.jspa?threadID=102387
Some have gotten overly creative with the problem trying to solve it with networking: https://pete.wtf/2012/05/01/how-to-setup-aws-s3-access-from-specific-ips/
I prefer a more simple route, S3 allows you to sign urls to solve this very problem, but inside of your VPC you may wish to not have to think about signing - or you just couldn't sign, for example you might be using wget, etc. So I wrote this little micro-service for that very reason: https://github.com/rmmeans/S3-Private-Downloader
Hope that helps!
UPDATED:
AWS now has a feature for VPC endpoints: https://aws.amazon.com/blogs/aws/new-vpc-endpoint-for-amazon-s3/, you should use that and not what I previously suggested.