L'app Node.js non può essere eseguita sulla porta 80 anche se nessun altro processo blocca la porta


94

Sto eseguendo un'istanza di Debian su Amazon EC2 con Node.js installato. Se eseguo il codice seguente:

http = require('http');

http.createServer(function (request, response){
  response.writeHead(200, {'Content-Type':'text/plain'});
  response.end('Hello World\n');
}).listen(80);
console.log("Running server at port 80");

Ottengo l'output di seguito che mi dice che c'è un altro processo in ascolto sulla porta 80:

Running server at port 80

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: listen EACCES
    at errnoException (net.js:901:11)
    at Server._listen2 (net.js:1020:19)
    at listen (net.js:1061:10)
    at Server.listen (net.js:1127:5)
    at Object.<anonymous> (/home/admin/nodetests/nodetest.js:6:4)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)

Ora, quando controllo per vedere se c'è un processo (come root nel caso in cui qualcosa sia nascosto) in ascolto sulla porta 80 usando:

netstat -tupln

Ottengo l'output seguente, che mi dice che non c'è niente in ascolto sulla porta 80:

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1667/sshd       
tcp6       0      0 :::22                   :::*                    LISTEN      1667/sshd

Dovrei notare che Debian ha la porta 80 aperta come regola in entrata se questo fa la differenza.

La mia domanda è: cosa sto facendo di sbagliato? Come mai non riesco a identificare il processo in ascolto sulla porta 80? Perché è bloccato in Debian? Quali passaggi devo eseguire per far funzionare correttamente il codice?

Risposte:


197

Il codice di errore EACCESindica che non hai le autorizzazioni appropriate per eseguire le applicazioni su quella porta. Su sistemi Linux, qualsiasi porta inferiore a 1024 richiede l'accesso come root.


5
quindi, sudo node myapp.js lo farà se si dispone dell'autorizzazione per utilizzare sudo (semplicemente aggiungendolo per qualsiasi principiante).
AlexMA

20
@AlexMA ma eseguire un server come root è un grande no no
Patrick Evans

1
Allora come esegui il nodo sulla porta 80? Dovresti semplicemente ... non usare un proxy?
AlexMA

9
@PatrickEvans Suppongo che la migliore pratica sarebbe quella di funzionare su una porta diversa e solo impostare una regola port-forwarding come accennato qui: stackoverflow.com/questions/16573668/...
AlexMA

73

Invece di eseguire sulla porta 80, puoi reindirizzare la porta 80 alla porta della tua applicazione (> 1024) usando

iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3000

Funzionerà se l'applicazione è in esecuzione sulla porta 3000.


1
fatto. Ho scoperto che devi essere root per eseguire iptables in una nuova installazione Debian, altrimenti $ PATH non punterà ad esso.
Brian Yeh,

Sì, questo era probabilmente il modo più semplice per farlo. Sono su Google Cloud Compute che mi ha dato problemi quando ho toccato la porta 80. È stato fantastico. Grazie.
Andy

Questa dovrebbe essere la soluzione accettata. L'esecuzione del server Web come sudo è pericoloso, in quanto potenzialmente fornisce l'accesso root a un utente malintenzionato in caso di vulnerabilità nell'applicazione; inoltre, se l'applicazione dovesse creare dei file, questi sarebbero inaccessibili agli altri utenti, facendoti usare sudoancora di più.
jesusiniesta

Non sono sicuro del perché, ma su Ubuntu 14.04 questo non ha funzionato per me. Ora uso il port forwarding tramite ssh, che è altrettanto facile. Ho pubblicato una risposta di seguito .
panepeter

19

Risposta breve: puoi consentire l'accesso del nodo a quella porta utilizzando:

setcap 'cap_net_bind_service=+ep' /path/to/nodejs

risposta lunga

Modificare:

Potrebbe non funzionare con le nuove versioni del nodo


quello ha funzionato. @LinuxMint - sudo setcap 'cap_net_bind_service = + ep' / usr / local / bin / node
Combina

A volte un aggiornamento cambierà il percorso della posizione in nodo e questo smetterà di funzionare. Quindi dovrai eseguirlo di nuovo per il nuovo percorso di node.
vapore l'

Sembra che questo non funzionerà più dopo la versione del nodo 8. github.com/nodejs/node/issues/22648
timaw

6

Nota che se hai in apacheesecuzione, puoi creare un proxy inverso su un vhost. Se il tuo nodo è in esecuzione sulla porta 8080:

<VirtualHost 127.0.0.1:80>
        ServerName myLocalServer

        ProxyPass        /  http://localhost:8080/
        ProxyPassReverse /  http://localhost:8080/
</VirtualHost>

Ovviamente, aggiungi il server a /etc/hosts:

127.0.0.1    myLocalServer

Dovrai abilitare i moduli apache pertinenti:

sudo a2enmod proxy_html
sudo a2enmod proxy_http
sudo a2enmod proxy_connect
sudo a2enmod proxy_ajp
sudo service apache2 restart

... e ora puoi connetterti a http://myLocalServer.


3

Per chi cerca una soluzione semplice e veloce per un ambiente di sviluppo , il port forwarding tramite ssh può essere una bella alternativa:

ssh -L 80:localhost:3000 yourusername@localhost -N

Questo inoltra la porta 80 su localhost alla porta 3000 su localhost.

Deve essere eseguito come root (porta privilegiata). Per cancellarlo, premi semplicemente ctrl-c nel terminale. (Puoi aggiungere il -fflag per eseguire il comando in background, ma poi devi trovarlo di nuovo per ucciderlo).

Questa soluzione richiede di avere un server ssh in esecuzione localmente . Può essere fatto rapidamente , ma tieni presente le implicazioni sulla sicurezza se sei su una rete condivisa. Potresti voler applicare almeno un certo livello di sicurezza aggiuntiva (disabilita password e accesso root).

Personalmente lo uso sempre e solo sulla mia macchina locale. Non sono sicuro di come influenzi la velocità di elaborazione delle tue richieste se lo esegui in produzione, forse qualcuno ha un'idea. Ad ogni modo, dovresti assicurarti che questo comando continui a funzionare tutto il tempo, il che introduce più mal di testa. Per gli ambienti di produzione , suggerisco di utilizzare un proxy inverso come nginx .


2

la risposta dell'esacianuro è giusta. ma c'è qualche soluzione per far funzionare questo?

la risposta è si.

Come?

è possibile utilizzare, reverse proxyad esempio, eseguire una nginx reverse proxyporta on 80e passare il proxy alla destinazione ip:portche il nodo lo utilizza.

puoi impostarlo usando docker containerche rende la vita ancora più facile. questa è la build ufficiale di nginx nel docker hub che puoi estrarre.

ci sono ancora più vantaggi nell'utilizzo reverse proxyche puoi google.


0

Ho lo stesso errore e ho provato a eseguire la mia applicazione usando sudo e ha funzionato per me.

senza sudo

mansi@mansi:~/NodePractice$ node myFirst.js 
events.js:141
      throw er; // Unhandled 'error' event
      ^

Error: listen EACCES 0.0.0.0:80
    at Object.exports._errnoException (util.js:870:11)
    at exports._exceptionWithHostPort (util.js:893:20)
    at Server._listen2 (net.js:1224:19)
    at listen (net.js:1273:10)
    at Server.listen (net.js:1369:5)
    at Object.<anonymous> (/home/mansi/NodePractice/myFirst.js:6:4)
    at Module._compile (module.js:410:26)
    at Object.Module._extensions..js (module.js:417:10)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)

e con sudo

mansi@mansi:~/NodePractice$ sudo node myFirst.js 
^C

... che è esattamente quello che non vuoi fare. Crea problemi di sicurezza.
bvdb

-1

L'utilizzo della PORTA 80 richiede alcune autorizzazioni speciali. L'utilizzo sudoprima di eseguire l'istruzione dell'app ha risolto il mio problema. ad esempio, se stai usando npm per eseguire la tua app, puoi digitaresudo npm start


1
Questa risposta non aggiunge nulla per rispondere a contenuti già forniti da altri. Rispondi solo se stai aggiungendo ulteriori informazioni.
Brian Yeh

-2

Il codice di errore EACCESindica che non disponi delle autorizzazioni appropriate per eseguire le applicazioni su quella porta. Su sistemi Linux, qualsiasi porta inferiore a 1024 richiede l'accesso come root.

Eseguire il programma con sudopermision. Eseguire il sudo sucomando prima di eseguire il programma.


Vedi i commenti del post sotto la risposta agli esacianidi. Grazie.
Brian Yeh
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.