プロキシ経由のNginxリダイレクト、URLの書き換えと保存


71

Nginxでは、次のようにURLをリダイレクトしようとしました。

http://example.com/some/path -> http://192.168.1.24

ユーザーはブラウザに元のURLを表示したままです。ユーザーがリダイレクトされたら、へのリンクをクリックするとします。/section/index.htmlリダイレクトにつながるリクエストを作成するようにしたいと思います。

http://example.com/some/path/section/index.html -> http://192.168.1.24/section/index.html

再び元のURLを保持します。

私たちの試みには、プロキシと書き換えルールを使用したさまざまなソリューションが関係しており、ソリューションに最も近い構成を示しています(これはWebサーバーのWebサーバー構成であることに注意してくださいexample.com)。ただし、これにはまだ2つの問題があります。

  • Webサーバーhttp://192.168.1.24が受信した要求URLに含まれ/some/pathているため、必要なページの提供に失敗するため、書き換えは適切に実行されません。
  • ページが提供された後にリンクにカーソルを合わせると/some/path、URLに表示されません

    server {
        listen          80;
        server_name     www.example.com;
    
        location /some/path/ {
            proxy_pass http://192.168.1.24;
            proxy_redirect http://www.example.com/some/path http://192.168.1.24;
            proxy_set_header Host $host;
        }
    
        location / {
            index index.html;
            root  /var/www/example.com/htdocs;
        }
    }
    

でウェブサーバーの設定を変更するだけのソリューションを探していますexample.com。構成を変更することもできます192.168.1.24(Nginxも)が、アクセスをプロキシする数百の異なるサーバーに対してこのセットアップを繰り返す必要があるため、これを試して回避したいと思いますexample.com

回答:


59

まず、rootロケーションブロック内でディレクティブを使用しないでください。これは悪い習慣です。この場合、それは重要ではありません。

2つ目のロケーションブロックを追加してみてください。

location ~ /some/path/(?<section>.+)/index.html {
    proxy_pass http://192.168.1.24/$section/index.html;
    proxy_set_header Host $host;
}

これは、/ some / path /の後とindex.htmlの前の部分を$ section変数にキャプチャし、proxy_pass宛先を設定するために使用されます。必要に応じて、正規表現をより具体的にすることができます。


1
返信が遅くなりましたことをお-び申し上げます。これは私たちが探しているものを達成することに非常に近いものです。唯一の欠点は、ターゲットページが提供されると、ブラウザ内のリンクのURLに「/ some / path /」が含まれないことです。つまり、ユーザーがそれらをクリックしても機能しません。これを克服する方法を考え出すことができれば、私はこの答えを更新して受け入れます。
robjohncox 14

8
ブラウザに表示されるリンクは、192.168.1.24サーバーで実行されているソフトウェアによって生成されます。目的を達成するには、そのソフトウェアを変更する必要があります。
テロキルカネン14

ロケーションブロック内のルートに関する警告に従っているかどうかわかりません。nginxのドキュメントを読むと、それが正しい方法です。すべての場所の外部にデフォルトのルートを持たないことから悪い習慣を警告します。nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/...
男のmograbi

まあ、ブロックroot内で使用しないという経験則がある方が簡単locationです。そうすれば、デフォルトの場所で予期しない動作が発生することはありません。root各場所のデフォルトを変更する必要がある場合にのみ、それを使用できます。
テロキルカネン

1
名前として$ hostを受け取るとはどういう意味ですか?送信された正確なHTTPヘッダーとは何ですか?
テロキルカネン

65

proxy_passディレクティブでURI部分を使用する必要があります。また、proxy_redirectディレクティブの順序引数を混同しており、おそらくまったく必要ないでしょう。Nginxには、このディレクティブの適切なデフォルトがあります。

この場合、locationブロックは非常に簡単です。

location /some/path/ {
    proxy_pass http://192.168.1.24/;
    # note this slash  -----------^
    proxy_set_header Host $host;
}

1
返事が遅れて申し訳ありません-私はこれを試してみましたが、残念ながらユースケースではうまくいきません。問題は、ターゲットサーバーでリクエストが行われたとき/some/path/に、URL の一部が有効なURLではないリクエストに保存されることです(これを削除するには、URLも書き換える必要があります)。
robjohncox 14

@robjohncox正確に何を試しましたか?
アレクセイ10

9
スラッシュは私のためのトリックをしました。これで、mydomain.com /
some

7
この応答で「#スラッシュに注意してください」というコメントに賛成票を投じることはできますか?そのコメントに3つの歓声!
8one6

これがすべての人にとってどのように機能しているかわからない。これは私が達成しようとしていることです。ただし、ユーザーがローカルサービスの192.168.1.24/loginなどにリダイレクトするリンクをクリックすると、mydomain.com
some / path / login

4

次の構成を使用/some/path/して、フロントエンドと/バックエンドの間で100%のシームレスなマッピングを行うことができます。

これは、404 Not Found正しいHTTP Refererヘッダーがブラウザーによって送信される場合、エラーを生成する絶対パスもシームレスに処理する唯一の答えであることに注意してください。(これは高価であるだけでなく、デフォルトでコンパイルされない追加モジュールなしではサポートされません)。

location /some/path/ {
    proxy_pass http://192.168.1.24/; # note the trailing slash!
}
location / {
    error_page 404 = @404;
    return 404; # this would normally be `try_files` first
}
location @404 {
    add_header Vary Referer; # sadly, no effect on 404
    if ($http_referer ~ ://[^/]*(/some/path|/the/other)/) {
        return 302 $1$uri;
    }
    return 404 "Not Found\n";
}

あなたは見つけることができ、完全な概念実証し、最小限の生存-製品https://github.com/cnst/StackOverflow.cnst.nginx.confのリポジトリを。

すべてのエッジケースが動作しているように見えることを確認するためのテストを実行します。

curl -v -H 'Referer: http://example.su/some/path/page.html' localhost:6586/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location
> GET /and/more.gif HTTP/1.1
> Referer: http://example.su/some/path/page.html
< HTTP/1.1 302 Moved Temporarily
< Location: http://localhost:6586/some/path/and/more.gif
< Vary: Referer

curl -v localhost:6586/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location
> GET /and/more.gif HTTP/1.1
< HTTP/1.1 404 Not Found

curl -v localhost:6586/some/path/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location -e uri
> GET /some/path/and/more.gif HTTP/1.1
< HTTP/1.1 200 OK
request_uri:    /and/more.gif

あなたがマップする異なるパスの多くを持っている場合は、PSは、その代わりに正規表現の比較を行うの$http_refererifの中location @404には、グローバル・ベースを使用する場合がありますmap代わりにディレクティブを。

またproxy_passlocationに含まれるスラッシュと末尾のスラッシュは、関連する回答に従って非常に重要であることに注意してください。

参照:


2

そのスラッシュがnginxプロキシされたジェンキンに追加されると、「リバースプロキシのセットアップが壊れているように見える」というエラーが表示されます。

proxy_pass          http://localhost:8080/;

Remove this -----------------------------^

読むべき

proxy_pass          http://localhost:8080;

これはOPの質問が関連しているものではなく、言及されている問題のいずれも解決するとは思わない。
コリーロビンソン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.