web-dev-qa-db-ja.com

SSL権限エラー:HTTPSを使用したNode.js + 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ディレクトリとファイルを所有しているのはルート所有者だけだからです。 Nodeアプリを1つのWebサイトに設定しようとしています。私のノードapp.jsプロジェクトファイルはmysite1:mysite1が所有しており、ノードアプリをroot以外のユーザー( "mysite1"など)。

/ 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に設定されています。ウェブサイトでは、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>

(セキュリティ上の理由から)root以外のユーザーとしてアプリを実行すると、ノードアプリに表示される唯一のエラーは、SSLファイルにアクセス/構成しようとする権限エラーです。具体的にどうすればよいですか、この「背後」のApacheを実行する方法があまり明確ではないのですか、それともより簡単な解決策があるのですか?

Apacheのように、SSLデータを取得してサーバーを実行する前にnode.jsをrootとして実行してユーザーに渡す前に、もっと簡単な解決策が必要なようです。

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

ノードのapp.jsプロジェクトファイルで、require( 'https')および証明書オプションを削除し、「http」パッケージに置き換えて、スクリプトを初期化しようとしました。

私のウェブサイトのページに、socket.ioをロードしてノードアプリと接続しようとするスクリプトがあります。

<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で何を変更する必要がありますか?以前にノードでプロキシを使用したことがありません。これが私の最初のノードアプリです。

解決策:

私はそれを理解しました、それはウェブソケットとJavaScriptを含む必要がある他のことの組み合わせでした:

1)WebSocketを処理するためのApache構成 https://stackoverflow.com/a/41685748/2317571

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

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

2
peppy

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>
2
Alex Lo