如何使用Elastic Load Balancer和Node.js(HTTP和TCP)正确运行Amazon EC2?

我的目标 :运行2台服务器,用于我的Web应用程序的HTTP服务器和用于处理我的TCP客户端的TCP服务器,并使用SSL。 我希望ELB为HTTP处理SSL我的应用程序来处理TCP服务器的SSL连接 (我只使用TCP服务器的自签名证书),

这是我迄今为止

  • 我的HTTP服务器是一个带有Express的Node.js HTTP服务器。 我想encryption所有的连接,发现我可以通过亚马逊的证书pipe理器获得一个免费的SSL证书。 但是,我发现我需要Elastic Load Balancer。 所以我决定一个,比我预料的更痛苦。 我在为Web应用程序工作时遇到问题。
  • 这个想法是,负载平衡器终止来自客户端的所有SSL连接,并将未encryption的数据发送到80以上的后端EC2机器.jar HTTP.jsp服务器正在侦听80。

这是我的HTTP服务器文件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); }); 

我通过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 }); }; 
  • 我做了我的研究,发现这些post与这个问题有关。 1,2,3 。 第一篇文章提出了这段代码。 在app.js包含这个会导致302 error我怎样才能解决这个问题? 我应该在哪里包括它?

     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(); }); 
  • 其中一个postbuild议使用反向代理。 这是必要的吗?

  • 另一个复杂性是ELB健康检查在端口80上查询,并由同一个HTTP服务器处理。 有了这个代码片段,ELB开始看到5xx error ,而ELB将这个实例退出服务

  • 对于我的TCP服务器,我打算自己处理SSL连接(自我生成的证书)。 我在一些随机的端口上运行TCP。 当ELB在这个端口上看到SSL连接时,它会终止它吗?

ELB监听器configuration

(负载平衡器)http 80 – >(节点实例)http 80

(负载均衡器)https 443 – >(节点实例)http 80

(负载平衡器)TCP random_port – >(节点实例)TCP random_port

在app.js中包含这个会导致302错误。

 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(); }); 

302不是一个错误,它是一个redirect。 您添加了将所有HTTP请求redirect到HTTPS的代码。 该代码看起来是正确的,如果ELB的原始请求不是通过HTTPS,应该redirect。

其中一个postbuild议使用反向代理。 这是必要的吗?

不,不是。 它可能会提供一个性能改进,但是这不是必要的,并且会增加额外的运动部件,这可能会混淆事物。

另一个复杂性是ELB健康检查在端口80上查询,并由同一个HTTP服务器处理。 有了这个代码片段,ELB开始看到5xx错误,而ELB将这个实例退出服务。

你确定ELB是看到5xx错误,而不是302响应? 无论如何,您需要在该片段中的if语句中添加一个条件,以允许对健康检查URL的HTTP请求通过。

对于我的TCP服务器,我打算自己处理SSL连接(自我生成的证书)。 我在一些随机的端口上运行TCP。 当ELB在此端口上看到SSL连接时,它会终止它吗?

编辑:我只是意识到你想通过TCP连接使用自签名证书,所以你应该指定一个ELB上的TCP侦听器,并将其转发到服务器上的TCP,ELB不会尝试终止SSL。