Tenho um servidor Node.js configurado e estou tentando usar HTTPS com meu certificado Let's Encrypt no Apache. Aqui está o código relevante que configurei:
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')
}, ...
Quando tento iniciar o script, recebo este erro:
Error: EACCES: permission denied, open '/etc/letsencrypt/live/www.mysite.com/privkey.pem'
Isso ocorre porque apenas o proprietário root possui os diretórios e arquivos Let's Encrypt para o SSL, que é usado atualmente em meus mais de 30 sites regulares no Apache. Estou tentando configurar um aplicativo Node para um site. Meus arquivos de projeto node app.js são de propriedade de mysite1:mysite1 e sei que é mais seguro executar o aplicativo node como um usuário não root (como "mysite1").
Qual é a maneira correta de fazer meu Let's Encrypt HTTPS funcionar com segurança com o aplicativo Node.js (no Apache) sem precisar conceder permissões 755 ao meu diretório /etc/letsencrypt?
EDITAR - ESCLARECIMENTO:
Node.js e Apache estão rodando lado a lado. No meu arquivo virtualHost .conf do site, 443 DocumentRoot é /home/mysite1/mysite1.com , para o qual meu Let's Encrypt SSL foi instalado.
Meu aplicativo Node.js está configurado em /home/mysite1/app . No site, eu uso o socket.io como uma sala de bate-papo para todo o site e ele se conecta/funciona perfeitamente com o seguinte (se o aplicativo for iniciado como usuário root), nenhum ProxyPass é necessário:
<script src="//www.mysite1.com:3000/socket.io/socket.io.js"></script>
<script>var socket = io('https://www.mysite1.com:3000');</script>
Quando executo o aplicativo como um usuário não root (por motivos de segurança), o único erro que vejo é que meu aplicativo de nó apresenta um erro de permissão ao tentar acessar/configurar arquivos SSL. O que especificamente devo fazer, não estou muito claro como executar isso "por trás" do Apache, ou se existe uma solução mais simples?
Parece que deve haver uma solução mais simples, talvez o node.js seja executado como root para obter os dados SSL e fazer o servidor funcionar antes de entregá-lo ao usuário, como o Apache faz?
EDITAR 2:
Com base na sugestão de Michael e ezra-s, pesquisei no Google por algum tempo e mudei algumas coisas, mas não consigo fazer funcionar. No Apache, fiz algo assim:
<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>
Em meu arquivo de projeto node app.js, removi as opções require('https') e certificado e substituí-as pelo pacote "http" e tentei inicializar o script.
Em uma página do meu site, tenho scripts que tentam carregar o socket.io e conectar-se ao aplicativo do nó:
<script src="https://www.mysite1.com/node/socket.io/socket.io.js"></script>
<script>var socket = io('https://www.mysite1.com/node/');</script>
Quando carrego a página, ocorre um erro 500 e o script não carrega. O que devo mudar na minha configuração do Apache ou nos URLs do script? Nunca usei proxy com node antes, este é meu primeiro aplicativo de node.
SOLUÇÃO:
Eu descobri, era uma combinação de outras coisas que precisavam ser feitas envolvendo web sockets e javascript:
1) Apache Config para lidar com websocketshttps://stackoverflow.com/a/41685748/2317571
2) Configuração de conexão de soquete JavaScript para clientehttps://stackoverflow.com/questions/22919276/how-to-connect-socket-io-through-a-reverse-proxy
3) (dica bônus): Graças ao conselho de Michael e ezra-s por colocar o aplicativo node atrás do Apache, posso usar o firewall ufw e bloquear a porta 3000 do node/socket.io para localhost - uma porta a menos (e segurança buraco) aberto ao mundo. Esperamos que esta informação possa ajudar outra pessoa.
Responder1
1. Execute um aplicativo Node.js sozinho em uma porta.
2. Proxies reversos para ele.
Observação:A conexão entre o aplicativo Node.js e o Apache usará HTTP. No entanto, isso ocorrerá apenas no nível "localhost". Portanto, tudo ficará bem.
A configuração do 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>