SSL 権限エラー: HTTPS を使用した Node.js + Let's Encrypt SSL + Apache + 非ルート ユーザー

SSL 権限エラー: HTTPS を使用した Node.js + Let's Encrypt SSL + Apache + 非ルート ユーザー

Node.js サーバーをセットアップし、Apache で Let's Encrypt 証明書を使用して HTTPS を使用しようとしています。セットアップした関連コードは次のとおりです。

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'

これは、現在 Apache 上の 30 を超える通常の Web サイトで使用されている SSL 用の Let's Encrypt ディレクトリとファイルを所有しているのはルート所有者のみであるためです。1 つの Web サイトに Node App を設定しようとしています。私の node app.js プロジェクト ファイルは mysite1:mysite1 によって所有されており、非ルート ユーザー (「mysite1」など) として node app を実行する方が安全であることはわかっています。

/etc/letsencrypt ディレクトリに 755 権限を与えずに、Let's Encrypt HTTPS を Node.js アプリ (Apache 上) で安全に動作させる適切な方法は何ですか?

編集 - 明確化:

Node.js と Apache は並行して実行されています。Web サイトの virtualHost .conf ファイルでは、443 DocumentRoot は /home/mysite1/mysite1.com であり、これは Let's Encrypt SSL がインストールされた場所です。

私の Node.js アプリは /home/mysite1/app に設定されています。Web サイトでは、サイト全体のチャット ルームとして socket.io を使用しており、次のように接続/正常に動作します (アプリがルート ユーザーとして起動されている場合)。ProxyPass は必要ありません。

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

セキュリティ上の理由から、非ルート ユーザーとしてアプリを実行すると、ノード アプリが SSL ファイルにアクセス/構成しようとしているときに権限エラーが発生するというエラーのみが表示されます。具体的に何をすればよいのでしょうか。Apache の背後でこれを実行するにはどうすればよいですか。または、もっと簡単な解決策はありますか。

もっと簡単な解決策があるように思えます。Apache のように、node.js を root として実行して SSL データを取得し、サーバーを実行してからユーザーに渡すというのはどうでしょうか?

編集2:

Michael と 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') と証明書オプションを削除し、それを "http" パッケージに置き換えて、スクリプトの初期化を試みました。

私の Web サイトのページには、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 で何を変更すればよいですか? これまでノードでプロキシを使用したことはありません。これが初めてのノード アプリです。

解決:

私はそれを理解しました。それは、Web ソケットと JavaScript に関連して実行する必要のある他のことの組み合わせでした。

1) Webソケットを扱うためのApache Confighttps://stackoverflow.com/a/41685748/2317571

2) クライアントのJavaScriptソケット接続設定https://stackoverflow.com/questions/22919276/how-to-connect-socket-io-through-a-reverse-proxy

3) (ボーナス ヒント): Michael と ezra-s のアドバイスのおかげで、Apache の背後にノード アプリを配置できるようになりました。これにより、ufw ファイアウォールを使用して、node/socket.io ポート 3000 を localhost にロックダウンできるようになりました。これにより、世界に公開されるポート (およびセキュリティ ホール) が 1 つ減ります。この情報が他の誰かの役に立つことを願っています。

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

関連情報