I've setup the following Resource Policy in my AWS API Gateway to whitelist an IP range:
The policy is working properly, however now I have to apply the same policy to some Gateways (not all of them) within the same account and potentially in the future I will need to include more IPs in that list; So I will need to modify the resource policy in the Gateways one by one..
In order to fix that, I want to setup a policy in IAM and apply that policy to some gateways. I've created the following policy in IAM:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "execute-api:Invoke",
"Resource": "*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "35.192.0.0/12"
}
}
}
]
}
However I cannot find the way to attach it to the Gateways.
I've tried to setup a role, but the API Gateway service does not allow me to attach that policy.
Is there anyway to create a IP whitelist policy and attach them to some gateways at once? Basically I'm looking for a way to modify the IP whitelist in one place and apply it dynamically to some of my gateways.
Thanks,
The policy for API Gateway is a resource policy, the IAM policy can only be attached to users, groups and roles.
You will need to apply this to each API Gateways resource policy, if you want to reuse try looking at IaC.
Related
We have AWS accounts created and managed using control tower service.
The requirement is to restrict internet access from lambda even it is not attached to any VPC.
By default lambda functions can connect to internet if it is not connected to any VPC.
How do we enforce restricting internet access to users using lambda functions ?
Lambda is always in a VPC,just when you don't specify a VPC it's assigned to default one which has internet access configured.
Create a new VPC, by default it won't have internet access. And assign your functions to it.
We have addressed this requirement by creating a service control policy with below statements and attached to the OU.
It enforces the users to select a VPC, subnet and security group while creating/updating the lambda function. With this you can make sure the lambda functions are always under your VPC.
Ref: https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc.html#vpc-conditions
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EnforceVPCFunction",
"Action": [
"lambda:CreateFunction",
"lambda:UpdateFunctionConfiguration"
],
"Effect": "Deny",
"Resource": "*",
"Condition": {
"Null": {
"lambda:VpcIds": "true"
}
}
}
]
}
Refer the above AWS documentation to find the policy statements to enable restriction at different levels like subnet, Security group and VPC.
I'm trying to allow AWS Lambda residing in a private VPC to invoke another Lambda not in any VPC. I'm purposely avoiding use of NAT gateways in favor of Interface VPC Endpoints as they're a bit cheaper to use. However, I'm running into trouble configuring a custom policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "[~some stuff~]",
"Action": [
"lambda:InvokeFunction"
],
"Effect": "Allow",
"Resource": "arn:aws:lambda:[~region~]:[~taken out~]:function:Test-Invoked"
}
]
}
This was generated by the policy generator provided by AWS, which I copied and pasted. When I tried to create the endpoint, this got overwritten by the default All access. After I tried to change this once the endpoint was created, AWS takes me to an error page saying "Error: An unknown error occurred".
Would appreciate some help on this.
Your interface endpoint policy is invalid. Its missing Principal element for once.
But my advise would be to use default policy, and control access to the endpoint using security groups, and to control permissions to invoke the second lambda by means of IAM roles and/or lambda's resource-based permissions.
I was curious to know what the functional difference is for creating an S3 bucket with a bucket policy like:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Access-to-specific-VPC-only",
"Principal": "*",
"Action": "s3:*",
"Effect": "Deny",
"Resource": ["arn:aws:s3:::example-bucket",
"arn:aws:s3:::example-bucket/*"],
"Condition": {
"StringNotEquals": {
"aws:sourceVpc": "vpc-111bbb22"
}
}
}
]
}
versus creating a VPC endpoint like:
{
"Name": "example-vpc-ap",
"Bucket": "example-bucket",
"NetworkOrigin": "VPC",
"VpcConfiguration": {
"VpcId": "vpc-111bbb22"
},
"CreationDate": "2019-11-27T00:00:00Z"
}
Are they functionally equivalent? Is one being depricated or a best practice? It is not clear what the answer is after referencing:
https://docs.aws.amazon.com/AmazonS3/latest/dev/creating-access-points.html#access-points-vpc
VPC access policy for S3 buckets
S3 VPC end point Bucket policy
Thanks
I think that aws:sourceVpc can only be used in conjunction with a VPC Endpoint.
From Example Bucket Policies for VPC Endpoints for Amazon S3 - Amazon Simple Storage Service:
You can create a bucket policy that restricts access to a specific VPC by using the aws:SourceVpc condition. This is useful if you have multiple VPC endpoints configured in the same VPC, and you want to manage access to your Amazon S3 buckets for all of your endpoints.
The VPC Endpoint definition shown in your Question is simply saying that the Endpoint is connected to a specific VPC. It does not restrict bucket access to only that Endpoint. Users could still access the bucket via the Internet or another endpoint.
I will, however, admit that all these endpoints and configurations are quite confusing!
I am trying to use an existing API gateway which is present in accountA. I am having some EC2 instances which are having some scripts to invoke the API gateway present. These instances may/may not reside in the same AWS account as the one where my API gateway is present (Let's call the other account as accountB).
For the authentication part currently, there's only AWS_IAM authentication implemented at the API gateway level. The EC2 instances (in both the accounts) are having IAM roles attached which are having IAM permissions to invoke the API.
The permission for the same looks as:
{
"Sid": "InvokeAPI",
"Effect": "Allow",
"Action": "execute-api:Invoke",
"Resource": "*"
}
When I try to invoke the API from the instances which are in accountA, it is working as expected. However, when I try to invoke the API from my instances in accountB, the gateway returns a 403 error with the following message:
User: arn:aws:sts::accountB:assumed-role/invoke_api_iam_role/i-xxxxxxxxx is not authorized to access this resource
I tried to look at API gateway resource policies and tried to whitelist the accountB's EC2 IAM role in accountA API Gateway's resource policy and still, I'm getting the same error.
Current resource policy implemented at the API gateway kinda looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::accountB:role/invoke_api_iam_role"
},
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-east-1:accountA:myAPIID/*"
}
]
}
For signing the requests to the API gateway through the awsv4 signature, I use aws-requests-auth
Please help to resolve this issue.
So as it turns out, everything above is correct and you need to deploy the API to a particular stage for applying the resource policy against it.
I have few buckets in S3 where I want to limit access.
In the process of implementing this I am now confused and appreciate your help in making me understand this.
This is my scenario --
Created a VPC, Public Subnet, ec2.
Created a bucket using an admin user --aws1234-la
Created a bucket policy and attached to the bucket saying allow access only if coming from my vpc.
"Statement": [
{
"Sid": "Access-to-specific-VPC-only",
"Principal": "*",
"Action": "s3:*",
"Effect": "Deny",
"Resource": ["arn:aws:s3:::aws1234-la",
"arn:aws:s3:::aws1234-la/*"],
"Condition": {
"StringNotEquals": {
"aws:sourceVpc": "vpc-111bbb22"
}
}
} ] }
Next, from CLI , aws s3 ls
It is displaying the buckets.
Where I am making a mistake ?
Ideally step 4 should return an error as I am not going thru my VPC ?
Any help will be hightly appreciated.
Thanks
From Specifying Conditions in a Policy - Amazon Simple Storage Service:
The new condition keys aws:sourceVpce and aws:sourceVpc are used in bucket policies for VPC endpoints.
Therefore, you need to be accessing the S3 bucket via a VPC Endpoint to be able to restrict access to a VPC. This is because, without the VPC Endpoint, the request being received by Amazon S3 simply appears to be coming "from the Internet", so it is not able to identify the source VPC. In difference, a request coming via a VPC Endpoint includes an identifier of the source VPC.
Making it work
Assumption: You already have an IAM Policy on your user(s) that allow access to the bucket. You are wanting to know how to further restrict the bucket so that it is only accessible from a specific VPC. If this is not the case, then you should be using an Allow policy to grant access to the bucket, since access is denied by default.
To reproduce your situation, I did the following:
Created a new VPC with a public subnet
Added a VPC Endpoint to the VPC
Launched an Amazon EC2 instance in the public subnet, assigning an IAM Role that already has permission to access all of my Amazon S3 buckets
Created an Amazon S3 bucket (my-vpc-only-bucket)
Added a Bucket Policy to the bucket (from Example Bucket Policies for VPC Endpoints for Amazon S3):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Access-to-specific-VPC-only",
"Principal": "*",
"Action": "s3:*",
"Effect": "Deny",
"Resource": ["arn:aws:s3:::my-vpc-only-bucket",
"arn:aws:s3:::my-vpc-only-bucket/*"],
"Condition": {
"StringNotEquals": {
"aws:sourceVpc": "vpc-111bbb22"
}
}
}
]
}
Please note that this policy assumes that the user(s) already have access to the bucket via an IAM Policy that grants Allow access. This policy is adding a Deny that will override the access they already have to the bucket.
Logged in to the Amazon EC2 instance in the new VPC and then:
Run aws s3 ls s3://my-vpc-only-bucket
It worked!
From my own computer on the Internet:
Run aws s3 ls s3://my-vpc-only-bucket
Received a AccessDenied error (which is what we want!)
By the way, the Deny policy will also prohibit your use of the Amazon S3 management console to manage the bucket because requests are not coming from the VPC. This is a side-effect of using Deny and s3:* on the bucket. You can always remove the bucket policy by using your root credentials (login via email address), then go to the Bucket Policy in the S3 console and click Delete. (You'll see some errors on the screen getting to the Bucket Policy, but it will work.)
Alternate method via Allow
If, on the other hand, the user(s) do not already have access to all Amazon S3 buckets, then by default they will not have access to the new bucket. Thus, you will need to grant Allow access to the bucket, but only from the VPC via the VPC Endpoint.
Setup is the same as above, but the Bucket Policy would be:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Access-to-specific-VPC-only",
"Principal": "*",
"Action": "s3:*",
"Effect": "Allow", <-- This changed
"Resource": ["arn:aws:s3:::my-vpc-only-bucket",
"arn:aws:s3:::my-vpc-only-bucket/*"],
"Condition": {
"StringEquals": { <--- This changed
"aws:sourceVpc": "vpc-111bbb22"
}
}
}
]
}
I then tested it with an IAM Role assigned to the EC2 instance that does not have any permissions to access Amazon S3
Ran aws s3 ls s3://my-vpc-only-bucket
It worked!
Ran from my own computer, using an IAM User that does not have any permissions to access Amazon S3
Received a AccessDenied error (which is what we want!)
Bottom line: You need to add a VPC Endpoint to the VPC.
Since you specified the resource at the bucket level, it will denied all the operations inside the bucket. However, the listing of the bucket is acting on the resource arn:aws:s3:::*, and it is not denied, thus the bucket will be displayed even if you are not inside of the VPC.
AFAIK, there is no way to partially hide only for the bucket without blocking all the buckets.