Javascript Node.js https服务器:Can';我听不到443端口-为什么?

Javascript Node.js https服务器:Can';我听不到443端口-为什么?,javascript,node.js,ssl,https,amazon-ec2,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

我第一次在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)
server.js

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

我刚刚在我使用的一个节点应用程序上验证了它,当我将端口从5000更改为443时,我看到了完全相同的错误,一行接一行地删除了文件路径

在开发中,大多数人将在编号更高的端口(如8080)上运行dev服务器。在生产环境中,您可能希望使用合适的web服务器(如Nginx)来提供静态内容,并将其他所有内容反向代理到您的节点应用程序,这使得问题变得不那么严重,因为Nginx可以作为root用户非常愉快地运行

编辑:由于您的用例需要提供一些静态内容,那么您可能希望使用诸如Nginx或Apache之类的web服务器来处理静态文件,并将代理反向到动态内容的另一个端口。使用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上访问,而无需实际绑定到该端口


应该说,一般来说,以root用户身份运行这样的服务不是一个好主意。您将为可能存在漏洞的应用程序以及您拉入的任何NPM模块提供root访问权限。例如,将它放在后面,Nginx将意味着您不需要以root用户身份运行它,Nginx是可靠的、经过良好测试的,并且具有可靠的性能和缓存功能。此外,Nginx通常会更快地提供静态内容,尤其是。

可能不是代码,请看一看。@BrendanAshworth,当它如此简单以至于令人痛苦时……我知道的唯一原因是因为我以前回答过同样的问题:)如果这个答案没有解决可iptable解决方案的问题,允许1024以下的端口在不运行root时运行,那么它也可能与root用户权限有关。还有一个几乎重复的问题和答案。你是对的,只是加入了这个神奇的词,它马上就起作用了。不得不爱上sudo@jt0dd-在root访问下运行web服务器通常是一种不好的做法,因为它会增加您可能遇到的安全漏洞的数量。请参阅我对您的问题的评论中的两篇文章,了解在低端口上侦听而不以root身份运行节点进程的其他方法。我个人正在使用iptable解决方案。@jfriend00比我快!iptables解决方案是一个很好的解决方案,只要您不需要提供任何静态文件。如果你这样做了,我认为最好像我提到的那样-使用Nginx为他们服务,并将所有其他内容反向代理到Node.js应用程序运行的端口。@jt0dd好吧,像Apache和Nginx这样的web服务器是可靠的,广泛使用的产品可能比我们大多数人自己能够创建的任何定制解决方案表现得更好、更安全。Nginx通常被认为比Apache更快地提供静态内容,这使它非常适合这个用例。它还通过允许您在所需的端口上运行Nginx很好地解决了这个问题。Nginx很容易配置-我将在我的answer.IMO中添加一个示例配置,如果您实际拥有需要额外的web服务器层来服务静态文件的数据,您应该只增加设置的复杂性。我有一个不需要它的站点(节点本身就可以正常工作),所以在这种情况下,越简单越好。OP应该保持简单,除非实际需要更复杂的东西。iptables解决方案解决了没有root权限的端口问题。
/* 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);
};
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;
    }
}