我有一个谷歌云实例(Ubuntu 20.04),我试图在其中运行一个nodejs应用程序并将其公开到端口80。
这是我的 server.js 代码:
var express = require('express'),
app = express(),
http = require('http'),
httpServer = http.Server(app);
var basicAuth = require("express-basic-auth");
app.use(basicAuth({
users: { 'admin': 'admin' },
challenge: true
}));
app.use(express.static(__dirname + '/'));
app.get('/', function(req, res) {
res.sendfile(__dirname + '/index.html');
});
app.listen(80);
它在本地运行完美(例如在我的本地机器浏览器中 localhost:80)但在谷歌云实例中它会产生一条错误消息:
events.js:174
throw er; // Unhandled 'error' event
^
Error: listen EACCES: permission denied 0.0.0.0:80
at Server.setupListenHandle [as _listen2] (net.js:1263:19)
at listenInCluster (net.js:1328:12)
at Server.listen (net.js:1415:7)
at Function.listen (/home/user/development/node_modules/express/lib/application.js:618:24)
at Object.<anonymous> (/home/user/development/server.js:14:5)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
Emitted 'error' event at:
at emitErrorNT (net.js:1307:8)
at process._tickCallback (internal/process/next_tick.js:63:19)
at Function.Module.runMain (internal/modules/cjs/loader.js:834:11)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)
然后我尝试创建一条防火墙规则,以便我可以从此实例公开不同的端口。因此,我创建了一条防火墙规则,允许来自任何 IP(0.0.0.0/0)的连接访问 tcp:8000,并将此标记规则添加到实例并重新启动它。
现在我相应地更改了服务器以公开端口 8000:
var express = require('express'),
app = express(),
http = require('http'),
httpServer = http.Server(app);
var basicAuth = require("express-basic-auth");
app.use(basicAuth({
users: { 'admin': 'admin' },
challenge: true
}));
app.use(express.static(__dirname + '/'));
app.get('/', function(req, res) {
res.sendfile(__dirname + '/index.html');
});
app.listen(8000);
这次服务器在 Google 云实例中运行时没有任何错误消息,但是当我在浏览器中点击 public_ip:8000 时,请求超时了。
有人可以帮我配置谷歌云实例,以便它可以在端口 80 或端口 8000 上运行吗?
执行curl INTERNAL_IP
结果
curl: (7) Failed to connect to 10.142.0.5 port 80: Connection refused
执行curl -p admin:admin localhost:8000
并curl -p admin:admin INTERNAL_IP:8000
返回并在终端打印 index.html 文件。
答案1
看看这个文章:
低于 1024 的 TCP/IP 端口号比较特殊,普通用户不能在这些端口上运行服务器。这是一项安全功能,如果您连接到这些端口上的服务,您可以确信您使用的是真正的服务,而不是某些黑客为您设置的假服务。
在端口上运行 Node.js 应用程序 80
没有NGINX 反向代理你应该首先配置 GCP 防火墙与端口相同的方式8000
,然后您应该从以下可能的解决方案中进行选择:
- 使用授权绑定:
sudo apt update -y
sudo apt install -y authbind
sudo touch /etc/authbind/byport/80
sudo chown %user% /etc/authbind/byport/80
sudo chmod 755 /etc/authbind/byport/80
authbind node server.js
替换%user%
为您的用户名。
sudo apt update -y
sudo apt install -y authbind
sudo touch /etc/authbind/byport/80
sudo chown %user% /etc/authbind/byport/80
sudo chmod 755 /etc/authbind/byport/80
替换%user%
为将要运行的用户pm2
,并为运行 pm2 配置文件的用户添加别名,例如~/.bashrc
或~/.zshrc
(笔记您需要运行source ~/.bashrc
或source ~/.zshrc
之后立即运行):
+alias pm2='authbind --deep pm2'
然后运行:
pm2 update
并使用 pm2 尝试你的应用程序:
pm2 start app.js
- 使用iptables简单地重定向流量:
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8000
- 使用
libcap
到使所有节点程序能够绑定到任意端口低于 1024:
sudo setcap 'cap_net_bind_service=+ep' $(which node)
不要使用 root 权限运行你的应用程序:
$ sudo node app.js
或者
$ sudo su -
# node app.js
最好使用完整的地址路径,http://PUBLIC_IP:PORT
而不是仅仅PUBLIC_IP:PORT
为了应对任何问题。