Error de Node.js EACCES al escuchar en la mayoría de los puertos

250

Estoy probando una aplicación (espero que se ejecute en heroku, pero también tengo problemas a nivel local). Me da un error EACCES cuando ejecuta http.Server.listen (), pero solo ocurre en algunos puertos.

Entonces, localmente estoy ejecutando:

joe@joebuntu:~$ node
> var h = require('http').createServer();
> h.listen(900);
Error: EACCES, Permission denied
    at Server._doListen (net.js:1062:5)
    at net.js:1033:14
    at Object.lookup (dns.js:132:45)
    at Server.listen (net.js:1027:20)
    at [object Context]:1:3
    at Interface.<anonymous> (repl.js:150:22)
    at Interface.emit (events.js:42:17)
    at Interface._onLine (readline.js:132:10)
    at Interface._line (readline.js:387:8)
    at Interface._ttyWrite (readline.js:564:14)

No tengo nada ejecutándose en el puerto 900 (ni en ninguno de los otros 20 puertos que he probado), así que esto debería funcionar. Lo extraño es que se hace el trabajo en algunos puertos. Por ejemplo, el puerto 3000 funciona perfectamente.

¿Qué causaría esto?

Actualización 1:

Me di cuenta de que en mi computadora local, el error EACCES viene porque tengo que ejecutar el nodo como root para vincularme a esos puertos determinados. No sé por qué sucede esto, pero usar sudo lo soluciona. Sin embargo, esto no explica cómo lo arreglaría en Heroku. No hay forma de ejecutar como root en Heroku, entonces, ¿cómo puedo escuchar en el puerto 80?

jwegner
fuente
23
Los puertos menos 1024 tradicionalmente requieren permisos elevados. En Heroku no escuchas el puerto 80, escuchas el puerto que te dicen a través de las variables de entorno y dejas que su capa de enrutamiento maneje el enlace del puerto 80 en el borde.
Mâtt Frëëman
Su actualización 1 me ayudó. 'sudo node myporgram.js' lo hizo correr.
Sabre

Respuestas:

352

Ejecutando en su estación de trabajo

Como regla general, los procesos que se ejecutan sin privilegios de root no pueden vincularse a puertos inferiores a 1024.

Por lo tanto, pruebe con un puerto superior o ejecute con privilegios elevados a través de sudo. Puede degradar los privilegios después de haberse vinculado al puerto bajo utilizando process.setgidy process.setuid.

Corriendo en heroku

Al ejecutar sus aplicaciones en heroku, debe usar el puerto como se especifica en la variable de entorno PORT.

Ver http://devcenter.heroku.com/articles/node-js

const server = require('http').createServer();
const port = process.env.PORT || 3000;

server.listen(port, () => console.log(`Listening on ${port}`));
Ben Taber
fuente
3
¿Significa esto que tengo que usar el puerto provisto por Heroku, y luego harán algo de magia detrás de escena para transferir eso al puerto 80? ¿Qué sucede si quiero ejecutar algo que no esté en el puerto 80?
jwegner
12
Si. Solo puede escuchar el puerto que le indicamos en $ PORT Nos encargamos de enrutar 80 o 443 a su puerto. El puerto real cambia todo el tiempo a medida que movemos su dinamómetro. En este momento, solo admitimos enrutamiento público de 80 y 443.
Será
@ Will, ¿hay alguna posibilidad de que esa restricción se levante? Específicamente, ¿poder escuchar en puertos que no sean 80 o 443? Es un conjunto bastante restrictivo, considerando todas las cosas.
ghayes
2
¿Por qué quieres que tu aplicación se ejecute en un puerto diferente a http y https?
Será el
1
@ ¿Me gustaría alojar un servidor de juegos simple en Heroku? La unidad necesita transferirse a crossdomain.xmltravés del puerto 843.
polkovnikov.ph
178

El usuario no privilegiado (no root) no puede abrir un socket de escucha en puertos inferiores a 1024.

usuario1303768
fuente
55
Upvoted: esta es una buena regla general, pero hay excepciones a esto, por ejemplo, 'capacidades' en Linux.
mikemaccana
3
Me acabas de salvar horas de depuración. No sabía sobre eso.
Malharhak
66
Sin embargo, no me gusta esto, no quiero tener que hacerlo sudocuando ejecuto un servidor expreso usando el nodo (en realidad, trago). Así que no tiene sentido
blamb
esta pieza de sabiduría
mauris
44
@blamb Luego use la solución MeetMehta ; ^)
ruffin
107

Consulte este enlace de referencia :

Dar permiso de usuario seguro para usar el puerto 80

Recuerde, NO queremos ejecutar sus aplicaciones como usuario root, pero hay un problema: su usuario seguro no tiene permiso para usar el puerto HTTP predeterminado (80). Su objetivo es poder publicar un sitio web que los visitantes puedan usar navegando a una URL fácil de usar como http://ip:port/

Desafortunadamente, a menos que inicie sesión como root, normalmente tendrá que usar una URL como http://ip:port, donde el número de puerto> 1024.

Muchas personas se quedan atrapadas aquí, pero la solución es fácil. Hay algunas opciones, pero esta es la que más me gusta. Escriba los siguientes comandos:

sudo apt-get install libcap2-bin
sudo setcap cap_net_bind_service=+ep `readlink -f \`which node\``

Ahora, cuando le dice a una aplicación Node que desea que se ejecute en el puerto 80, no se quejará.

Conoce a mehta
fuente
55
Esta es definitivamente la mejor solución.
Mark Lagendijk
1
@ MarkLagendijk: Gracias Mark. También hice la misma pregunta por error y publiqué una respuesta detallada aquí stackoverflow.com/questions/23281895/… . Siéntase libre de editarlo también.
Conoce a Mehta el
66
por qué no es esta la respuesta 👍
KhaledMohamedP
@KhaledMohamedP: Me alegra que haya ayudado :)
Conoce a Mehta el
Quién dice que esto todavía no funciona con el módulo pm2. Mata tu pm2 usando pm2 killy vuelve a crearlo .
Prasanth Jaya
10

Otro enfoque es hacer la redirección de puertos:

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 900 -j REDIRECT --to-port 3000

Y ejecute su servidor en> 1024 puerto:

require('http').createServer().listen(3000);

ps lo mismo podría hacerse para el puerto https (443) por cierto.

once
fuente
1
¡Gracias Gracias! Esto me ahorró una hora de depuración para puertos seguros, otra hora para la redirección SSL, y también me permitió restringir la visibilidad de un servidor de desarrollo en AWS Lightstail (que no permite el ajuste fino de las solicitudes por dirección IP).
miguelmorin
3

Significa que el nodo no puede escuchar en el puerto definido. Cámbielo a algo así como 1234 o 2000 o 3000 y reinicie su servidor.

Mark Karwowski
fuente
3

¡¡DIOS MIO!! En mi caso, estaba haciendo en ....listen(ip, port)lugar de ...listen(port, ip)y eso estaba arrojando el mensaje de error:Error: listen EACCES localhost

Estaba usando números de puerto> = 3000 e incluso probé con acceso de administrador. Nada funcionó. Luego, con una mirada más cercana, noté el problema. ¡Lo cambié ...listen(port, ip)y todo comenzó a funcionar bien!

Simplemente llamando esto en caso de que sea útil para otra persona ...

Dilip Muthukurussimana
fuente
¡Gracias! Yo tuve el mismo problema. Estoy acostumbrado a todas las otras API que usan nombre de host, puerto.
David
Tuve este problema cuando intenté ejecutar la imagen del acoplador Wekan. Lo resolví usando este consejo. Gracias.
Ângelo Polotto
@ dilip-muthukurussimana ¿Pretendía tener ....listen(ip, port)en su respuesta (con cuatro .)? Me tomó un minuto darme cuenta de que estabas hablando del orden de los argumentos debido a eso.
bschlueter
Sí, me refería solo al orden de los argumentos. Los PLS no ponen ....(cuatro puntos) allí, lo que pensé que era obvio.
Dilip Muthukurussimana
2

Recibí este error en mi Mac porque ejecutó el servidor apache de forma predeterminada usando el mismo puerto que el servidor del nodo que en mi caso era el puerto 80. Todo lo que tuve que hacer es detenerlo con sudo apachectl stop

Espero que esto ayude a alguien.

mabounassif
fuente
2

También recibí este error en mi Mac. Utilizo npm run devpara ejecutar mi aplicación Nodejs en Windows y funciona bien. Pero recibí este error en mi mac - error given was: Error: bind EACCES null:80.

Una forma de resolver esto es ejecutarlo con acceso root. Puede usar sudo npm run devy necesitará que ingrese su contraseña.

En general, es preferible servir su aplicación en un puerto no privilegiado, como 3000, que funcionará sin permisos de root.

referencia: error de Node.js EACCES al escuchar en el puerto http 80 (permiso denegado)

ZILONG PAN
fuente
2

Tuve un problema similar que negaba ejecutar en el puerto 8080, pero también cualquier otro.

Resulta que fue porque el env.localarchivo que leyó contenía comentarios después de los nombres de las variables como:

PORT=8080 # The port the server runs at

Y lo interpretó así, tratando de usar el puerto " 8080 # The port the server runs at", que obviamente es un puerto no válido (-1). Eliminar los comentarios lo resolvió por completo.

Usando Windows 10 y Git Bash por cierto.


Sé que no es exactamente el problema descrito aquí, pero podría ayudar a alguien por ahí. Aterricé en esta pregunta buscando el problema para mi respuesta, así que ... ¿tal vez?

Fusseldieb
fuente
Sí, he experimentado esto. Los comentarios después de los valores en archivos .env pueden causar esto.
Danoz
1

Recuerde que si usa sudo para enlazar con el puerto 80 y está usando las variables env PORT & NODE_ENV, debe reexportar esos vars ya que ahora está en el perfil raíz y no en su perfil de usuario. Entonces, para que esto funcione en mi Mac, hice lo siguiente:

sudo su
export NODE_ENV=production
export PORT=80
docpad run
Sean
fuente
1

esto sucede si el puerto en el que está intentando alojar localmente está protegido por puerto

Jasper Smith
fuente
1

Prueba authbind:

http://manpages.ubuntu.com/manpages/hardy/man1/authbind.1.html

Después de la instalación, puede agregar un archivo con el nombre del número de puerto que desea usar en la siguiente carpeta: / etc / authbind / byport /

Dele 500 permisos usando chmod y cambie la propiedad al usuario con el que desea ejecutar el programa.

Después de eso, haz "authbind node ..." como ese usuario en tu proyecto.

DraughtGlobe
fuente
1

Mi error se resolvió simplemente cambiando el número de puerto en server.js Especialmente en esta línea

const port = process.env.PORT || 8085;

Cambié mi número de puerto a 8085 de 8080.

Espero eso ayude.

Alok Ranjan
fuente
0

Después de probar muchas formas diferentes, la reinstalación de IIS en mis ventanas resolvió el problema.

JaulaE
fuente
0

Mi error se resuelve usando (en Windows)

app.set('PORT', 4000 || process.env.PORT);

app.listen(app.get('PORT'), <IP4 address> , () => {
    console.log("Server is running at " + app.get('PORT'));
});

Permita que la aplicación NodeJS acceda a la red en el Firewall de Windows.

Prathamesh Más
fuente
0

reiniciar no fue suficiente! La única forma de resolver el problema es la siguiente:

Tienes que matar el servicio que se ejecuta en ese puerto.

en cmd, ejecútelo como administrador, luego escriba: netstat -aon | encontrar / i "escuchando"

luego obtendrá una lista con el servicio activo, buscará el puerto que se ejecuta en 4200 y usará la identificación del proceso, que es la última columna para eliminarlo

: taskkill / F / PID 2652

Krebto
fuente