Mejores prácticas al ejecutar Node.js con el puerto 80 (Ubuntu / Linode)

Estoy configurando mi primer servidor Node.js en un cloud Linux node y soy bastante nuevo en los detalles del Linux admin de Linux admin . (Por cierto, no estoy tratando de usar Apache al mismo tiempo).

Todo está instalado correctamente, pero descubrí que a menos que use el root login , no puedo escuchar en el port 80 con el nodo. Sin embargo, preferiría no ejecutarlo como root por razones de seguridad.

¿Cuál es la mejor práctica para:

  1. Establecer buenos permisos / usuario para el nodo para que sea seguro / sandboxed
  2. Permita que el puerto 80 se use dentro de estas restricciones.
  3. Inicie el nodo y ejecútelo automáticamente.
  4. Manejar la información de registro enviada a la consola.
  5. Cualquier otra preocupación general de mantenimiento y seguridad.

¿Debo reenviar el tráfico del puerto 80 a un puerto de escucha diferente?

Gracias

Puerto 80

Lo que hago en mis instancias en la nube es redirigir el puerto 80 al puerto 3000 con este comando:

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

Luego, ejecuto mi Node.js en el puerto 3000. Las solicitudes al puerto 80 se asignarán al puerto 3000.

También debe editar su archivo /etc/rc.local y agregar esa línea menos el sudo . Eso agregará la redirección cuando la máquina se inicie. No necesita sudo en /etc/rc.local porque los comandos allí se ejecutan como root cuando se inicia el sistema.

Registros

Utiliza el módulo forever para iniciar tu Node.js con. Se asegurará de que se reinicie si alguna vez falla y redirigirá los registros de la consola a un archivo.

Lanzamiento en arranque

Agregue su script de inicio Node.js al archivo que ha editado para la redirección de puerto, /etc/rc.local . Eso ejecutará el script de inicio de Node.js cuando se inicie el sistema.

Océano digital y otro VPS

Esto no solo se aplica a Linode, sino también a Digital Ocean, AWS EC2 y otros proveedores de VPS. Sin embargo, en los sistemas basados ​​en RedHat /etc/rc.local es /ect/rc.d/local .

Otorgar permiso de usuario seguro para usar el puerto 80

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

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

Mucha gente se queda estancada aquí, pero la solución es fácil. Hay algunas opciones, pero esta es la que 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á.

Verifique este enlace de referencia

Quite los privilegios de raíz después de vincular al puerto 80 (o 443).

Esto permite que el puerto 80/443 permanezca protegido, a la vez que le impide atender solicitudes como root:

 function drop_root() { process.setgid('nobody'); process.setuid('nobody'); } 

Un ejemplo de trabajo completo usando la función anterior:

 var process = require('process'); var http = require('http'); var server = http.createServer(function(req, res) { res.write("Success!"); res.end(); }); server.listen(80, null, null, function() { console.log('User ID:',process.getuid()+', Group ID:',process.getgid()); drop_root(); console.log('User ID:',process.getuid()+', Group ID:',process.getgid()); }); 

Ver más detalles en esta referencia completa .

Para el puerto 80 (que era la pregunta original), Daniel tiene toda la razón. Recientemente me mudé a https y tuve que cambiar de iptables a un ligero proxy nginx que administra los certificados SSL. Encontré una respuesta útil junto con una esencia de gabrielhpugliese sobre cómo manejar eso. Básicamente yo

  • Creó una solicitud de firma de certificado SSL (CSR) a través de OpenSSL

     openssl genrsa 2048 > private-key.pem openssl req -new -key private-key.pem -out csr.pem 
  • Obtuve el certificado real de uno de estos lugares (casualmente uso Comodo )
  • Instalado nginx
  • Cambió la location en /etc/nginx/conf.d/example_ssl.conf a

     location / { proxy_pass http://localhost:3000; proxy_set_header X-Real-IP $remote_addr; } 
  • Formateé el certificado para nginx anotando los certificados individuales juntos y vinculados a él en mi archivo nginx example_ssl.conf (y cosas sin comentarios, me deshice de ‘ejemplo’ en el nombre, …)

     ssl_certificate /etc/nginx/ssl/cert_bundle.cert; ssl_certificate_key /etc/nginx/ssl/private-key.pem; 

Con suerte, eso puede salvar a alguien más de algunos dolores de cabeza. Estoy seguro de que hay una manera pura de hacer esto, pero nginx fue rápido y funcionó.

¿Proporciona Linode alguna “pared frontal” o firewall donde debe abrir el puerto para la máquina? ¿Tal vez sea un buen lugar para encontrar una mejor solución que el enrutamiento en cada máquina? Cuando despliegue el servidor en Azure, debo definir los llamados puntos finales. El punto final contiene un puerto público, un puerto privado (en la máquina) y un protocolo (TCP / UDP). Por lo tanto, si está ejecutando la aplicación en el puerto 3000 en el servidor, se puede alcanzar en el puerto 80 y el enrutamiento se realiza por plataforma, no por máquina. También puedo establecer ACL en puntos finales.