My Goal: To run 2 servers, HTTP server for my web application and TCP server to handle my TCP clients and use SSL for both. I want ELB to handle SSL for HTTP and my application to handle the SSL connection for TCP server (I use self-signed certs only for TCP server),
Here's what I have so far
- My HTTP server is a Node.js HTTP server with Express. I wanted to encrypt all connections and found out I could get a free SSL certificate through Certificate Manager on Amazon. However, I found out I need Elastic Load Balancer. So I set one up and it has been more painful than I anticipated. I'm having trouble getting https working for my web application.
- The idea is that the load balancer terminates all the SSL connections from client and sends the un-encrypted data to the Back-end EC2 machine over 80. The node.js HTTP server is listening on 80.
This is my HTTP server file app.js
var express = require('express');
var http = require('http');
var servestatic = require('serve-static');
var app = express();
var bodyParser = require('body-parser');
var flash = require('connect-flash');
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var cacheResponseDirective = require('express-cache-response-directive');
app.use(morgan('dev')); // log every request to the console
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({extended: true })); // support encoded bodies
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session
app.use(cacheResponseDirective());
app.use(express.static('public')); // enable if needed for server to serve static content
require('routes.js')(app); // Load routes and pass in our app and fully configured passport
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
if ('OPTIONS' == req.method) {
res.send(200);
}
else {
next();
}
};
var server = app.listen(80, function() {
console.log('The server is running at http://%s,%s', HOST,PORT);
});
I handle all my routes through routes.js
module.exports = function (app) {
path = require('path');
// for home or index page
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, './models', 'index.html'));
});// end of index file
// for contact page
app.get('/contact', function (req, res) {
res.sendFile(path.join(__dirname, './models', 'contact.html'));
});
// route for signup
app.get('/signup', function (req, res) {
console.log("\n I'm in index");
res.sendFile(path.join(__dirname, './models', 'signup.html'));
});
app.get('/loginBtn', function (req, res) {
console.log("\n I'm in initial login page");
res.sendFile(path.join(__dirname, './models', 'login.html')); // Go to the login page
});
};
I did my research and found these posts related to this issue. 1, 2, 3. The first post suggests this snippet of code. Including this in
app.js
results in a302 error
. How can I de-bug this issue? where should I include it?app.use(function(req, res, next) { if((!req.secure) && (req.get('X-Forwarded-Proto') !== 'https')) { res.redirect('https://' + req.get('Host') + req.url); } else next(); });
One of the posts recommends using reverse proxy. Is this necessary?
The other complexity is that the ELB health check pings on port 80 and is handled by the same HTTP server. With this code snippet, the ELB starts seeing
5xx error
and the ELB takes the instance out of service.For my TCP server, I plan to handle the SSL connections myself(self-generated certs). I run TCP on some random port. When ELB sees SSL conenction on this port, will it terminate it?
ELB listener config
(Load balancer) http 80 --> (Node instance) http 80
(Load balancer) https 443 --> (Node instance) http 80
(Load balancer) TCP random_port -->(Node instance) TCP random_port