0

I'm trying to set up a solution which includes an EC2 instance with Apache running NodeJS. I've already successfully created a working webserver-instance with a public SSL-certificate from Certifate Manager accessed on port 80 and 443. This server should be able to connect to my other instance but for some reason I keep running into dead-ends and I suspect the solution is not possible...

I've built a working setup using Let's Encrypt certificates but I would love to keep as much as possible in AWS.

Issue: In the LE-solution, I can access the local .pem-files on my server. I can include the local paths to the LE-certificates in the server-setup-file like this:

...

var options = {
    key: fs.readFileSync("/etc/letsencrypt/live/example.com/privkey.pem"),
    cert: fs.readFileSync("/etc/letsencrypt/live/example.com/fullchain.pem")
};

var https   = require('https').Server(options, app);

...

but when I'm using AWS Certificate Manager's public certificates, I'm not sure how to get around this?

My solution (not working): I'm no SSL-wizard, so I might be trying to do something impossible here. I've tried to create a local certificate using OpenSSL but keep the Load Balancer and Certificate Manager certificate on the domain.

...

var options = {
    key: fs.readFileSync("/home/ec2-user/server-key.pem"),
    cert: fs.readFileSync("/home/ec2-user/server-cert.pem"),
};

var https   = require('https').Server(options, app);

...

This solutions returns following error message when I try to connect to the node/socket server with url: https://live.example.com:3000:

WebSocket connection to 'wss://live.example.com:3000/socket.io/?EIO=4&transport=websocket' failed: Error in connection establishment: net::ERR_CERT_COMMON_NAME_INVALID

So I guess that my solution with both Certificate Manager certificate on the domain and the OpenSSL certificate on the server isn't possible or is the problem to be found elsewhere?

Please let me know :-)

Simon Degn
  • 901
  • 1
  • 12
  • 40
  • Are you ok with using the AWS cert on a load balancer and having plain HTTP connections between the load balancer and your Apache server? – DylanSp Dec 15 '20 at 18:20
  • @DylanSp because you have a suggestion for a working solution or are you pointing out a security leak in my current setup? – Simon Degn Dec 15 '20 at 19:00
  • Suggestion for a working solution. The tl;dr is that Certificate Manager-issued certs can only be used on certain pieces of AWS infrastructure, like ELBs; you can't put them on arbitrary web servers you manage. – DylanSp Dec 15 '20 at 19:17
  • @DylanSp alright. If that's the case, I would consider another solution than CM. The solution is for a public mobile app, so no connection should be HTTP. – Simon Degn Dec 15 '20 at 19:30
  • The only HTTP connection would be internal to AWS's infrastructure, between the load balancer and your server. The connection from the mobile app to the load balancer would be HTTPS. – DylanSp Dec 15 '20 at 19:32
  • @DylanSp that's interesting. I understood you would disable HTTPS from the Load Balancer. How could you solve it like that then? – Simon Degn Dec 15 '20 at 20:15
  • 1
    I'll type up an answer describing it. :) – DylanSp Dec 15 '20 at 20:30
  • Do you have the solution for this? I have the exact problem but on Laravel. – Mr. Kenneth Nov 07 '22 at 05:03
  • @Mr.Kenneth it has been a few years and the project got stuck a few weeks after this. But I'm pretty sure I managed to make this part work and I'm also pretty sure that the solution was based on the answer by DylanSp below. Attach an Elastic Load Balancer and configure the SSL to this and then keep the connection between the load balancer and the server in plain HTTP. – Simon Degn Nov 07 '22 at 08:57
  • @SimonDegn does that mean you made the `options` blank? – Mr. Kenneth Nov 07 '22 at 09:00

1 Answers1

1

As mentioned in comments, certificates created through AWS Certificate Manager can only be used for certain AWS services such as Elastic Load Balancers, not self-managed web servers. What you can do is use a Certificate Manager cert and put it on a load balancer, with your Apache/Node server sitting behind the load balancer in a target group. All connections over the public internet would be HTTPS, but the connection between the load balancer and your app server (going over AWS's internal network) would be plain HTTP.

Diagram of HTTPS connections from clients to the Elastic Load Balancer and HTTP connections from the load balancer to EC2 instances

DylanSp
  • 1,379
  • 13
  • 27