-1

I configured the ELB to open up both 80 and 443, where 443 is configured with SSL. Both ELB ports points to the instances' 80 port. The ELB's heatlh check is using ping target HTTP:80/index.html. It used to work, until I recently decided to start redirecting http to https.

Now the following codes are on the server.js(the codes within // are my newly added codes):

//
app.use(function(req, res, next) {
    if (config.env === 'prod' && req.get('X-Forwarded-Proto') !== 'https') {
        console.log("redirecting")
        console.log('https://' + req.get('Host') + req.url)
        res.set('X-Forwarded-Proto', 'https');
        res.redirect('https://' + req.get('Host') + req.url);
    }
    else
        next();
});
//

app.use(express.static(path.join(__dirname, 'home')));
app.set('trust proxy'); // enable this to trust the proxy

app.listen(app.get('port'), function() {
  console.log('Express server listening on port ' + app.get('port'));
});

app.get("/*", function(req, res, next) {
    res.sendFile(path.join(__dirname, 'home/index.html'));
});

I supposed the above request will redirect all request to the elb server but with https protocol.

However the server start printing:

redirecting
https://10.x.x.xx/index.html

And then the ELB is failing as https://10.x.x.xx/inde.html is not available.

However the index.html's location right under the {domain}/.

I think the way I redirect may be wrong - but I have no idea how to fix it.

jamesdeath123
  • 4,268
  • 11
  • 52
  • 93

2 Answers2

2

My solution was to check for the health API route prior to redirecting.

  1. Set up Health check on AWS load balancer to /api/health
  2. Add condition

if (config.env === 'prod' && req.get('X-Forwarded-Proto') !== 'https' && req.url !== '/api/health') { // redirect }

paqash
  • 2,294
  • 1
  • 17
  • 22
0

The load balancer health check requests won't have the x-forwarded-proto header, since they haven't been forwarded from a client, they are coming directly from the load balancer. You probably need to check if the header exists first, before doing the redirect.

Also I'm a bit confused about your SSL setup. Are you doing SSL termination at the Load Balancer, but also serving an SSL certificate at the EC2 server? You say "Both ELB ports points to the instances' 80 port", which means you aren't serving an SSL certificate on the EC2 server, so your health check URL should be http instead of https.

Also this line that you have right before the redirect accomplishes nothing at all:

res.set('X-Forwarded-Proto', 'https');
Mark B
  • 183,023
  • 24
  • 297
  • 295
  • I thought this will set all request with such header? Since only the request that doesn't have this header will get into this line? – jamesdeath123 Feb 27 '17 at 22:20
  • And regards to the SSL - currently, http://{domain} and https://{domain} will both work; only that the http:{domain} will not have the protection. SSL is done on ELB, which eventually points all requests to the EC2's port 80. – jamesdeath123 Feb 27 '17 at 22:21
  • The whole point of `x-forwarded-proto` header is to let the load balancer set that. Why would you want to override that at the server? And by setting it on the request right before you issue a redirect accomplishes nothing because the request is then discarded. – Mark B Feb 27 '17 at 22:41
  • Regarding your SSL I don't follow exactly what you are saying. Basically your issue is that you are sending a redirect to the health check URL, which isn't going to work. You have to allow the health check URL to load via http without redirecting. – Mark B Feb 27 '17 at 22:42
  • I see your point - wouldn't the redirected request also contain that header? I thought the req is still carrying all information with it. – jamesdeath123 Feb 27 '17 at 23:03
  • The request doesn't get sent back as part of the response. The redirect is the response, it isn't part of the request. And even if you set that header on the response, it wouldn't be accomplishing anything. The entire point of that header is to allow the ELB to communicate to the server what protocol the client connected to the ELB with. – Mark B Feb 27 '17 at 23:09
  • I see. That's really helpful. Thanks. – jamesdeath123 Feb 27 '17 at 23:11