Ubuntu

暴露或監聽Google云實例上的 http 埠

  • October 2, 2020

我有一個Google云實例(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),但在Google云實例中它會產生錯誤消息:

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 時,請求超時。

有人可以幫我配置Google云實例,以便它可以在埠 80 或埠 8000 中執行嗎?

curl INTERNAL_IP的結果

curl: (7) Failed to connect to 10.142.0.5 port 80: Connection refused

在終端中列印 index.html 文件並curl -p admin:admin localhost:8000返回。curl -p admin:admin INTERNAL_IP:8000

看看這篇文章

低於 1024 的 TCP/IP 埠號的特殊之處在於普通使用者不允許在其上執行伺服器。這是一項安全功能,因為如果您在其中一個埠上連接到服務,您可以相當確定您擁有真實的東西,而不是某些黑客為您提供的假貨。

**80**要在沒有NGINX 反向代理**的埠上執行 Node.js 應用程序,**您應該首先以與埠相同的方式配置 GCP 防火牆8000,然後您應該從以下可能的解決方案中進行選擇:

  1. 使用authbind
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. 使用PM2authbind
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在出現任何問題時使用。

引用自:https://serverfault.com/questions/1035793