简体   繁体   English

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

[英]How to run Amazon EC2 with Elastic Load Balancer and Node.js (HTTP and TCP) correctly?

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

Here's what I have so far 这是我到目前为止所拥有的

  • My HTTP server is a Node.js HTTP server with Express. 我的HTTP服务器是带有Express的Node.js HTTP服务器。 I wanted to encrypt all connections and found out I could get a free SSL certificate through Certificate Manager on Amazon. 我想加密所有连接,发现我可以通过亚马逊上的证书管理器获得免费的SSL证书。 However, I found out I need Elastic Load Balancer. 但是,我发现我需要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. 我无法让https为我的网络应用程序工作。
  • 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. 我们的想法是负载均衡器终止来自客户端的所有SSL连接,并将未加密的数据发送到80后的后端EC2机器上.node.js HTTP服务器正在侦听80。

This is my HTTP server file app.js 这是我的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);

});

I handle all my routes through routes.js 我通过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 . 123 The first post suggests this snippet of code. 第一篇文章提出了这段代码。 Including this in app.js results in a 302 error . app.js包含此内容会导致302 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. 另一个复杂性是ELB运行状况检查在端口80上ping并由同一HTTP服务器处理。 With this code snippet, the ELB starts seeing 5xx error and the ELB takes the instance out of service . 使用此代码段,ELB开始看到5xx error ,ELB使实例停止服务

  • For my TCP server, I plan to handle the SSL connections myself(self-generated certs). 对于我的TCP服务器,我计划自己处理SSL连接(自生成的证书)。 I run TCP on some random port. 我在一些随机端口上运行TCP。 When ELB sees SSL conenction on this port, will it terminate it? 当ELB在此端口上看到SSL连接时,它会终止它吗?

ELB listener config ELB监听器配置

(Load balancer) http 80 --> (Node instance) http 80 (负载均衡器)http 80 - >(节点实例)http 80

(Load balancer) https 443 --> (Node instance) http 80 (负载均衡器)https 443 - >(节点实例)http 80

(Load balancer) TCP random_port -->(Node instance) TCP random_port (负载均衡器)TCP random_port - >(节点实例)TCP random_port

Including this in app.js results in a 302 error. 在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 isn't an error, it's a redirect. 302不是错误,它是重定向。 You added code to redirect all HTTP requests to HTTPS. 您添加了代码以将所有HTTP请求重定向到HTTPS。 The code looks correct to me and should be redirecting if the original request to the ELB is not over HTTPS. 代码对我来说是正确的,如果对ELB的原始请求不是通过HTTPS,则应该重定向。

One of the posts recommends using reverse proxy. 其中一个帖子建议使用反向代理。 Is this necessary? 这有必要吗?

No it isn't. 不,不是。 It may provide a performance improvement, but it isn't necessary and would add extra moving parts at this point which could confuse things. 它可以提供性能改进,但它不是必需的,并且此时会添加额外的移动部件,这可能会使事情变得混乱。

The other complexity is that the ELB health check pings on port 80 and is handled by the same HTTP server. 另一个复杂性是ELB运行状况检查在端口80上ping并由同一HTTP服务器处理。 With this code snippet, the ELB starts seeing 5xx error and the ELB takes the instance out of service. 使用此代码段,ELB开始看到5xx错误,ELB使实例停止服务。

Are you sure the ELB is seeing 5xx errors instead of 302 responses? 你确定ELB看到5xx错误而不是302回复吗? Regardless, you need to add a condition to the if statement in that snippet to allow HTTP requests to the health check URL go through. 无论如何,您需要向该代码段中的if语句添加条件,以允许对运行状况检查URL的HTTP请求通过。

For my TCP server, I plan to handle the SSL connections myself(self-generated certs). 对于我的TCP服务器,我计划自己处理SSL连接(自生成的证书)。 I run TCP on some random port. 我在一些随机端口上运行TCP。 When ELB sees SSL connection on this port, will it terminate it? 当ELB在此端口上看到SSL连接时,它会终止吗?

Edit: I just realized you want to use self-signed certs over the TCP connections, so you should just specify a TCP listener on the ELB and forward that to TCP on the server, and the ELB will not try to terminate the SSL. 编辑:我刚刚意识到你想在TCP连接上使用自签名证书,所以你应该在ELB上指定一个TCP侦听器并将其转发给服务器上的TCP,并且ELB不会尝试终止SSL。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM