Search code examples
amazon-web-servicesamazon-s3httpsdnscname

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...


Solution

  • It seems it is currently not possible to do by using S3 only, but it is possible with CloudFront as it supports custom certificates.

    CloudFront is not very expensive and can even be cheaper than S3 in some cases. It support custom certificates for free when using SNI (however it's not supported by older browsers like < IE7, < Chrome6, < Firefox 2.0)

    HOWTO with CloudFront

    I'll take as example that you want to use https://files.mydomain.com to point to an S3 bucket called mydomain-files (the bucket name does not mater and can contain dots).

    Custom certificate is required

    According to "Michael - sqlbot" anwser, it is required to use a custom certificate. My initial assumption was that using a CNAME will permit to use Amazon S3 wildcard certificate while using my custom domain but this was false: a custom certificate is absolutly required, and is possible to setup with CloudFront only, not S3.

    Get free certificate

    You can use whatever certificate provider you want but here I take StartSSL (StartCom) which provide free SSL certificates (limited to one subdomain and 1 year however).

    • Validate your ownership of domain mydomain.com
    • Create certificate with domain files.mydomain.com
    • Download the certificate (files.crt) and private key (files.key, encrypted with your custom password): they are in PEM format
    • Decrypt the private key: openssl rsa -in files.key -out files.key
    • Generate certificate chain with StartSSL files from here: cat sub.class1.server.ca.pem ca.pem >> chain.crt

    Upload certificate to AWS

    • Install AWS CLI to upload the certificate (note the key must be unencrypted, the certificate be in PEM format, and the certificate chain is required for CloudFront). You have to choose a name and a path (choose what you want but the path should start with /cloudfront/
    • Upload your certificate to AWS for Cloudfront usage, like documented here: aws iam upload-server-certificate --server-certificate-name CUSTOM_CERTIFICATE_NAME --certificate-body file://files.crt --private-key file://files.key --certificate-chain file://chain.crt --path /cloudfront/CUSTOM_PATH/

    Configure CloudFront

    • Create a new Web Distribution
    • Use CNAME: files.mydomain.com
    • Select the "Custom SSL certificate" radio button and select your certificate (CUSTOM_CERTIFICATE_NAME you choose when uploading)
    • Select your S3 bucket as CloudFront distribution origin
    • Validate and wait for deployment to complete: you should access your bucket files with url like https://xyzxyzxyz.cloudfront.net/file

    Configure DNS

    • Open your mydomain.com DNS configuration
    • Add the CNAME: files IN CNAME xyzxyzxyz.cloudfront.net
    • Wait for DNS to propagate (see DNS TTL) (can be fast if new DNS entry)

    End

    You should now be able to access your files with https://files.mydomain.com/file. The certificate will be your custom certificate generated for files.mydomain.com so everything will work fine.