Using CloudFront with externally hosted DNS, pointing to EC2 instance

Viewed 3884

I'm trying to set up cloudfront with my ec2 instance. The domain is at dreamhost, and I've added a CNAME record pointing to the cloudfront url.

I'm using Lets Encrypt on my EC2 instance. If I use my elastic IP and set that to an A record on dreamhost, it forwards fine and everything works. If I point the CNAME record to the cloudfront url I get a 502 error.

Following the troubleshooting guide here, I checked my SSL cert using an online service and it shows that everything is fine.

What am I missing? Does the cloudfront url have to be added to my cert or what?

Also, I'm pointing the distribution's SSL cert to a cert hosted in AWS Certificate Manager, that I think is ultimately pointing at my origin. I pointed the cert to my url and added the CNAME record to verify ownership and all of that seemed to work fine.

UPDATE:

I plugged my ec2 public url into an online ssl checker and I get the below result. Perhaps this could be part of the problem? I get the same result if I enter my elastic IP. It seems like this could be the culprit, but I have no idea what the next step is. Back to googling..

enter image description here

UPDATE 2:

From what I'm reading, I need to make sure the intermediate certificate is installed on my ec2 instance. I also learned that in Apache 2.4 the fullchain.pem file takes the place of the old cert.pem file as the SSLCertificateFile.

I modified the contents of /etc/httpd/conf/httpd-le-ssl.conf like so:

   <VirtualHost *:443>
      DocumentRoot "/var/www/html"
      ServerName "test.example.com"
      ServerAlias "test.example.com"
      Include /etc/letsencrypt/options-ssl-apache.conf
      SSLCertificateFile /etc/letsencrypt/live/test.example.com/fullchain.pem
      SSLCertificateKeyFile /etc/letsencrypt/live/test.example.com/privkey.pem
   </VirtualHost>

After changing that and restarting the httpd service, i'm still getting the error on my url. When I plug in test.example.com into the SSL checker, it shows this:

enter image description here

Keep in mind the first screen shot I posted was using my elastic IP, not my test.example.com url, so the aren't really comparable. I unfortunately don't have a screenshot of what test.example.com looked like before I made the changes, but I'm still getting a 502 error, so it's not apparently fixing it.

UPDATE 3:

It looks like my response headers are showing server: CloudFront when I navigate to test.example.com, so that's a step in the right direction. I wasn't getting that at all before.

UPDATE 4:

I downloaded openssl and was able to get the following information. It's weird that the certificate chain doesn't even show lets encrypt as a source of a certificate.

I originally set up my EC2 instance using a letsencrypt cert using test.example.com. Then when I created the cloudfront dstribution I used certificate manager to create a cert pointing to my test.example.com I'm now wondering if I somehow configured that wrong since the openssl output shows only an amazon cert. I'm confused by the interaction between the certificate manager and the lets encrypt cert that both seem to be pointing to the same url. ugh.

I'm thinking I'm going to have to set up an elastic load balancer and use the cert from ACM in the ELB. Then I guess I won't need the lets encrypt cert on the EC2 instance anymore?

enter image description here

enter image description here

enter image description here

2 Answers

If you use the second approach that @Kannaiyan pointed out, you don't need to move the domain name to AWS. Simply create a hosted zone and copy the NS records generated in the zone to your DNS provider. You can then easily hook up your domain name, including the apex domain, to the Cloudfront distribution.

You can check my answer here

If you want to use your custom SSL with a dedicated IP, AWS is going to charge you $600 per month. CloudFront will give dedicated IP Address at the edge and takes your SSL and serve with that IP Address.

You can also import Custom SSL to your AWS Cert manager which then can be used to assign it to the CloudFront Endpoint. The only drawback with this approach is, you need to update the SSL again during cert renewal.

Other alternatives,

Steps with a third party DNS provider.

  1. Create CNAME Record with your DNS provider.
  2. Create AWS Secure Certificate with AWS certificate manager, which may require domain verification with a CNAME or email address. This is FREE.
  3. Add CNAME record to your CloudFront distribution.
  4. Once you receive the cert, assign the cert to CloudFront endpoint

There will be an additional round trip to query DNS to resolve to IP.

CNAME (Resolve) --> CloudFront Host DNS Name (something.cloudfront.net) --> Resolve to IP.

Alternatively, (Also the best way to do it)

If you move your DNS to Route 53, you can assign your CloudFront to a Distribution, that will resolve your serving domain in a single DNS request.

With the above setup, I'm not finding a need for Lets Encrypt cert with EC2.

More info on Custom SSL Certs with AWS on CloudFront can be found from here.

Hope it helps.

EDIT:

Validate SSL:

  1. Point your cloudfront origin to a S3 bucket.
  2. Verify cloudfront url works without issues in connect to S3 bucket with the object.
  3. Verify with Custom Domain URL to make sure custom SSL cert works.
  4. Now change your origin to EC2 server.
  5. Make sure you log the request and response for debugging purposes.
  6. Validate your custom domain url again.
  7. If you receive 5XX then, check the response from your EC2 server.
Related