Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Amazon S3: using DNS alias to bucket + HTTPS at the same time

I want to create an S3 bucket in the Frankfurt zone, and make the files accessible with the URL: https://files.stample.co/filename

So I want both HTTPS, and a custom DNS alias (CNAME) at the same time.

According to what I understand, Amazon has a wildcard certificate for URL https://*.s3.amazonaws.com.

HTTPS / SSL

So this wildcard will:

  • Work for https://stample-files.s3.amazonaws.com
  • Not work for https://files.stample.co.s3.amazonaws.com

So what I understand and confirmed by other StackOverflow posts is that if I want SSL to work I have to use a bucket name with no dot otherwise the Amazon certificat with wildcard won't match the bucket domain.

Using DNS alias / CNAME

On this S3 documentation, under Customizing Amazon S3 URLs with CNAMEs section:

Depending on your needs, you might not want "s3.amazonaws.com" to appear on your website or service. For example, if you host your website images on Amazon S3, you might prefer http://images.johnsmith.net/ instead of http://johnsmith-images.s3.amazonaws.com/.

The bucket name must be the same as the CNAME. So http://images.johnsmith.net/filename would be the same as http://images.johnsmith.net.s3.amazonaws.com/filename if a CNAME were created to map images.johnsmith.net to images.johnsmith.net.s3.amazonaws.com.

This seems to be for technical reasons because otherwise Amazon can't know the bucket we try to target:

Because Amazon S3 sees only the original host name www.example.com and is unaware of the CNAME mapping used to resolve the request, the CNAME and the bucket name must be the same.

So what I understand here is that for CNAME to work, we have to use dots in the bucketname.

Both together ?

If I use dots in bucket name:

  • SSL won't work
  • CNAME will work

If I don't use dots in bucket name:

  • SSL will work
  • CNAME won't work

I've tested both cases and could not make SSL and CNAME work fine together.

What can I do to make both work? It seems to me that what I want to achieve is not very fancy...

like image 279
Sebastien Lorber Avatar asked Sep 22 '15 10:09

Sebastien Lorber


1 Answers

You can potentially do both, depending on what you mean by that, but it requires a change in your approach and an understanding of some S3 internals, or an understanding of why what you are trying can't possibly be expected to work.

First, to clarify, when I say you can do both, I assume you do not expect that you could create a bucket called "example.com" and then be able to access the bucket as https://example.com.

If that's what you want or expect, you are missing out on some fundamentals of SSL.

For a web server to offer SSL, it must have an SSL certificate signed by a trusted Certificate Authority. This certificate not only contains a public key used for encryption, it also contains the hostname for which it is valid, and will not work for a different hostname. SSL not only provides encryption, it also provides assurance that the web site you reached is indeed the web site you believe it to be. For s3, the hostname in the certificate is *.s3.amazonaws.com and some regional variants, which I'll explain below. The rules for hostname matching require that the * not match anything with a dot in it, so *.s3.amazonaws.com does match example-bucket.s3.amazonaws.com (no dot in the hostname component that aligns with the *) but it does not match example.com.s3.amazonaws.com because * does not match example.com since it contains a dot. These rules are imposed by browsers, and this isn't a limitation in S3.

Now, if you are trying to use https://example.com to access your bucket, S3 alone won't enable this, because example.com by itself isn't even remotely similar to the hostname on S3's SSL certificate, which is *.s3.amazonaws.com. You not only need to purchase an SSL certificate from a Certificate Authority that has been signed for use with "example.com," but you also need to install it on the web server... which, in this case, is S3... and S3 doesn't support this.

Amazon CloudFront, however, does. You can configure a CloudFront distribution as a front-end to your bucket, and install your own SSL certificate on CloudFront, accessing the bucket over HTTPS that way. In this configuration, it doesn't matter what your bucket name is -- it doesn't even have to match your domain name, because you can configure CloudFront to use whatever bucket you want. The browser fetches content through CloudFront, which in turn pulls the content from the bucket.

Now... assuming that isn't what you're asking... assuming that you don't expect your own domain to work in SSL with Amazon's certificate... you can configure a bucket with dotted name, allowing you to create a CNAME for hosting your "example.com" content... and still access the bucket with HTTPS. However, you can't access it with SSL using the CNAME, for reasons explained above... because your hostname doesn't match the one on S3's SSL cert.

However, if you want to access a bucket with dots in the name over SSL, you can do this using the regional endpoint where your bucket was provisioned.

The "example.com" bucket in the us-west-2 region would be addressed by putting the bucket name in the first part if the path instead if the beginning of the hostname... like this:

https://s3-us-west-2.amazonaws.com/example.com/path/to/file.jpg

Each S3 region has at least one regional endpoint that works this way. For the "US-Standard" region, the endpoints are "s3.amazonaws.com" which geographically routes to the main site in Virginia or the mirror site in Oregon, "s3-external-1.amazonaws.com" which routes only to Virginia, or "s3-external-2.amazonaws.com" which is largely undocumented but routes to the mirror in Oregon.

So, it is possible to access resources in a bucket with dots in the name, over HTTPS, but you have to know the bucket's region... though you cannot simply access it with https://your-cname.example.com, because of the way SSL works, in general.

like image 78
Michael - sqlbot Avatar answered Sep 27 '22 16:09

Michael - sqlbot