在 Google Cloud 实例上公开或监听 http 端口

在 Google Cloud 实例上公开或监听 http 端口

我有一个谷歌云实例(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:8000curl -p admin:admin INTERNAL_IP:8000返回并在终端打印 index.html 文件。

答案1

看看这个文章

低于 1024 的 TCP/IP 端口号比较特殊,普通用户不能在这些端口上运行服务器。这是一项安全功能,如果您连接到这些端口上的服务,您可以确信您使用的是真正的服务,而不是某些黑客为您设置的假服务。

在端口上运行 Node.js 应用程序 80没有NGINX 反向代理你应该首先配置 GCP 防火墙与端口相同的方式8000,然后您应该从以下可能的解决方案中进行选择:

  1. 使用授权绑定
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%为您的用户名。

  1. 使用PM2授权绑定
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 ~/.bashrcsource ~/.zshrc之后立即运行):

+alias pm2='authbind --deep pm2'

然后运行:

pm2 update

并使用 pm2 尝试你的应用程序:

pm2 start app.js
  1. 使用iptables简单地重定向流量:
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8000
  1. 使用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为了应对任何问题。

相关内容