Node.js https服务器:无法侦听端口443 - 为什么?

时间:2014-10-26 23:09:48

标签: javascript node.js ssl https amazon-ec2

我是第一次在Node中创建一个HTTPS服务器,而代码(见下文)适用于像6643这样的随机端口,但是在端口443上,它不会起作用。我收到这个错误:

[Debug][Server]: Initialized...
[Debug][Control Center]: Application initialized...

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: listen EACCES
    at errnoException (net.js:904:11)
    at Server._listen2 (net.js:1023:19)
    at listen (net.js:1064:10)
    at Server.listen (net.js:1138:5)
    at Object.module.exports.router (/home/ec2-user/Officeball/Versions/officeball_v0.0.5/server/custom_modules/server.js:52:5)
    at Object.<anonymous> (/home/ec2-user/Officeball/Versions/officeball_v0.0.5/server/control_center.js:15:59)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)

这是在Amazon Linux EC2服务器上。我的理解是,一旦我将域名的DNS A名称记录设置为服务器的IP,当用户搜索https://mydomain.com时,浏览器将查找我的服务器&#39;在端口443处的IP,它应该是HTTPS流量的标准端口。

所以我的理解是我需要通过端口443提供https内容。

我做错了什么?


这是我的服务器代码:

control_center.js(init)

/* Control Center */

//DEFINE GLOBALS

preloaded = {};

//GET DIRECT WORKING PATH

var dirPath = process.cwd();

//REQUIRE CUSTOM MODULES 

var debug = new (require(dirPath + 
        "/custom_modules/debug"))("Control Center");
var socket = require(dirPath + 
        "/custom_modules/socket")(4546);

// ! this is the relevant line
var server = require(dirPath + "/custom_modules/server").router(443);

//APP INITIALIZE

debug.log("Application initialized...");

server.js

/* Server */

//REQUIRE NPM MODULES

var fs      = require('fs'), 
    https   = require('https'), 
    url     = require('url'), 
    path    = require('path');

//GET DIRECT WORKING PATH

var dirPath = process.cwd();

//REQUIRE CUSTOM MODULES

//Snip!

var debug = new (require(dirPath + 
        "/custom_modules/debug"))("Server");

//Preload requests

var preload = require(dirPath + 
        '/custom_modules/preload').init();

//INIT MODULE 

debug.log("Initialized...");

//DEFINE MODULE VARIABLES

var options = {
  key: fs.readFileSync('SSL/evisiion_private_key.pem'),
  cert: fs.readFileSync('SSL/evisiion_ssl_cert.pem')
};

//LISTEN FOR PATH REQUESTS

//route requests to server
module.exports.router = function(port) {
    https.createServer(options, function(req, res) {

        //Snip!

    }).listen(port);
};

1 个答案:

答案 0 :(得分:26)

在Linux上(我相信,大多数其他类Unix操作系统),服务必须以root身份运行才能绑定到编号小于1024的端口。

我刚刚在我躺在的Node应用程序上验证了它,当我将端口从5000更改为443时,我看到完全相同的错误,行相同的行禁止文件路径。

在开发中,大多数人会在更高编号的端口(例如8080)上运行开发服务器。在生产中,您可能希望使用适当的Web服务器(如Nginx)来提供静态内容并将其他所有内容反向代理到您的节点应用程序,这使它不再是一个问题,因为Nginx可以非常愉快地以root身份运行。

编辑:由于您的用例需要提供一些静态内容,因此您可能希望使用Web服务器(如Nginx或Apache)来处理静态文件,并将代理反向代理到另一个端口以获取动态内容。使用Nginx进行反向代理非常简单 - 这是一个示例配置文件:

server {
    listen 443;
    server_name example.com;
    client_max_body_size 50M;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location /static {
        root /var/www/mysite;
    }

    location / {
        proxy_pass http://127.0.0.1:8000;
    }
}

这假设您的Web应用程序可以在端口443上访问,并且在端口8000上运行。如果该位置与/ static文件夹匹配,则从/ var / www / mysite / static提供。否则,Nginx将其交给端口8000上正在运行的应用程序,该应用程序可能是Node.js应用程序,也可能是Python应用程序,或者其他任何内容。

这也非常巧妙地解决了您的问题,因为应用程序可以在端口443上访问,而无需实际绑定到该端口。