暴露或監聽Google云實例上的 http 埠
我有一個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
,然後您應該從以下可能的解決方案中進行選擇:
- 使用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%
為您的使用者名。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
在出現任何問題時使用。