web-dev-qa-db-ja.com

Apacheの前のリバースプロキシとしてのNGINXは、SSLがオンになっていると機能しません

私はそこにあるフォーラムのすべての投稿、チュートリアル、コメントを読みましたが、SSLがNginxサーバーブロックで有効になると、Nginxプロキシを正しく機能させることができません。

Apacheは、通常のアクセスとSSLアクセスの両方のために仮想ホストで完全にセットアップされています。 Apacheは、ports.confでポート8081をリッスンしています。

NameVirtualHost *:8081
Listen 8081

<IfModule ssl_module>
        Listen 443
</IfModule>

<IfModule mod_gnutls.c>
        Listen 443
</IfModule>

私のSSLApache仮想ホストは次のとおりです。

Nginxをオンにし、次の構成(以下を参照)のようにssl設定をコメントアウトすると、SSLバージョンと非SSLバージョンの両方のサイトに正しくアクセスできるため、すべてが正常に機能します。

    server {
        listen 80;
  #      listen 443 ssl;
        server_name foobar.net;

   # ssl on;
   #     ssl_certificate /etc/letsencrypt/live/foobar.net/fullchain.pem;
   #     ssl_certificate_key /etc/letsencrypt/live/foobar.net/privkey.pem;

        location / {
            proxy_pass http://104.236.224.53:8081;
            proxy_set_header Host $Host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }

上記のファイルを変更し、サーバーブロックのオプションのコメントを外してSSLをオンにすると、ポート443でNginxとApacheの間に競合があるように見えますか?

更新され、コメント化されていないサーバーブロックは次のようになります。

    server {
        listen 80;
        listen 443 ssl;
        server_name foobar.net;

    ssl on;
        ssl_certificate /etc/letsencrypt/live/foobar.net/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/foobar.net/privkey.pem;

        location / {
            proxy_pass http://104.236.224.53:8081;
            proxy_set_header Host $Host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }

Nginxを開始しようとすると、次のエラーが返されます。

 nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Mon 2017-02-20 18:35:20 EST; 16s ago
  Process: 14505 ExecStop=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid (code=exited, status=0/SUCCESS
  Process: 14475 ExecReload=/usr/sbin/nginx -g daemon on; master_process on; -s reload (code=exited, status=0/SUCCESS)
  Process: 14671 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=1/FAILURE)
  Process: 14652 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
 Main PID: 14328 (code=exited, status=0/SUCCESS)

Feb 20 18:35:18 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use)
Feb 20 18:35:18 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use)
Feb 20 18:35:19 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use)
Feb 20 18:35:19 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use)
Feb 20 18:35:20 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use)
Feb 20 18:35:20 foo.foobar.net nginx[14671]: nginx: [emerg] still could not bind()
Feb 20 18:35:20 foo.foobar.net systemd[1]: nginx.service: Control process exited, code=exited status=1
Feb 20 18:35:20 foo.foobar.net systemd[1]: Failed to start A high performance web server and a reverse proxy server.
Feb 20 18:35:20 foo.foobar.net systemd[1]: nginx.service: Unit entered failed state.
Feb 20 18:35:20 foo.foobar.net systemd[1]: nginx.service: Failed with result 'exit-code'.

NginxからApacheにSSLを適切に渡すための実装でここに欠けているものは何ですか?


編集1:@Timの良い点に対処するために、すべてのリクエストをNginxで処理するように主な意図を編集します。

  • 私の当初の目的は、DockerコンテナーにあるDiscourseを、Apacheが既にメインサーバーとして使用されていたのと同じマシンにインストールすることでした。
  • Discourseを適切に実行するにはポート80にアクセスする必要があるため、すべての着信要求を処理するためにnginxを前にリバースプロキシとして設定し、それに応じて渡すようにすることをお勧めします。
  • 背面のApacheを使用してすべての動的コンテンツを処理し、nginxに静的ビットを処理させたいと思います。そのためには、インスタンスごとにApacheで仮想hoを確立する必要があることを理解しています。httpリクエストとhttpsリクエストの両方です。 たぶん私はこの点で間違っているのでしょうか?

DigitalOcean:オプションのステップ9に早送りします。 によって提案された構成に従いました。

論理的にはこの時点で、nginxから渡されるリクエストをポート8081でリッスンしているApacheにHTTPホストがあるのと同じように、同じことを行うことができ、ポート8081をリッスンし、Apacheに正常にヘッダーを渡すことができるHTTPSホストもあると想定しました残りを処理します。エラー400: the plain http request was sent to https portに悩まされていたため、この実装は完全には機能しませんでした

さらに一歩進んで、Apache HTTPとHTTPSの両方がポート8081をリッスンしているため、割り当てられたApache HTTPをポート8081に、HTTPSをポート1443に割り当てると、すべてがシームレスに機能すると思いました。この実装でHTTPS経由でワープレスのブログにアクセスしようとするとエラーが発生するため、これも完全には機能しません

Your browser sent a request that this server could not understand.
Reason: You're speaking plain HTTP to an SSL-enabled server port.
Instead use the HTTPS scheme to access this URL, please.

多くの人がDigitalOceanが適切に機能するように実装を提案しているように見えますが、この時点で私は文字通りアイデアから新鮮です。 :-/

2
Robert

あなたから受け取ったすべてのフィードバックのおかげで、ようやく実装ができたようです。ありがとう@AlexeyTenおよび@Tim

  • まず、ドメインfoobar.netのApacheでhttpsvhostを無効にしましたSudo a2dissite foobar.net.cong

  • Apache ports.confファイルを編集してポート8081のみをリッスンし、ポート443でリッスンを削除しました。

NameVirtualHost *:8081

Listen 8081
  • 最後に、nginxサーバーブロックを編集してポート443をリッスンし、必ずコメントアウトしましたssl on。そうしないとうまくいきませんでした。
> server {
>     listen 80;
>     listen 443 ssl;
>     server_name foobar.net;
> 
>   # ssl on;
>     ssl_certificate /etc/letsencrypt/live/foobar.net/fullchain.pem;
>     ssl_certificate_key /etc/letsencrypt/live/foobar.net/privkey.pem;
> 
>     location / {
>         proxy_pass http://104.236.224.53:8081;
>         proxy_set_header Host $Host;
>         proxy_set_header X-Real-IP $remote_addr;
>         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
>         proxy_set_header X-Forwarded-Proto $scheme;
>     } }

この実装は正常に機能し、php処理をApacheにシームレスに引き継ぐようです。

0
Robert

ApacheとNginxの両方にポート443でリッスンするように指示しましたが、同じマシンであると思います。 1つのポートでリッスンできるアプリケーションは1つだけです。

おそらく、質問を編集して、なぜNginxとApacheの両方を使用するのかを教えてください。どちらでもほとんどのことができます。そうすれば、もっと役立つアドバイスが得られるでしょう。

2
Tim

@Robert、ソリューションは機能しましたが、ブラウザにSSL証明書をロードしませんでした。

私の解決策は以下の通りです:

Apacheのデフォルトポートを80から8080に変更します

ApacheのデフォルトSSLポートを443から444に変更します

以下は私のngnix設定です:

server 
{

listen 80;

    server_name servername.com;

location / {

        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $Host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        expires off;
    }
}


server {

    listen 443 ssl http2;
    server_name servername.com;
    ssl on;
    ssl_certificate /etc/nginx/ssl/keyname.crt;
    ssl_certificate_key /etc/nginx/ssl/private/keyname.key;

location / {

        proxy_pass https://127.0.0.1:444;
        proxy_set_header Host $Host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        expires off;
    }
}

注意:

  1. sSLの場合、proxy_passをhttpsに変更する必要があります。
  2. NginxがApacheのリバースプロキシとして機能している場合、これは正常に機能します。
  3. SSL構成の443ではなく444を含めるようにApachevhostを変更する必要があります。
  4. SSL用にApacheのports.confを444に構成する
0
yogi