nginx try_filesがSSLターミネーションロードバランサーの背後にある場合に間違ったスキームを使用してリダイレクトする(haproxy)


8

SSL終了を行うロードバランサーの背後でバックエンドとして実行されているnginx 1.6.2サーバーがあります。バックエンドサーバーへのすべての通信はHTTP経由で行われます。

何が起こっているかの図:

          /--http---> frontend:80  --\
client --+                            +--http---> backend:8000
          \--https--> frontend:443 --/

                      LOAD BALANCER                BACKENDS

テストのために、私は現時点で1つのバックエンドしか持っていません。ロードバランサーはHAProxy 1.5を実行します。

バックエンドのnginx構成のブロックにかなり典型的なtry_filesディレクティブがありますserver

server {
    server_name frontend;
    ...
    try_files $uri $uri/ =404;
    ...
}

現在、デフォルトで、末尾にスラッシュがないディレクトリにアクセスすると、たとえばhttps://frontend/somedir、nginxはHTTP 301リダイレクトをのような絶対URLに送信しようとしますhttp://frontend:8000/somedir/

nginxに8000のポート番号を省略させるには、を使用しport_in_redirect offます。

ただしhttp://、nginxが生成しているリダイレクトの最初にスキームを修正することはできません。私がnginxにできる最高のことは、SSLを効果的に取り除くことからhttps://frontend/somedirへのリダイレクトhttp://frontend/somedir/です!

ロードバランサーはX-Forwarded-Protoヘッダーを送信していますが、nginxがリダイレクトを作成するときにそれを参照する方法がありません。実際には、2012年の回答でnginxは完全にこれを行うことはできません。解決策はロードバランサーをnginxに置き換えることです。これは、スタックの大幅な変更を保証するのに些細なことです。

2012年以降、ここで何か変化はありますか?これらのリダイレクトをHAProxyレベルで書き直したくありません。Webアプリケーションからの実際の意図的なHTTPSからHTTPへのリダイレクトは、Location:応答ヘッダーのスキームを常に同じに書き換えると、「re-HTTPSed」になる可能性があります。リクエストが行われた。

編集:

以下は、nginxが絶対Location:URLを生成することを示す最小化された構成です。書き換えはないことに注意してください。

user nobody nobody;
worker_processes auto;
worker_rlimit_nofile 4096;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
    multi_accept on;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;

    # TODO: Tune fastcgi_buffers/other buffers

    # Configure keepalive connections
    keepalive_timeout 15;
    keepalive_requests 1000;

    # Hide server version.
    server_tokens off;

    # Do not allow any directory indexes anywhere.
    # This is the default, but it is here for extra paranoia.
    autoindex off;

    # gzip text content.
    gzip on;
    gzip_vary on;
    gzip_disable "msie6";
    gzip_comp_level 2;
    gzip_min_length 1024;
    gzip_types  text/css
                text/plain
                text/xml
                application/json
                application/javascript;

    server {
        listen 8000 default_server;

        root /usr/share/nginx/html;
        index index.html index.htm;

        server_name localhost;

        location / {
            try_files $uri $uri/ =404;
        }
    }
}

あなたはヘッダーを表示するためにカールを使用する場合と-のメモを、私は、ディレクトリを作成しているtestdirの下で/usr/share/nginx/html

[myuser@dev nginx]$ curl -i http://localhost:8000/testdir
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Thu, 26 Mar 2015 14:35:49 GMT
Content-Type: text/html
Content-Length: 178
Location: http://localhost:8000/testdir/
Connection: keep-alive

<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>

nginx wants to send an HTTP 301 redirect to an absolute URL-nginxは、明示的な書き換えルールがない限りそれを行いません-完全な設定を表示してください。
AD7six 2015年

この問題を説明するためだけに、構成を追加しました。明示的な書き換えは行いません。
mutron

1
Location:nginxは元のプロトコルが何であるかわからないため、ヘッダーのプロトコルを置き換えるようにバランサーを設定する必要があります。
Alexey Ten

2
@AlexeyTenは、それを回答として投稿して、承認できるようにしますか?私はnginxでこれを行う方法も見つけていないので、ロードバランサーでの変更は確かに唯一の方法のようです。
mutron

1
これはまだ最新のnginXリリースのバグです!誰かがすでにバグレポートがあるかどうか知っていますか?見つかりませんでした。
Roel van Duijnhoven、

回答:



-1

ロードバランサーに、次のようhttphttpsリクエストを書き換えるように指示する必要があります。

proxy_redirect http:// $scheme://;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.