O aplicativo Node.js não pode ser executado na porta 80, embora não haja outro processo bloqueando a porta

94

Estou executando uma instância do Debian no Amazon EC2 com Node.js instalado. Se eu executar o código abaixo:

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");

Recebo a saída abaixo que me diz que há outro processo escutando na 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)

Agora, quando verifico se há um processo (como root, caso algo esteja oculto) escutando na porta 80 usando:

netstat -tupln

Recebo a saída abaixo, que me diz que não há nada escutando na 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

Devo observar que o debian tem a porta 80 aberta como uma regra de entrada, se isso fizer diferença.

Minha pergunta é: o que estou fazendo de errado? Por que não consigo identificar o processo ouvindo a porta 80? Por que está bloqueado no Debian? Que etapas devo seguir para fazer o código funcionar corretamente?

Brian Yeh
fonte

Respostas:

197

O código de erro EACCESsignifica que você não tem as permissões adequadas para executar aplicativos nessa porta. Em sistemas Linux, qualquer porta abaixo de 1024 requer acesso root.

hexacianida
fonte
5
assim, sudo node myapp.js fará isso se você tiver autorização para usar sudo (apenas acrescentando-o para qualquer iniciante).
AlexMA
20
@AlexMA, mas executar um servidor como root é um grande não, não
Patrick Evans
1
Então, como você executa o nó na porta 80? Você deveria apenas ... não e usar um proxy?
AlexMA,
9
@PatrickEvans Suponho que a prática recomendada seria executar em uma porta diferente e apenas configurar uma regra de encaminhamento de porta conforme mencionado aqui: stackoverflow.com/questions/16573668/…
AlexMA
73

Em vez de executar na porta 80, você pode redirecionar a porta 80 para a porta do seu aplicativo (> 1024) usando

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

Isso funcionará se seu aplicativo estiver sendo executado na porta 3000.

Kamrul
fonte
1
fez isso. Descobriu que você tem que ser root para executar iptables em uma instalação nova do debian, caso contrário $ PATH não apontará para ele.
Brian Yeh
Sim, esta foi provavelmente a maneira mais fácil de fazer isso. Estou no Google Cloud Compute, o que me deu problemas ao tocar na porta 80. Isso foi ótimo. Obrigado.
Andy
Esta deve ser a solução aceita. Executar o servidor da web como sudo é perigoso, podendo dar a um invasor acesso root se houver alguma vulnerabilidade no aplicativo; além disso, se o aplicativo criasse algum arquivo, ele ficaria inacessível para outros usuários, fazendo com que você o usasse sudoainda mais.
jesusiniesta,
Não sei por que, mas no Ubuntu 14.04 isso não funcionou para mim. Agora eu uso o encaminhamento de porta via ssh, que é tão fácil quanto. Eu postei uma resposta abaixo .
panepeter de
19

Resposta curta: você pode permitir o acesso do nó a essa porta usando:

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

resposta longa

Editar:

Pode não funcionar em novas versões de nó

Reut Sharabani
fonte
isso funcionou. @LinuxMint - sudo setcap 'cap_net_bind_service = + ep' / usr / local / bin / node
Combine
Às vezes, uma atualização altera o caminho do local para o nó e isso para de funcionar. Portanto, você precisará executá-lo novamente para o novo caminho para o nó.
movido a vapor de
Parece que isso não funcionará mais após a versão do node 8. github.com/nodejs/node/issues/22648
timaw
6

Observe que, se estiver apacheexecutando, você pode criar um proxy reverso em um vhost. Se o seu nó estiver em execução na porta 8080:

<VirtualHost 127.0.0.1:80>
        ServerName myLocalServer

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

Claro, adicione servidor a /etc/hosts:

127.0.0.1    myLocalServer

Você precisará habilitar os módulos relevantes do apache:

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

... e agora você pode se conectar a http://myLocalServer.

Redsandro
fonte
3

Para quem procura uma solução rápida e fácil para um ambiente de desenvolvimento , o encaminhamento de porta via ssh pode ser uma boa alternativa:

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

Isso encaminha a porta 80 no localhost para a porta 3000 no localhost.

Ele precisa ser executado como root (porta privilegiada). Para cancelar, simplesmente pressione ctrl-c no terminal. (Você pode adicionar o-f sinalizador para que o comando seja executado em segundo plano, mas então você precisa encontrá-lo novamente para eliminá-lo).

Esta solução requer que você tenha um servidor ssh rodando localmente . Isso pode ser feito rapidamente , mas tenha em mente as implicações de segurança se você estiver em uma rede compartilhada. Você pode querer aplicar pelo menos algum nível de segurança adicional (desabilitar senha e login de root).

Eu pessoalmente só uso isso na minha máquina local. Não tenho certeza de como isso afeta a velocidade de processamento de suas solicitações se você executar isso na produção, talvez alguém tenha uma ideia. De qualquer forma, você precisaria ter certeza de que esse comando continue em execução o tempo todo, o que apresenta mais dores de cabeça. Para ambientes de produção , sugiro usar um proxy reverso como o nginx .

panéter
fonte
2

a resposta do hexacianeto está certa. mas existe alguma solução para fazer isso funcionar?

a resposta é sim.

como?

você pode usar um, reverse proxypor exemplo, executar uma nginx reverse proxyporta 80e passar o proxy para o destinoip:port que o nó usa.

você pode configurar isso usando o docker containerque torna a vida ainda mais fácil. esta é a compilação oficial do nginx no hub do docker que você pode puxar.

há ainda mais benefícios em usar do reverse proxyque você pode pesquisar no Google.

Ali_Hr
fonte
0

Eu obtive o mesmo erro e tentei executar meu aplicativo usando o sudo e funcionou para mim.

sem 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 com sudo

mansi@mansi:~/NodePractice$ sudo node myFirst.js 
^C
Parth Pachchigar
fonte
... que é exatamente o que você não quer fazer. Isso cria problemas de segurança.
bvdb
-1

O uso da PORT 80 requer algumas permissões especiais. Usar sudoo demonstrativo antes de executar o aplicativo resolveu meu problema. por exemplo, se estiver usando npm para executar seu aplicativo, você pode digitarsudo npm start

webcrawler
fonte
1
Esta resposta não acrescenta nada ao conteúdo já fornecido por outros. Responda apenas se você estiver adicionando informações adicionais.
Brian Yeh
-2

O código de erro EACCESsignifica que você não tem as permissões adequadas para executar aplicativos nessa porta. Em sistemas Linux, qualquer porta abaixo de 1024 requer acesso root.

Execute o programa com sudopermissão. Execute o sudo sucomando antes de executar o programa.

akshith ranjan
fonte
Veja os comentários da postagem sob a resposta de hexacianetos. Obrigado.
Brian Yeh