Without making s3 bucket public how can we host website - web-services

Trying to host submit form index.hmtl file in s3 bucket with out public access
{
"Version": "2008-10-17",
"Id": "permissionTohttps",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxxxx:root"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::test-2018/test/*",
"Condition": {
"Bool": {
"aws:SecureTransport": "true"
}
}
}
]
}
Trying to host submit form index.hmtl file in s3 bucket with out public access

If you enable website hosting on an S3 bucket, it's going to be public.
It's not clear exactly how you want to restrict access to the web-form, but you could accomplish this by disabling website hosting on the bucket, then setting up an AWS CloudFront distribution that uses your S3 bucket as the origin (the source files for the distribution). You can then require signed URLs to access the CloudFront distribution (which would require you to have some other website that can issue signed URLs). You could alternatively use WAF rules (Web ACLs) that only allow requests from an IP range that you desire.

Related

S3 Bucket Policy for Limiting Access to Cloudflare IP Addresses

I will be using Cloudflare as a proxy for my S3 website bucket to make sure users can't directly access the website with the bucket URL.
I have an S3 bucket set up for static website hosting with my custom domain: www.mydomain.com and have uploaded my index.html file.
I have a CNAME record with www.mydomain.com -> www.mydomain.com.s3-website-us-west-1.amazonaws.com and Cloudflare Proxy enabled.
Issue: I am trying to apply a bucket policy to Deny access to my website bucket unless the request originates from a range of Cloudflare IP addresses. I am following the official AWS docs to do this, but every time I try to access my website, I get a Forbidden 403 AccessDenied error.
This is my bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CloudflareGetObject",
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::ACCOUNT_ID:user/Administrator",
"arn:aws:iam::ACCOUNT_ID:root"
]
},
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::www.mydomain.com/*",
"arn:aws:s3:::www.mydomain.com"
],
"Condition": {
"NotIpAddress": {
"aws:SourceIp": [
"2c0f:f248::/32",
"2a06:98c0::/29",
"2803:f800::/32",
"2606:4700::/32",
"2405:b500::/32",
"2405:8100::/32",
"2400:cb00::/32",
"198.41.128.0/17",
"197.234.240.0/22",
"190.93.240.0/20",
"188.114.96.0/20",
"173.245.48.0/20",
"172.64.0.0/13",
"162.158.0.0/15",
"141.101.64.0/18",
"131.0.72.0/22",
"108.162.192.0/18",
"104.16.0.0/12",
"103.31.4.0/22",
"103.22.200.0/22",
"103.21.244.0/22"
]
}
}
}
]
}
By default, AWS Deny all the request. Source
Your policy itself does not grant access to the Administrator [or any other user], it only omits him from the list of principals that are explicitly denied. To allow him access to the resource, another policy statement must explicitly allow access using "Effect": "Allow". Source
Now, we have to create Two Policy Statment's:- First with Allow and Second with Deny. Then, It is better to have only One Policy With "allow" only to Specific IP.
It is better not to complicate simple things like using Deny with Not Principal and NotIPAddress. Even AWS says :
Very few scenarios require the use of NotPrincipal, and we recommend that you explore other authorization options before you decide to use NotPrincipal. Source
Now, the questions come on how to whitelist Cloudflare IP's???.
Let's go with a simple approach. Below is the Policy. Replace your bucket name and your Cloudflare Ip's. I have tested it and it is running.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudFlareIP",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:getObject",
"Resource": [
"arn:aws:s3:::my-poc-bucket",
"arn:aws:s3:::my-poc-bucket/*"
],
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"IP1/32",
"IP2/32"
]
}
}
}
]
}

How do I determine the path to AWS Buckets

I am new to AWS. I have a website and I would like to host my larger images on AWS. I have successfully created a bucket and can access that bucket via FTP but I do not know how to determine the URL for the contents of that bucket so I can reference the images on my website.
I have tried: https://bucketname.s3.amazonaws.com/imagename.jpg
and I have tried https://s3.amazonaws.com/bucketname/imagename.jpg
But I get errors on both.
What is the correct path?
Thank you.
Click on the bucket. Go to properties, scroll to the bottom, under 'static website hosting', click edit then enable.
Once saved, you will be provided with a 'bucket website endpoint' (i.e. a url to access your files).
Under the 'permissions' tab, you may also need to allow public access to the objects in the bucket by adding a bucket policy like this:
{
"Version": "2012-10-17",
"Id": "Policy1517754859350",
"Statement": [
{
"Sid": "AllowGetObjects",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::YOUR-BUCKET-NAME-HERE/*"
}
]
}
AWS S3 objects can be accessed at https://{bucket}.s3.amazonaws.com/{key}.
You should have seen an error message in the webpage.
But before that, make sure that the object in the bucket is public. Go to the bucket, change the object to make it public.
But best option is to create a CloudFront distribution. Otherwise accessing S3 bucket directly is costly.
In addition to the other two answers posted, which helped move me in the right direction I was able to get more insights and discovered that the easiest way to provide read-only access to bucket assets is to set an ACL that is domain specific so that only requests that come from the designated URL will have read access to the contents of the bucket:
{
"Version": "2012-10-17",
"Id": "http referer policy",
"Statement": [
{
"Sid": "Allow get requests originating from www.example.com and example.com.",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::bucketname/*",
"Condition": {
"StringLike": {
"aws:Referer": "https://example.com/*"
}
}
}
]
}
The URL or path to the resources is provided in the Control Panel when you add objects to the bucket and is listed as the
Object URL
.

Files uploaded with CloudFront 403 error when access Root account via AWS Console

Uploading files through CloudFront to s3 bucket via a CloudFront Origin Access Identity runs successfully, however properties of the uploaded files are unable to be modified and some meta-data is unable to be accessed by the root user of my AWS account. I am able to get the files through the CloudFront endpoint, however I do not understand why I am not able to modify or access some fields of the uploaded files through my AWS root account via the AWS Management Console.
The default ACL in the s3 bucket is for the root user account as can be seen below:
I added in a second policy to my bucket just to ensure that the root user has explicit access to the files. The full bucket policy can be seen below:
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity 00000000000000"
]
},
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::my-bucket/stuff/",
"arn:aws:s3:::my-bucket/stuff/*",
"arn:aws:s3:::my-bucket/other-stuff/",
"arn:aws:s3:::my-bucket/other-stuff/*"
]
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::000000000000:root"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-bucket/stuff/",
"arn:aws:s3:::my-bucket/stuff/*",
"arn:aws:s3:::my-bucket/other-stuff/",
"arn:aws:s3:::my-bucket/other-stuff/*"
]
}
]
}
When I view a file that I have uploaded through CloudFront I am receiving a Access Denied for numerous options on the file overview tab:
I am also receiving more Access Denied from the file properties tab on the same file:
You need to pass ACL "Bucket-owner-full-control" with the PUT/POST call you're making with CloudFront link and also modify the Bucket policy for CloudFront to allow you PutobjectACL.

AWS CloudFront is Downloading files when multiple websites are hosted in the same bucket

I have an s3 bucket myBucket with two websites in it. First website is at root and the second one is in the folder abc. A CloudFront distribution has been configured on myBucket and its working successfully since an year. Here is the cloudfront access identity policy on the bucket.
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXXXXXXX"
},
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::myBucket",
"arn:aws:s3:::myBucket/*"
]
}
]
}
Since the cloudfront identity has access to all the bucket its successfully serving the pages from the bucket folder myBucket/abc when accessed through https://myexample.com/abc/index.html but when refreshed its downloading a blank file with the name download. These two websites are linked and hence needed to keep them in the same bucket. Is there anyway how i can get rid of this download ? Also should i have to create another origin and the corresponding behavior to do this right ?

Making S3 static web hosting content private

I want to be able to publish test reports to S3 and have it accessible to the URL sent at the end of the Drone build.
Is it possible to have the S3 static site not view-able by anyone? So its only accessible by people who can already access resources in the VPC using a VPN.
I read that the content must have public read access, so checking if that is avoidable.
Yes:
Set up the static website as normal,
Add a VPC endpoint for S3,
Use a bucket policy to deny all but traffic from your VPC.
Here is a good article describing it in more detail: https://blog.monsterxx03.com/2017/08/19/build-private-staticwebsite-on-s3/
The other option is to write an S3 bucket policy like below, where x.x.x.x/x is the CIDR of the VPC:
{
"Id": "Policy1564215115240",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1564215036691",
"Action": "s3:*",
"Effect": "Deny",
"Resource": "arn:aws:s3:::<s3 bucket name>",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": "x.x.x.x/x"
}
},
"Principal": "*"
}
]
}