使用端口80(Ubuntu / Linode)运行Node.js的最佳实践


260

我在上设置了我的第一台Node.js服务器,cloud Linux node而我对的细节还很陌生Linux admin。(顺便说一句,我不想​​同时使用Apache。)

一切都已正确安装,但我发现除非使用,否则root login无法监听port 80node。但是出于安全原因,我宁愿不以root用户身份运行它。

最佳做法是:

  1. 为节点设置良好的权限/用户,使其安全/沙盒化?
  2. 允许在这些限制内使用端口80。
  3. 启动节点并自动运行它。
  4. 处理发送到控制台的日志信息。
  5. 任何其他常规维护和安全问题。

我应该将端口80流量转发到其他监听端口吗?

谢谢

Answers:


532

港口80

我在云实例上执行的操作是使用以下命令将端口80重定向到端口3000:

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3000

然后,我在端口3000上启动Node.js。对端口80的请求将映射到端口3000。

您还应该编辑/etc/rc.local文件并添加减去的那一行sudo。这将在计算机启动时添加重定向。您不需要sudo/etc/rc.local因为其中的命令是root在系统引导时运行的。

日志

使用forever模块启动您的Node.js。如果崩溃,它将确保重新启动,并将控制台日志重定向到文件。

开机启动

将您的Node.js启动脚本添加到您为端口重定向编辑的文件中/etc/rc.local。系统启动时,它将运行您的Node.js启动脚本。

Digital Ocean和其他VPS

这不仅适用于Linode,而且适用于Digital Ocean,AWS EC2和其他VPS提供商。但是,基于RedHat的系统/etc/rc.local/ect/rc.d/local


3
谢谢您的回答,非常准确。
Robotbugs

21
顺便说一句,在Ubuntu上,它是/etc/rc.local
kehers

12
对于虚拟专用服务器,通常会出现“ -i eth0”标志。根据需要更换eth0。
JHAWN 2014年

7
如果我将Node.js启动脚本添加到中/etc/rc.local,它是否将root在系统启动时执行?这将破坏端口80重定向的目的。
jamix 2014年

4
请注意,要使端口重定向正常工作,目标端口也需要在防火墙上启用。WRT在启动时启动节点实例,我们仅使用发行版的init脚本/ systemd文件即可允许您指定用户。
bk138 2014年

116

授予安全用户使用端口80的权限

请记住,我们不希望以root用户身份运行您的应用程序,但是有一个麻烦:您的安全用户没有使用默认HTTP端口(80)的权限。您的目标是通过导航到易于使用的网址(例如,http://ip:port/

不幸的是,除非您以root用户身份登录,否则通常必须使用类似http://ip:port- 的URL ,其中端口号> 1024。

很多人被困在这里,但是解决方案很容易。有几种选择,但这是我喜欢的选择。键入以下命令:

sudo apt-get install libcap2-bin
sudo setcap cap_net_bind_service=+ep `readlink -f \`which node\``

现在,当您告诉Node应用程序您希望它在端口80上运行时,它不会抱怨。

检查此参考链接


9
这是更好,更简单的答案。
凯尔·查达

2
此外,添加详细的解答这里stackoverflow.com/questions/23281895/...
相约梅塔

1
像NGINX这样的Web服务器如何在端口80上运行?它会做类似的事情吗?
埃里克·安德鲁·刘易斯

1
@EricAndrewLewis:我会说这取决于。当您以非root用户模式运行服务器时,将显示此错误。如果您以root用户身份运行Nginx服务器,该怎么办!另外,如果以普通用户身份运行并出现错误。运行以上命令以提供访问该端口的安全权限。另请参阅stackoverflow.com/questions/31369480/...
相约梅塔

16

绑定到端口80(或443)后,请放弃root特权。

这可以使端口80/443保持受保护的状态,同时仍然阻止您以root身份服务请求:

function drop_root() {
    process.setgid('nobody');
    process.setuid('nobody');
}

使用上述功能的完整工作示例:

var process = require('process');
var http = require('http');
var server = http.createServer(function(req, res) {
    res.write("Success!");
    res.end();
});

server.listen(80, null, null, function() {
    console.log('User ID:',process.getuid()+', Group ID:',process.getgid());
    drop_root();
    console.log('User ID:',process.getuid()+', Group ID:',process.getgid());
});

有关更多信息,请参见此完整参考


9

对于端口80(这是最初的问题),Daniel完全正确。我最近搬到了https并且不得不从iptables管理SSL证书的轻量级Nginx代理切换到了。我发现了一个有用的答案与沿要点通过gabrielhpugliese如何处理这个问题。基本上我

希望这可以减轻别人的麻烦。我敢肯定有一种纯节点的方式可以做到这一点,但是nginx很快并且有效。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.