Ошибка разрешения SSL: Node.js с HTTPS + Let's Encrypt SSL + Apache + Пользователь без прав root

Ошибка разрешения SSL: Node.js с HTTPS + Let's Encrypt SSL + Apache + Пользователь без прав root

У меня настроен сервер Node.js, и я пытаюсь использовать HTTPS с моим сертификатом Let's Encrypt на Apache. Вот соответствующий код, который я настроил:

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')
}, ...

При попытке запустить скрипт возникает следующая ошибка:

Error: EACCES: permission denied, open '/etc/letsencrypt/live/www.mysite.com/privkey.pem'

Это потому, что только владелец root владеет каталогами и файлами Let's Encrypt для SSL, который в настоящее время используется с моими 30+ обычными веб-сайтами на Apache. Я пытаюсь настроить приложение Node для одного веб-сайта. Мои файлы проекта node app.js принадлежат mysite1:mysite1, и я знаю, что должно быть безопаснее запускать приложение node как не-root пользователь (например, "mysite1").

Как правильно обеспечить безопасную работу моего Let's Encrypt HTTPS с приложением Node.js (на Apache) без предоставления моему каталогу /etc/letsencrypt прав 755?

ПРАВКА - УТОЧНЕНИЕ:

Node.js и Apache работают бок о бок. В моем файле virtualHost .conf для веб-сайта 443 DocumentRoot — это /home/mysite1/mysite1.com , для которого был установлен мой Let's Encrypt SSL.

Мое приложение Node.js настроено в /home/mysite1/app . На сайте я использую socket.io как чат-комнату для всего сайта, и он прекрасно подключается/работает со следующими (если приложение запущено как пользователь root), ProxyPass не требуется:

<script src="//www.mysite1.com:3000/socket.io/socket.io.js"></script>
<script>var socket = io('https://www.mysite1.com:3000');</script>

Когда я запускаю приложение как не-root пользователь (в целях безопасности), единственная ошибка, которую я вижу, это то, что у моего node app есть ошибка разрешения при попытке доступа/настройки файлов SSL. Что конкретно мне делать, я не очень понимаю, как запустить это "позади" Apache, или есть более простое решение?

Кажется, должно быть более простое решение, может быть, node.js запускается от имени root, чтобы получить данные SSL и запустить сервер, прежде чем передать их пользователю, как это делает Apache?

ПРАВКА 2:

Основываясь на предложении Майкла и ezra-s, я некоторое время искал в Google и изменил несколько вещей, но не могу заставить это работать. В Apache я сделал что-то вроде этого:

<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>

В моем файле проекта node app.js я удалил параметры require('https') и certificate и заменил их пакетом "http" и попытался инициализировать скрипт.

На странице моего веб-сайта есть скрипты, которые пытаются загрузить socket.io и подключиться к приложению Node:

<script src="https://www.mysite1.com/node/socket.io/socket.io.js"></script>
<script>var socket = io('https://www.mysite1.com/node/');</script>

При загрузке страницы возникает ошибка 500, и скрипт не загружается. Что мне следует изменить в конфигурации Apache или URL-адресах скрипта? Я никогда раньше не использовал прокси с node, это мое первое приложение node.

РЕШЕНИЕ:

Я понял, что это была комбинация других вещей, которые нужно было сделать, с использованием веб-сокетов и JavaScript:

1) Apache Config для работы с веб-сокетамиhttps://stackoverflow.com/a/41685748/2317571

2) Конфигурация соединения сокета JavaScript для клиентаhttps://stackoverflow.com/questions/22919276/how-to-connect-socket-io-through-a-reverse-proxy

3) (бонусный совет): Благодаря совету Майкла и ezra-s о том, как разместить приложение node за Apache, я могу использовать брандмауэр ufw и заблокировать порт node/socket.io 3000 на localhost — на один порт (и дыру в безопасности) меньше, открытый миру. Надеюсь, эта информация поможет кому-то еще.

решение1

1. Запустите приложение Node.js на отдельном порту.

2. Обратные прокси к нему.

Примечание:Соединение между приложением Node.js и Apache будет осуществляться по протоколу HTTP. Однако оно будет происходить только на уровне "localhost". Поэтому все будет в порядке.

Конфигурация виртуального хоста:

<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>

Связанный контент