web-dev-qa-db-ja.com

プロキシ用のApacheRewriteRule

使用されているサブドメインに基づいて動作するWebアプリケーション(ClockingIT)がインストールされています。 SSLを使用したいので、ワイルドカード証明書がないため、これはあまり便利ではありません:-)そこで、Apacheのmod_proxyおよびmod_rewrite機能を使用することを考えました。

より正確には、URL Xttps://example.com/cit/(外部)にXttp://test.example.com:3000 /(内部)の内容を表示したいと思います。

これが私の設定です:

   <VirtualHost *:443>
     ServerName example.com

     (SSL setup, etc)

     SSLProxyEngine On
     UseCanonicalName Off
     ProxyRequests Off   
     ProxyPreserveHost Off # or On, makes no difference

     RewriteEngine On
     RewriteRule      ^/cit$         Xttp://test.example.com:3000/ [P,NC]
     RewriteRule      ^/cit/(.*)$    Xttp://test.example.com:3000/$1 [P,NC]
     ProxyPassReverse /cit/          Xttp://test.example.com:3000/

test.example.comはDNSサーバーで定義されていませんが、/ etc/hostsで127.0.0.1にマップするように設定されています。サーバーで「w3mXttp://test.example.com:3000 /」を実行すると、正しいWebページが表示されます。ただし、デスクトップのブラウザで https://example.com/cit/ にアクセスすると、正しいWebページが表示されません。 Webアプリはリクエストを受信しますが、リクエストはexample.comドメインに対するものであり、意図されたサブドメインの「テスト」コンテンツではなくデフォルトページを提供しているようです。ドキュメントによると、プロキシはtest.example.comドメインを通過しないようですが、どういうわけか通過しないようです。 RewriteRuleの代わりにProxyPassディレクティブも試しましたが、同じ結果になりました。

足りないものはありますか?

(関連する場合、ClockingITはRuby on Rails Mongrel経由で提供されるアプリケーション)

追伸:s/Xttp/http/g-ServerFaultは、私の質問でhttpコロンスラッシュスラッシュを複数回使用することを好みませんでした;-)

編集:

Tcpflowを使用してトラフィックデータを確認した後、問題はApacheがポート3000に以下を送信することであるようです。

GET / HTTP/1.1
Host: test.example.com:3000
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
Cookie: _session_id=99f5f70d684c2186e64c5ebb8f69d574
Via: 1.1 example.com
X-Forwarded-For: 1.2.3.4
X-Forwarded-Host: example.com
X-Forwarded-Server: example.com

「telnetlocalhost3000」を使用して上記を貼り付けると、リダイレクトが表示されます。これを繰り返してX-Forwarded-Host:行を省略すると、目的のページが表示されます。したがって、私のセットアップは実際には機能していますが、ClockingITはX-Forwarded-Hostの値に基づいて決定を下しているようです。これが含まれないようにする方法はありますか?

4
Daniel

これに噛まれました。それは本当に迷惑な奇妙なものです。

Apacheのmod_proxyは、すべてのアウトバウンド要求にヘッダーx-forwarded-Hostを追加します。 HeaderRequest unset x-forwarded-Host、ProxyVia、ProxyPreseveHostでは無効にできません。私が見つけることができる他のものもありません。

Railsがそのヘッダーを確認すると、itを使用してHTTP応答のLocation:ヘッダーを作成します。参考までに、Rails Webistrano 1.4(mod_proxyで私をつまずかせていたアプリ)でベンダー化された関連コードは、関数Host_with_port_without_standard_port_handling内のvendor/Rails/actionpack/lib/action_controller /cgi_process.rbの88行目にあるようです。

ここで、説明されているProxyPassとProxyPassReverseの典型的な例を見てくださいどこでもネット上本質的に)あなたの質問とここに与えられた代替の答えを含みます:

<VirtualHost *:80>
ServerName proxy.domain.tld
ProxyPass /app1/ http://app1Host.internal/
ProxyPassReverse /app1/ http://app1Host.internal/
</VirtualHost>

問題がわかりますか?それはPPRラインです..

Rails/ActionPack/dasFrameworkは、その知恵では、Location:ヘッダーを「修正」することで、あなたを---(helpしようとしているため、PPR行の後半は正しくありません:一致する代わりに

Location: http://app1Host.internal/redirected/path

mod_proxyは実際には参照

Location: http://proxy.domain.tld/redirected/path

幸いなことに、修正は非常に簡単です-上記のvhost構成を次のように変更します。

<VirtualHost *:80>
ServerName proxy.domain.tld
ProxyPass /app1/ http://app1Host.internal/
ProxyPassReverse /app1/ http://proxy.domain.tld/
</VirtualHost>

仮想ホストでプロキシされているアプリが複数ある場合は、PPRを区別するために、少なくともロケーションセクション内にPPRを配置する必要があることに注意してください。

5

Apache 2.4以降には、X-Forwarded- *ヘッダーを削除するディレクティブがあります。

ProxyAddHeaders off

https://httpd.Apache.org/docs/2.4/mod/mod_proxy.html#proxyaddheaders

5
Todd Vierling

Mod_rewriteの代わりにProxyPassを使用して、実行しようとしていることを実行する方が簡単な場合があります。それはあなたの問題を解決しないかもしれません、しかしそれは確かにあなたの設定ファイルを少しきれいにするでしょう:

 ProxyPass/cit/http://test.example.com:3000/
ProxyPassReverse/cit/http://test.example.com:3000/

Tcpflowやwiresharkなどを使用して、Apacheがリクエストのプロキシに使用しているヘッダーを正確に確認することをお勧めします。

1
David Pashley