Linux 使用端口 80 运行 Node.js 的最佳实践(Ubuntu / Linode)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16573668/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best practices when running Node.js with port 80 (Ubuntu / Linode)
提问by Robotbugs
I am setting up my first Node.js
server on a cloud Linux node
and I am fairly new to the details of Linux admin
. (BTW I am not trying to use Apache at the same time.)
我正在 a 上设置我的第一台Node.js
服务器cloud Linux node
,我对Linux admin
. (顺便说一句,我不会同时尝试使用 Apache。)
Everything is installed correctly, but I found that unless I use the root login
, I am not able to listen on port 80
with node. However I would rather not run it as root for security reason.
一切都安装正确,但我发现除非我使用 ,否则我root login
无法使用 node.js 监听port 80
。但是,出于安全原因,我宁愿不以 root 身份运行它。
What is the best practice to:
什么是最佳实践:
- Set good permissions / user for node so that it is secure / sandboxed?
- Allow port 80 to be used within these constraints.
- Start up node and run it automatically.
- Handle log information sent to console.
- Any other general maintenance and security concerns.
- 为节点设置良好的权限/用户以使其安全/沙盒化?
- 允许在这些限制范围内使用端口 80。
- 启动节点并自动运行。
- 处理发送到控制台的日志信息。
- 任何其他一般维护和安全问题。
Should I be forwarding port 80 traffic to a different listening port?
我应该将端口 80 流量转发到不同的侦听端口吗?
Thanks
谢谢
采纳答案by Daniel
Port 80
80端口
What I do on my cloud instances is I redirect port 80 to port 3000 with this command:
我在云实例上所做的是使用以下命令将端口 80 重定向到端口 3000:
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3000
Then I launch my Node.js on port 3000. Requests to port 80 will get mapped to port 3000.
然后我在端口 3000 上启动我的 Node.js。对端口 80 的请求将被映射到端口 3000。
You should also edit your /etc/rc.local
file and add that line minus the sudo
. That will add the redirect when the machine boots up. You don't need sudo
in /etc/rc.local
because the commands there are run as root
when the system boots.
您还应该编辑您的/etc/rc.local
文件并添加该行减去sudo
. 这将在机器启动时添加重定向。您不需要sudo
in/etc/rc.local
因为那里的命令root
在系统启动时运行。
Logs
日志
Use the forevermodule to launch your Node.js with. It will make sure that it restarts if it ever crashes and it will redirect console logs to a file.
使用forever模块来启动你的Node.js。它将确保它在崩溃时重新启动,并将控制台日志重定向到一个文件。
Launch on Boot
开机启动
Add your Node.js start script to the file you edited for port redirection, /etc/rc.local
. That will run your Node.js launch script when the system starts.
将您的 Node.js 启动脚本添加到您为端口重定向编辑的文件中/etc/rc.local
。这将在系统启动时运行您的 Node.js 启动脚本。
Digital Ocean & other VPS
数字海洋及其他 VPS
This not only applies to Linode, but Digital Ocean, AWS EC2 and other VPS providers as well. However, on RedHat based systems /etc/rc.local
is /ect/rc.d/local
.
这不仅适用于 Linode,也适用于 Digital Ocean、AWS EC2 和其他 VPS 提供商。但是,在基于 RedHat 的系统上/etc/rc.local
是/ect/rc.d/local
.
回答by Nick Benes
For port 80 (which was the original question), Daniel is exactly right. I recently moved to https
and had to switch from iptables
to a light nginx proxy managing the SSL certs. I found a useful answeralong with a gistby gabrielhpuglieseon how to handle that. Basically I
对于端口 80(这是最初的问题),Daniel 是完全正确的。我最近搬到了管理 SSL 证书的轻型 nginx 代理,https
并且不得不切换iptables
到该代理。我发现了一个有用的答案与沿要点通过gabrielhpugliese如何处理这个问题。基本上我
Created an SSL Certificate Signing Request (CSR)via OpenSSL
openssl genrsa 2048 > private-key.pem openssl req -new -key private-key.pem -out csr.pem
- Got the actual cert from one of these places(I happened to use Comodo)
- Installed nginx
Changed the
location
in/etc/nginx/conf.d/example_ssl.conf
tolocation / { proxy_pass http://localhost:3000; proxy_set_header X-Real-IP $remote_addr; }
Formatted the cert for nginx by
cat
-ing the individual certs togetherand linked to it in my nginxexample_ssl.conf
file (and uncommented stuff, got rid of 'example' in the name,...)ssl_certificate /etc/nginx/ssl/cert_bundle.cert; ssl_certificate_key /etc/nginx/ssl/private-key.pem;
openssl genrsa 2048 > private-key.pem openssl req -new -key private-key.pem -out csr.pem
- 从这些地方之一获得实际证书(我碰巧使用Comodo)
- 安装了 nginx
改变了
location
在/etc/nginx/conf.d/example_ssl.conf
以location / { proxy_pass http://localhost:3000; proxy_set_header X-Real-IP $remote_addr; }
通过
cat
将各个证书组合在一起并在我的 nginxexample_ssl.conf
文件中链接到它来格式化 nginx 的证书(以及未注释的内容,去掉名称中的“示例”,...)ssl_certificate /etc/nginx/ssl/cert_bundle.cert; ssl_certificate_key /etc/nginx/ssl/private-key.pem;
Hopefully that can save someone else some headaches. I'm sure there's a pure-node way of doing this, but nginx was quick and it worked.
希望这可以为其他人省去一些麻烦。我确定有一种纯节点的方法可以做到这一点,但是 nginx 很快并且有效。
回答by Meet Mehta
Give Safe User Permission To Use Port 80
授予安全用户使用端口 80 的权限
Remember, we do NOT want to run your applications as the root user, but there is a hitch: your safe user does not have permission to use the default HTTP port (80). You goal is to be able to publish a website that visitors can use by navigating to an easy to use URL like http://ip:port/
请记住,我们不想以 root 用户身份运行您的应用程序,但有一个问题:您的安全用户没有使用默认 HTTP 端口 (80) 的权限。您的目标是能够发布一个网站,访问者可以通过导航到一个易于使用的 URL 来使用,例如http://ip:port/
Unfortunately, unless you sign on as root, you'll normally have to use a URL like http://ip:port
- where port number > 1024.
不幸的是,除非您以 root 身份登录,否则您通常必须使用类似http://ip:port
- 端口号 > 1024的 URL 。
A lot of people get stuck here, but the solution is easy. There a few options but this is the one I like. Type the following commands:
很多人被困在这里,但解决方案很简单。有几种选择,但这是我喜欢的一种。键入以下命令:
sudo apt-get install libcap2-bin
sudo setcap cap_net_bind_service=+ep `readlink -f \`which node\``
Now, when you tell a Node application that you want it to run on port 80, it will not complain.
现在,当您告诉 Node 应用程序您希望它在端口 80 上运行时,它不会抱怨。
Check this reference link
检查此参考链接
回答by slund
Drop root privileges after you bind to port 80 (or 443).
绑定到端口 80(或 443)后删除 root 权限。
This allows port 80/443 to remain protected, while still preventing you from serving requests as root:
这允许端口 80/443 保持受保护,同时仍然阻止您以 root 身份处理请求:
function drop_root() {
process.setgid('nobody');
process.setuid('nobody');
}
A full working example using the above function:
使用上述函数的完整工作示例:
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());
});
See more details at this full reference.
在此完整参考中查看更多详细信息。