0

我使用 建立了一个express项目express-generator,现在我正在尝试将其转换为使用 cloudflare SSL Certificateover https

我在 port 上运行我的 express 应用程序443

但是,当我然后转到域时,我得到 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);
4

1 回答 1

0

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

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

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

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

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

于 2019-01-03T21:56:53.317 回答