Cloudflare SSL错误522 Express

时间:2019-01-03 20:35:54

标签: javascript node.js express ssl express-generator

我使用express建立了一个express-generator项目,现在我试图将其转换为在SSL Certificate上使用cloudflare https的工作。

我在端口443上运行我的Express应用。

但是,当我随后进入该域时,遇到cloudflare 522错误,即使阅读文档,我也无法弄清楚是什么原因造成的。

服务器代码

#!/usr/bin/env node

/**
 * Module dependencies.
 */

var app = require('../app');
var debug = require('debug')('myapp:server');
var http = require('http');

/**
 * Get port from environment and store in Express.
 */

var port = normalizePort(process.env.PORT || '443');

app.set('port', port);

/**
 * Create HTTP server.
 */

var fs = require('fs')
var https = require('https');
var options = {
  key: fs.readFileSync(__dirname + '/certs/key.pem'),
  cert: fs.readFileSync(__dirname + '/certs/cert.pem')
};

var server = https.createServer(options, app);

/**
 * Listen on provided port, on all network interfaces.
 */

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

/**
 * Normalize a port into a number, string, or false.
 */

function normalizePort(val) {
  var port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

/**
 * Event listener for HTTP server "error" event.
 */

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  var bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}

/**
 * Event listener for HTTP server "listening" event.
 */

function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
}

在此部分中创建服务器的

var fs = require('fs')
var https = require('https');
var options = {
  key: fs.readFileSync(__dirname + '/certs/key.pem'),
  cert: fs.readFileSync(__dirname + '/certs/cert.pem')
};

var server = https.createServer(options, app);

1 个答案:

答案 0 :(得分:0)

  

我在端口3000上运行我的express应用,并使用iptables将流量从80和443转发到我的应用(3000)。

根据您的代码,您的nodejs应用程序将处理https。它不会处理纯HTTP。但是通过将端口80简单转发到端口3000,普通的HTTP请求将发送到应用程序。

  

...然后我转到域时,遇到cloudflare 522错误

如果您只是“进入域” ,则默认协议为HTTP。这意味着您的浏览器将在端口80上发送HTTP请求到Cloudflare,然后该请求将转发到您的系统在端口80上的纯HTTP请求,在该系统中,您将把这个简单的HTTP请求转发到端口3000上的nodejs应用程序。仅此应用程序不能处理纯HTTP。相反,它期望使用HTTPS,这意味着它期望TLS握手(ClientHello)的开始,而不是纯HTTP请求。这可能会导致您看到错误,因为nodejs应用程序可能会等待预期的输入,而不会响应纯HTTP请求。

要解决此问题,您可以例如让nodejs应用程序在不同的端口as described here上侦听HTTP和HTTPS,然后将80重定向到http-listener,将443重定向到https-listener。