Ich habe einen Node.js-Server eingerichtet und versuche, HTTPS mit meinem Let’s Encrypt-Zertifikat auf Apache zu verwenden. Hier ist der entsprechende Code, den ich eingerichtet habe:
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')
}, ...
Beim Versuch, das Skript zu starten, wird folgende Fehlermeldung angezeigt:
Error: EACCES: permission denied, open '/etc/letsencrypt/live/www.mysite.com/privkey.pem'
Dies liegt daran, dass nur der Root-Eigentümer die Let’s Encrypt-Verzeichnisse und -Dateien für das SSL besitzt, das derzeit für meine über 30 regulären Websites auf Apache verwendet wird. Ich versuche, eine Node-App für eine Website einzurichten. Meine Node-App.js-Projektdateien gehören mysite1:mysite1 und ich weiß, dass es sicherer sein soll, die Node-App als Nicht-Root-Benutzer (wie „mysite1“) auszuführen.
Wie kann ich dafür sorgen, dass mein Let’s Encrypt HTTPS sicher mit der Node.js-App (auf Apache) funktioniert, ohne meinem Verzeichnis /etc/letsencrypt die Berechtigung 755 erteilen zu müssen?
BEARBEITEN – ERKLÄRUNG:
Node.js und Apache laufen nebeneinander. In meiner virtualHost .conf-Datei für die Website ist 443 DocumentRoot /home/mysite1/mysite1.com, wofür mein Let’s Encrypt SSL installiert wurde.
Meine Node.js-App ist in /home/mysite1/app eingerichtet. Auf der Website verwende ich socket.io als seitenweiten Chatroom und die Verbindung/Funktioniert einwandfrei mit Folgendem (wenn die App als Root-Benutzer gestartet wird), kein ProxyPass erforderlich:
<script src="//www.mysite1.com:3000/socket.io/socket.io.js"></script>
<script>var socket = io('https://www.mysite1.com:3000');</script>
Wenn ich die App als Nicht-Root-Benutzer ausführe (aus Sicherheitsgründen), wird mir nur der Fehler angezeigt, dass meine Node-App beim Versuch, auf SSL-Dateien zuzugreifen/sie zu konfigurieren, einen Berechtigungsfehler aufweist. Was soll ich konkret tun? Mir ist nicht ganz klar, wie ich dies „hinter“ Apache ausführen kann oder ob es eine einfachere Lösung gibt?
Es scheint, als ob es eine einfachere Lösung geben muss. Vielleicht wird node.js als Root ausgeführt, um die SSL-Daten abzurufen und den Server zum Laufen zu bringen, bevor die Daten an den Benutzer übergeben werden, so wie es Apache macht?
BEARBEITEN 2:
Basierend auf dem Vorschlag von Michael und ezra-s habe ich eine Weile bei Google gesucht und ein paar Dinge geändert, aber es funktioniert nicht. In Apache habe ich so etwas gemacht:
<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>
In meiner Node-App.js-Projektdatei habe ich die Optionen require('https') und certificate entfernt und durch das Paket „http“ ersetzt und versucht, das Skript zu initialisieren.
Auf einer Seite meiner Website habe ich Skripte, die versuchen, socket.io zu laden und eine Verbindung mit der Node-App herzustellen:
<script src="https://www.mysite1.com/node/socket.io/socket.io.js"></script>
<script>var socket = io('https://www.mysite1.com/node/');</script>
Wenn ich die Seite lade, tritt ein 500-Fehler auf und das Skript wird nicht geladen. Was sollte ich an meiner Apache-Konfiguration oder den Skript-URLs ändern? Ich habe noch nie zuvor einen Proxy mit Node verwendet, dies ist meine erste Node-App.
LÖSUNG:
Ich habe es herausgefunden. Es war eine Kombination anderer Dinge, die im Zusammenhang mit WebSockets und JavaScript erledigt werden mussten:
1) Apache-Konfiguration für den Umgang mit WebSocketshttps://stackoverflow.com/a/41685748/2317571
2) JavaScript Socket Connection Config für Clienthttps://stackoverflow.com/questions/22919276/wie-verbinde-man-socket-io-durch-einen-reverse-proxy
3) (Bonus-Tipp): Dank der Tipps von Michael und ezra-s, die Node-App hinter Apache zu bringen, kann ich die UFW-Firewall verwenden und den Node/Socket.io-Port 3000 für den lokalen Host sperren – ein Port (und Sicherheitsloch) weniger, der für die Welt offen steht. Hoffentlich können diese Informationen jemand anderem helfen.
Antwort1
1. Führen Sie eine Node.js-App auf einem eigenen Port aus.
2. Reverse-Proxys dazu.
Notiz:Die Verbindung zwischen der Node.js-App und dem Apache wird HTTP verwenden. Sie wird jedoch nur auf der Ebene „localhost“ stattfinden. Daher wird es kein Problem sein.
Die VirtualHost-Konfiguration:
<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>