Cross account S3 static website access over VPN only - amazon-web-services

I'm trying to allow access to s3 bucket static website over VPN from network aws account , bucket in prod account.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": "account-prod",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket/*",
"Condition": {
"StringEquals": {
"aws:SourceVpc": "vpc-1"
}
}
}
{
"Sid": "",
"Effect": "Allow",
"Principal": "account-network",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket/*",
"Condition": {
"StringEquals": {
"aws:SourceVpc": "vpc-2" <<<>>> tried SourceVpce as well
}
}
}
]
}
I used VPC endpoint interface in the account where VPN is setup , I tried using Condition SourceVpc and SourceVpce but non worked.
I'm using transit gateway and aws client vpn and allowed s3 endpoint IPs on the vpn endpoint + SGs + auth rules. (tgw is used and s3 prefix list, route entry from s3 prefix list via tgw)
bucket uses object owner + private ACL + bucket policy and I tried adding grantee with the canonical account id.
Any ideas what am I doing wrong here ?
This currently works in the prod account as we have another VPN solution that runs there, we are trying to migrate everything to network account and move to aws client vpn.

Any ideas what am I doing wrong here ?
Yes. s3 bucket static website can only be accesses over the Internet. You can't access them using private IP addresses from VPC or VPN. If you use VPN, you have to setup some proxy which will access the website using the internet, and then pass it back to your host.

Make sure that your VPC Subnet route table has a route to the S3 endpoint, and the policy for the endpoint is giving access.
https://tomgregory.com/when-to-use-an-aws-s3-vpc-endpoint/
next, setup your bucket policy as below, try to give access from the source of your VPC Endpoint, and not the VPC itself. (note the vpce in the policy doc).
https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies-vpc-endpoint.html

Related

Can I make a public S3 Bucket accessible to whitelisted IPs or DNS names?

We are facing an issue with S3 private files which is taking excess time to load on a Drupal website.
Can we make a S3 bucket public but restrict the public files to whitelisted IP addresses or DNS names.
A link to the documentation would be a great help
You can restrict an Amazon S3 bucket so that it is accessible only to a range of IP addresses. This can be done by adding a Bucket Policy.
See: Bucket policy examples - Amazon Simple Storage Service
For example:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::YOUR-BCKET-NAME/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "54.240.143.0/24"
}
}
}
]
}
This permits access to an object (GetObject), but only if the request is coming from the CIDR range given in aws:SourceIp. This can a list of CIDR ranges too.
It is not possible to "restrict by DNS names", but a bucket can be restricted by referer (which is the domain of the website that the user was using when they clicked a link in their browser). However, this is not a secure method and can be easily faked.

What is the difference between S3 bucket policies and S3 VPC endpoints?

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!

Is there a way to make a private connection between a Heroku Private Space and AWS S3?

Is there a way to access S3 privately (not over the internet) from a Heroku Private Space?
Using Private Space Peering and a HTTP proxy is not an option.
Heroku Private Spaces are connected to AWS S3 via AWS PrivateLink. As such, the connection to AWS S3 is private (not over the internet).
To whitelist a Heroku private space in an AWS S3 bucket policy, whitelist the Private Space's AWS VPC id. The VPC id can be found with the command heroku spaces:peering:info --space <your space's name>. Here is an example bucket policy:
{
"Version": "2012-10-17",
"Id": "example-policy",
"Statement": [
{
"Sid": "AllowHerokuPrivateSpaceVpcAccess",
"Effect": "Allow",
"Principal": "*",
"Action": "*",
"Resource": "arn:aws:s3:::example-bucket/*",
"Condition": {
"StringEquals": {
"aws:sourceVpc": "<your space's VPC id>"
}
}
}
]
}
Requests to the bucket will be logged as coming from private IPs (e.g. 10.0.0.0/16).
Source: Heroku Support. This behavior is not documented in the Heroku documentation.

Whitelist private API GW api to be accessible from a VPC from another account

I have a Private API in Amazon API Gateway that I want to be consumed from another account, by a lambda with VPC support. I modified the API ResourcePolicy to allow private API traffic based on source VPC as specified here, in the last example. This is how my ResourcePolicy looks like:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:my-region:my-account:api-id/*",
"Condition": {
"StringEquals": {
"aws:sourceVpce": "my-vpce"
}
}
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": ""arn:aws:execute-api:my-region:my-account:api-id/*",
"Condition": {
"StringEquals": {
"aws:SourceVpc": "my-vpc-from-another-account"
}
}
}
]
}
Now, when I try to consume the API using https://my-api-id.execute-api.us-west-2.amazonaws.com/my-stage/ endpoint, I get getaddrinfo ENOTFOUND error. Is this the appropriate way to expose private API to be accessible from a VPC from another account?
Asked the guys from AWS, and the answer was that you can specify the source VPC, but only if it's in the same account.
aws:SourceVpc and aws:VpcSourceIp correspond to the VPC in which the VPC Endpoint resides, not, as "source" would suggest, the VPC from which the request originates.
At least, I can confirm that's true when the traffic is routed over Transit Gateway, I haven't tested this with VPC Peering.
When your VPC Endpoint resides in a different VPC than the VPC the request is coming from, you cannot use aws:SourceVpc or aws:VpcSourceIp to restrict access based on the request origin.
If you have a requirement to restrict access to only allow requests that originate from a particular VPC, there's really only one solid option, and that's to create a VPC Endpoint in the request origin VPC, and use aws:SourceVpc in the resource policy.
I have confirmed this with AWS Support, and have passed on feedback that the documentation is in need of some improvement on this point.

How do I restrict access to a static s3 website to a VPN

I'm trying to secure access to an internal static website.
Everyone in the company is using a VPN to access our Amazon VPC so I would like to limit access to that site if you're using the VPN.
So I found out this documentation on AWS to use VPC endpoint which seems to be what I'm looking for.
So I created a VPC endoint with the folowing policy.
{
"Statement": [
{
"Action": "*",
"Effect": "Allow",
"Resource": "*",
"Principal": "*"
}
]
}
On my S3 bucket, I verified that I could access index.html both from the regular Web and from the VPN.
Then I added the following bucket Policy to restrict to only the VPC Endpoint.
{
"Id": "Policy1435893687892",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1435893641285",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::mybucket/*",
"Principal": {
"AWS": [
"arn:aws:iam::123456789:user/op"
]
}
},
{
"Sid": "Access-to-specific-VPCE-only",
"Action": "s3:*",
"Effect": "Deny",
"Resource": ["arn:aws:s3:::mybucket/*"],
"Condition": {
"StringNotEquals": {
"aws:sourceVpce": "vpce-1234567"
}
},
"Principal": "*"
}
]
}
Now Regular Web gets a 403 but I also get a 403 when I'm behind the company VPN.
Am I missing something?
#Michael - sqlbot is right.
It seems what you are doing is restrict access to the S3 bucket where you store that static web content to requests coming from a particular AWS VPC, using a VPC endpoint.
VPC endpoints establish associations between AWS services, to allow requests coming from INSIDE the VPC.
You can't get what you want with VPC and S3 ACL configuration, but you can get it with ACL and some VPN configuration.
Let's assume connecting to your company's VPN doesn't mean that all the traffic, including Internet traffic between the VPN clients and AWS S3 will be routed through that VPN connection, because that's how sane VPN configuration usually works. If that's not the case, ommit the following step:
Add a static route to your S3 bucket to your VPN server configuration, so every client tries to reach the bucket through the VPN instead of trying to establish a direct internet connection with it. For example, on OpenVPN, edit server.conf, adding the following line:
push "route yourS3bucketPublicIP 255.255.255.255"
After that you will see that when a client connects to the VPN it gets an extra entry added to its routing table, corresponding to the static route that tells it to reach the bucket trough the VPN.
Use S3 bucket ACLs "IpAddress" field to set the configuration you want. It should look something like this:
.
{
"Version": "2012-10-17",
"Id": "S3PolicyId1",
"Statement": [
{
"Sid": "IPAllow",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::examplebucket/*",
"Condition": {
"IpAddress": {"aws:SourceIp": "54.240.143.0/24"},
"NotIpAddress": {"aws:SourceIp": "54.240.143.188/32"}
}
}
]
}
You use IpAddress field to allow an IP or range of IPs using CIDR notation, and NotIpAddress field the same way for restricting an IP or range of IPs (you can ommit that one). That IP (or range of IPs) specified on IpAddress should be the public address(es) of the gateway interface(s) that route(s) your company's VPN Internet traffic (the IP address(es) S3 sees when somebody from your VPN tries to connect to it).
More info:
http://www.bucketexplorer.com/documentation/amazon-s3--access-control-list-acl-overview.html
http://aws.amazon.com/articles/5050/
http://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html#example-bucket-policies-use-case-3
https://openvpn.net/index.php/open-source/documentation/howto.html
Actually, #Michael - sqlbot was right until until May 15, 2015. What you do is correct. You found the documentation (again, correctly) that allows you to set up S3 bucket within VPC (probably with no access from outside world), the same way you set up your EC2 machines. Therefore,
On my S3 bucket, I verified that I could access index.html both from the regular Web and from the VPN.
is a problem. If you didn't make mistakes, you shouldn't be able to access the bucket from regular Web. Everything that you did afterwards is irrelevant - because you didn't create S3 bucket inside your VPN-connected VPC.
You don't give much details as to what you did in your very first step; the easiest is probably to delete this bucket and start from the beginning. With the need to set up route tables and what not it is easy to make a mistake. This is a simper set of instructions - but it doesn't cover as much ground as the document that you followed.
But any links that predate this capability (that is, any links before May 2015) are irrelevant.