How to hide AWS S3 Bucket URL with custom CNAME - amazon-web-services

I want to connect CDN to an AWS S3 Bucket, but the AWS Document indicates that the bucket name must be the same as the CNAME. Therefore, it is very easy to guess the real s3 bucket url by others.
For example,
- My domain: example.com
- My S3 Bucket name: image.example.com
- My CDN CNAME(image.example.com) will point to image.example.com.s3.amazonaws.com
After that, people can access the CDN URL -> http://image.example.com to obtain the resources from my S3 Bucket. However, under this restriction, people can guess my real S3 bucket url from the CNAME (CNAME + s3.amazonaws.com) easily.
So, my question is that how can I hide my real s3 bucket url? Because I don't want to expose my real S3 url to anyone for preventing any attacks.

I am not sure I understand what you are asking for or what you are trying to do [hiding your bucket does not really help anything], however I will attempt to answer your question regarding "hiding" your bucket name. Before I answer, I would like to ask these two questions:
Why do you want to hide your S3 bucket url?
What kind of attacks are you trying to prevent?
You are correct that the S3 bucket name had to be the same as your URL. This is no longer a requirement as you can mask the S3 bucket using cloudfront. CloudFront as you know is a CDN from AWS. Thus the bucket name could be anything (randomstring).
You can restrict access to the bucket, such that only CloudFront can access it. Data in the bucket is then replicated to edge locations and served from there. Even if one knows the S3 URL, it will not do anything as access to the s3 bucket is restricted, an IAM rule grants CloudFront access and no one else.
Access restriction is done via origin access and while you can manually configure this using a bucket policy, you can also set a flag in CloudFront to do this on your behalf. More information is available here.
Use the CloudFront name in Route53. Do not use CNAME, but rather use A type, and set it up as an Alias. For more information see this document.
If you are using a different DNS provider, AWS aliases will naturally not be available. I suggest moving the zone file from your other provider to AWS. If you cannot do this, then you can still use a CNAME. Again see here for more information.
I suggest using your own domain name for CloudFront and setting up HTTPS. AWS offers certificates at no additional cost for services within AWS. You can register a certificate for your domain name which is either validated by a DNS entry or an Email. To set this up please see this document.
If you want to restrict access to specific files within AWS, you can use signed URLs. More information about that is provided here.

Related

Redirect directories to individual s3 buckets?

I have a Laravel application hosted on a domain. I have several dynamic directories ie:
example.com/directory
example.com/random
example.com/moon
I would like each of these directories to resolve to a different s3 bucket while masking the URL (I want to see the URL above, not the s3 bucket URL). What's the best way to accomplish this? I could possibly create a primary bucket and host example.com on it and create routing rules on that s3 bucket to redirect to the other s3 buckets (I think). What do those routing rules look like? I was unable to find directions in the AWS documentation that showed how to redirect to other buckets. Is there another, more simple way to go about this?
It's worth noting the Laravel application may not need to be involved in the actual routing as much as using the AWS sdk to dynamically configure the directories.
You have to use Route53 along with S3 enabling static website hosting.
For detail configuration about static website hosting in S3, you can take a look here.
After that choose Route53 as a service in AWS Console.
Select your hosted zone and add a CNAME recordset, in the value field enter the S3 bucket endpoint url and in the Name field enter the url that you want to point to the S3 bucket.
For using Route53 you can read this AWS document.
The best way would be to create a CloudFront (CF) distribution with three different origins. Then each origin would respond to different Origin Path which would lead to different buckets.
example.com could be defined in Route53, with Alias A record to the CF distribution. The benefit of using CF with S3 is that you not only can speed up your website (CF is CDN), but also you can keep your buckets and objects private:
Amazon S3 + Amazon CloudFront: A Match Made in the Cloud

Can I Use same AWS S3 bucket for 2 domains whilst using the cloudflare CDN

I am using AWS S3 bucket for storing and displaying the user upload image files.
My website name is example.net and as I want to use cloudflare CDN and show the image url path as images.example.net (as I want to mask the S3 url).
I created a S3 bucket with name images.example.net and mapped the CNAME images.example.net.s3.us-east-1.amazonaws.com as images.
So I am able to access the images using url images.example.net/myPic.jpg
Recently I got a new domain example.com (only the extension is different), and now I want to use the same S3 bucket example.net to store the files and the url needs to shown as images.example.com/myPic.jpg
If I create a new S3 bucket images.example.com , then I can do it, but I want to use the existing one only.
Is there any method to configure in cloudflare for that ?
Can I do it without creating a new bucket named images.example.com ?
If you're using virtual hosting then you're limited to a single domain per bucket by using the domain as the bucket name.
The only options available to you are:
Create a second S3 bucket with your other domain name as the CNAME
Create a CloudFront distribution in front of your S3 bucket and specify both domains as alternative domain names. Then on CloudFlare use the CloudFront CNAME. Disable all caching to allow CloudFlare to handle all the CDN functionality.
Obviously neither are ideal for your scenario, however these are the options available at this time.

Connecting GovCloud S3 resource with CloudFront

Can we connect a Non-Public s3 bucket sitting on AWS Gov Cloud to a cloudfront distribution on a non gov cloud AWS account. There is not much docs or steps given anywhere.
We did try connecting it with Canonical Account ID, Cloudfront Origin in the s3 bucket policy. But nothing has worked so far.
Is this not possible or is there a way to achieve this?
Edit:
I ask this because there is a section of AWS docs talks about tips on having gov-cloud s3 content on cloudfront. But it has no details on how to do it.
Link: https://docs.aws.amazon.com/govcloud-us/latest/UserGuide/setting-up-cloudfront-tips.html
It is hard to see how that would be possible.
AWS GovCloud regions are physically isolated, including logical network isolation from all other AWS regions, except for very specific service endpoints.
Here is another solution, provided in the official AWS documentation:
https://aws.amazon.com/premiumsupport/knowledge-center/cloudfront-serve-static-website/
For Origin Custom Headers, under Header Name, enter Referer. Under Value, enter a custom header that you want to forward to the origin (S3 bucket). To restrict access to the origin, you can enter a random or secret value that only you know.
Basically, Cloudfront will use a custom header containing a secret value, your S3 bucket on govcloud will be public read access with a custom policy to allow only this secret value in the header.
Don't forget to force HTTPS between cloudfront and your govcloud s3 bucket with OriginProtocolPolicy https-only set.

have multiple subdomains refer to the same S3 bucket without HTTP redirect

I have a bucket called subdomain.domain.com that hosts code that should be used whenever users go to various subdomains.
e.g. going to:
- a.domain.com
- b.domain.com
- c.domain.com
Should go to the same bucket.
I've set the CNAME for all the subdomain URL's to go to the URL of the subdomain.domain.com bucket. The problem is that, AWS tries to look for bucket a.domain.com' instead of just going tosubdomain.domain.com' bucket
I've read some suggestions saying I can create a bucket like a.domain.com and have it redirect back to subdomain.domain.com but I don't want a URL change and I'd like to be able to upload just to one bucket and all subdomains will be updated.
Some features that appear to be "missing" in S3 are actually designed into CloudFront, which complements S3. Pointing multiple domain names to a single bucket is one of those features. It isn't possible to do this with only S3 since, as you noticed, S3 matches the hostname with the bucket name.
Create a CloudFront distribution, defining each of the desired domain names as Alternate Domain Names.
For the origin server, type in the web site endpoint hostname of the bucket, found in the S3 console. (Don't select the bucket from the dropdown list).
Point the various hostnames to CloudFront in DNS.
CloudFront will translate the incoming hostnames so that S3 serves all the domains from a single bucket, the one you specified as the origin server.
Note that this configuration also allows you to optionally use SSL with your web hosting buckets, which is another feature that S3 relies on CloudFront to implement.

How to disable Amazon S3 raw endpoint access

Say you want to host a static web site on S3 :
You create a bucket with name your-website.com and set it up for web hosting;
You add a CNAME in your domain's zone file to point to your S3 bucket.
Great. Everything works fine when you visit http://your-website.com. But you don't want the raw/"naked" endpoint to be accessible.
Is there any setting in the bucket to disable direct access to http://your-website.com.s3-website.your-region.amazonaws.com ?
The reason is that if your web site is accessible both through http://your-website.com and http://your-website.com.s3-website.your-region.amazonaws.com would hurt your SEO (duplicate content)
You mention your major concern is SEO. For that purpose, you could use a other techniques, that are probably easier to implement than the one you initially asked about.
One of the main techniques to deal with duplicate content is to use rel=canonical, which is probably fairly easy to implement. For more information, see http://googlewebmastercentral.blogspot.com.br/2013/04/5-common-mistakes-with-relcanonical.html
If you insist on the need to disable access to the bucket unless the client connects through your CNAME, your best bet is to use CloudFront. You disable the S3 website hosting option on your bucket, make your S3 bucket private (i.e., remove bucket policies or ACLs allowing public read), create a CloudFront distribution, define your bucket as the origin, configure a CNAME on your distribution, change your DNS records to point to your distribution instead of bucket, create an Origin Access Identity (OAI) on your distribution and grant access to your bucket for that OAI. Phew.
By doing all this, there's no way for a user to access the content on your S3 bucket (unless they have an AK/SK with permissions to read the bucket, and send a signed request, obviously). The only way will be through your domain.
For more detail on Origin Access Identity, see http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html