Tengo un servidor Node.js configurado y estoy intentando usar HTTPS con mi certificado Let's Encrypt en Apache. Aquí está el código relevante que he configurado:
var fs = require('fs'),
https = require('https'),
express = require('express'),
options = {
key: fs.readFileSync('/etc/letsencrypt/live/www.mysite.com/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/www.mysite.com/fullchain.pem'),
ca: fs.readFileSync('/etc/letsencrypt/live/www.mysite.com/chain.pem')
}, ...
Cuando intento iniciar el script, aparece este error:
Error: EACCES: permission denied, open '/etc/letsencrypt/live/www.mysite.com/privkey.pem'
Esto se debe a que solo el propietario raíz posee los directorios y archivos de Let's Encrypt para SSL, que se usa actualmente con mis más de 30 sitios web habituales en Apache. Estoy intentando configurar una aplicación Node para un sitio web. Los archivos de mi proyecto node app.js son propiedad de mysite1:mysite1 y sé que se supone que es más seguro ejecutar la aplicación de nodo como usuario no root (como "mysite1").
¿Cuál es la forma correcta de hacer que mi Let's Encrypt HTTPS funcione de forma segura con la aplicación Node.js (en Apache) sin tener que otorgar permisos 755 a mi directorio /etc/letsencrypt?
EDITAR - ACLARACIÓN:
Node.js y Apache se ejecutan uno al lado del otro. En mi archivo virtualHost .conf para el sitio web, 443 DocumentRoot es /home/mysite1/mysite1.com, que es para lo que se instaló mi Let's Encrypt SSL.
Mi aplicación Node.js está configurada en /home/mysite1/app. En el sitio web, uso socket.io como sala de chat en todo el sitio y se conecta/funciona perfectamente bien con lo siguiente (si la aplicación se inicia como usuario root), no se requiere ProxyPass:
<script src="//www.mysite1.com:3000/socket.io/socket.io.js"></script>
<script>var socket = io('https://www.mysite1.com:3000');</script>
Cuando ejecuto la aplicación como usuario no root (por motivos de seguridad), el único error que veo es que mi aplicación de nodo tiene un error de permiso al intentar acceder/configurar archivos SSL. ¿Qué debo hacer específicamente? No tengo muy claro cómo ejecutar este Apache "detrás" o si existe una solución más sencilla.
Parece que debe haber una solución más simple, tal vez node.js se ejecuta como root para obtener los datos SSL y hacer que el servidor se ejecute antes de entregárselo al usuario, como lo hace Apache.
EDITAR 2:
Según la sugerencia de Michael y ezra-s, busqué en Google por un tiempo y cambié algunas cosas, pero no puedo hacerlo funcionar. En Apache, he hecho algo como esto:
<VirtualHost *:443>
ServerAlias mysite1.com
DocumentRoot /home/mysite1/mysite1.com
DirectoryIndex index.html index.php
<Directory /home/mysite1/mysite1.com>
.. web config stuff
</Directory>
ProxyRequests Off
ProxyPreserveHost On
ProxyVia Full
<Proxy *>
Require all granted
</Proxy>
<Location /node>
ProxyPass http://127.0.0.1:3000
ProxyPassReverse http://127.0.0.1:3000
</Location>
SSLEngine on
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/www.letshangout.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.letshangout.com/privkey.pem
</VirtualHost>
En mi archivo de proyecto node app.js, eliminé las opciones require('https') y certificado y las reemplacé con el paquete "http" e intenté inicializar el script.
En una página de mi sitio web, tengo scripts que intentan cargar socket.io y conectarse con la aplicación del nodo:
<script src="https://www.mysite1.com/node/socket.io/socket.io.js"></script>
<script>var socket = io('https://www.mysite1.com/node/');</script>
Cuando cargo la página, aparece un error 500 y el script no se carga. ¿Qué debo cambiar en mi configuración de Apache o en las URL del script? Nunca antes había usado proxy con nodo, esta es mi primera aplicación de nodo.
SOLUCIÓN:
Lo descubrí, era una combinación de otras cosas que debían hacerse relacionadas con sockets web y javascript:
1) Configuración de Apache para tratar con websocketshttps://stackoverflow.com/a/41685748/2317571
2) Configuración de conexión de socket JavaScript para el clientehttps://stackoverflow.com/questions/22919276/how-to-connect-socket-io-through-a-reverse-proxy
3) (consejo adicional): gracias al consejo de Michael y ezra-s por colocar la aplicación de nodo detrás de Apache, puedo usar el firewall ufw y bloquear el puerto 3000 de node/socket.io en localhost: un puerto menos (y seguridad). agujero) abierto al mundo. Esperemos que esta información pueda ayudar a alguien más.
Respuesta1
1. Ejecute una aplicación Node.js en un puerto por sí sola.
2. Invierta los poderes del mismo.
Nota:La conexión entre la aplicación Node.js y Apache utilizará HTTP. Sin embargo, sólo se llevará a cabo a nivel de "localhost". Por tanto, estará bien.
La configuración de VirtualHost:
<VirtualHost *:443>
ServerName nodeapp.com
ServerAdmin webmas@localhost
DocumentRoot /var/www/nodeapp
SSLEngine on
SSLCertificateFile /path/to/cert
SSLCertificateKeyFile /path/to/key
ProxyRequests off
ProxyPass "/" "http://127.0.0.1:node_app_port/"
ProxyPassReverse "/" "http://127.0.0.1:node_app_port/"
ErrorLog ${APACHE_LOG_DIR}/nodeapp_error.log
CustomLog ${APACHE_LOG_DIR}/nodeapp_access.log combined
</VirtualHost>