Akom's Tech Ruminations

Various tech outbursts - code and solutions to practical problems
Linux

Bootstrapping S3/CloudFront with LetsEncrypt

Posted by Admin • Thursday, August 5. 2021 • Category: DevOps, Linux

Let's assume that you want to do the following:

  1. Host the contents of your S3 bucket via YOUR.DOMAIN.COM
  2. Use CloudFront
  3. Use a LetsEncrypt cert

"What's the problem?", you may ask. There are plenty of tutorials for this stuff. Not exactly. A CloudFront Distribution will not let you add a CNAME until you have an SSL cert, but you can't use certbot to auto-provision an SSL cert until you are hosting from your domain.

Solution

The easiest solution is to initially generate your SSL cert manually. You can then use something like certbot-s3front to auto-renew.

Details


Bucket

Create your S3 bucket and set up a Bucket Policy under Permissions like the following. See CloudFront below for MY_IDENTITY.


{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "AllowOAIRead",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity MY_IDENTITY"
            },
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::MY_BUCKET/*",
                "arn:aws:s3:::MY_BUCKET"
            ]
        },
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::MY_BUCKET/*"
        }
    ]
}
 

Alternatively, edit the ACL (just below) and give everyone Read. If you want directory listings to be shows, also check List.

Make your initial SSL key

On your local machine (linux, ideally), install docker and run:

sudo docker run -it --rm --name certbot -v "/etc/letsencrypt:/etc/letsencrypt" -v "/var/lib/letsencrypt:/var/lib/letsencrypt" certbot/dns-dnsimple certonly --manual -d MY_DOMAIN_NAME --preferred-challenges dns

You'll be prompted to add a TXT record in DNS. The reason we're using DNS challenge is that the normal file challenge won't work until we get CloudFront to accept a CNAME, and it won't until we have a key (catch-22).

You'll now have your keys in /var/lib/letsencrypt/_data/live/MY_DOMAIN_NAME/

CloudFront

  1. Create an Origin Access Identity if you don't have one. This gets used in S3 Bucket Policy above
  2. Create or edit your distribution.
  3. Create an Origin (second tab) and refer to the Origin Access Identity. Select your S3 bucket in the Origin Domain Name drop-down
  4. Create a Behavior and select the options you want. This also references the Origina Access Identity
  5. Back to General: Enter your domain name in CNAME and add a new key. You can use the add button to jump to ACM, but you may have to click around to find the option to "Import" your own SSL key. Paste your keys from files: cert.pem, priv.pem, chain.pem. Now you can select that key from the drop-down in General

Automation

Your distribution should now be working. To automate renewal, you can set up a job (eg Jenkins) to run certbot-s3front every few months.

0 Trackbacks

  1. No Trackbacks

0 Comments

Display comments as (Linear | Threaded)
  1. No comments

Add Comment


You can use [geshi lang=lang_name [,ln={y|n}]][/geshi] tags to embed source code snippets.
Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.
Markdown format allowed


Submitted comments will be subject to moderation before being displayed.