Can't connect to Express server over HTTPS hosted on Amazon EC2 through Cloudfront

1

I'm trying to host my API on an AWS EC2 instance and connect to it over my domain configured with Cloudflare (see below) that points to AWS Cloudfront. I can access it over HTTP but not over HTTPS (which gives me a 502 Bad Gateway).

Enter image description here

Cloudfront is configured to receive HTTPS traffic with an SSL setup by AWS Certificate Manager. It's origin is the Public IPv4 DNS address of my EC2 instance: Enter image description here

Both the behavior and origin are set to receive both HTTP and HTTPS traffic: Enter image description here

Enter image description here

EC2 instance has a security group that allows all IPv4 and IPv6 Inbound Traffic and all outbound traffic: Enter image description here

The EC2 instance is running Express (Node.js) on Ubuntu with all incoming HTTP/HTTPS traffic allowed: Enter image description here Requests made over HTTP show on my NodeJS app's logs but HTTPS requests do not. The Express app is listening on port 80. Should it also be listening on port 443 somewhere?

Thank you so much to anyone who can help! I've been figuring this out for 2 days.

1 Answer
1
Accepted Answer

Hi, thanks for posting your question on re:Post!

Your CloudFront config looks good - you have correctly selected "Match viewer" for the Origin Protocol Policy. Could you provide more details about your use case? This information will help us offer the most relevant and effective advice.

EC2 instances indeed come with Public DNS names that allow access to your instances via the internet. However, it's important to note that these Public DNS names are not designed to be stable over time. They can change when instances are stopped and started, or when there are changes to the underlying infrastructure. This can potentially lead to disruptions if you rely on the Public DNS names for your application's accessibility.

To achieve a more stable and reliable solution for handling traffic to your instances, we recommend utilising an Elastic Load Balancer (ELB). An ELB provides a single endpoint that distributes incoming traffic across multiple instances, increasing the availability and fault tolerance of your application.

Here's a concise guide on the recommended approach:

  1. Implement an ELB to manage traffic across your instances, ensuring better fault tolerance and availability.
  2. Utilise Route 53 to create an Alias Record that points to your ELB.
  3. Create an SSL/TLS certificate for your ELB through AWS Certificate Manager for your custom domain managed with Route 53.
  4. Use ELB as an origin for Amazon CloudFront. This way, you can also offload the SSL/TLS functionality from your application server.

Optionally, please follow our guide on Adding HTTPS listeners to Elastic Load Balancers.

This is an example of an express app that is listening on both port 80 and 443 (and is supporting HTTP and HTTPS):

const fs = require('fs');
const http = require('http');
const https = require('https');
const credentials = {
  key: fs.readFileSync('key.pem', 'utf8'),
  cert: fs.readFileSync('cert.pem', 'utf8')
};

const express = require('express');
const app = express();

const httpServer = http.createServer(app);
const httpsServer = https.createServer(credentials, app);

httpServer.listen(80);
httpsServer.listen(443);

In your Node application, please make sure that you are calling createServer twice (once with app and once with credentials and app).

AWS
Piotrek
answered 9 months ago
  • Thank you for your prompt response. I generated the publicly trusted certificate with AWS Certificate Manager and according to https://docs.aws.amazon.com/acm/latest/userguide/export-private.html, I "cannot export a publicly trusted certificate or its private key" and thus, cannot provide the .pem files to Express.

  • I have updated my answer to reflect how to integrate an Elastic Load Balancer with HTTPS as an origin on CloudFront. You can also have a look on our post Why can't I configure ACM certificates for my website hosted on an EC2 instance?

    Should you need more specific guidance, please provide us with more details about your use case and/or compliance requirements.

  • Thank you very much for your help! Setting up the Elastic Load Balancer with the HTTPS requests pointed to port 80 of the instance fixed it.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions