web-dev-qa-db-ja.com

Apache:安全でないポートが安全なポートに送信されました...リダイレクトしたいです

序文

まず、単純にポート80->ポート443書き換えはこれを修正しません。以前のほとんどすべての質問、メールスレッド、フォーラムスレッドなどで、これが最初の無知な応答であり、何度もオウムされたことがわかりました。

2つ目:はい、同じポートでHTTPトラフィックとHTTPSトラフィックを処理することはできません。 これはそうではありません。

シナリオ:

ポート乗算を介して複数のサイトをホストするApacheサーバー。ポート80は公開サイトとして機能します。ポート443は、そのサイトの安全なバージョンを提供します。

ポート7443、8443、および9443はそれぞれ、SSLで保護された個別のサイトに対応します。

ユーザーがURLを誤って入力した場合、または無効なリンクが与えられた場合、たとえば http://hostname.tld:744 とすると、次のとんでもないページが表示されます。

Apache Bad Request error message

サーバーの代わりに、それらを https://hostname.tld:744 にリダイレクトするだけです。

私の質問は、どのように Zeus's butthole の名前で、Apacheの動作またはこのエラーメッセージを変更して、ユーザーを自動的にリダイレクトできるかということです。

Apacheは、HTTPS用に構成されているにもかかわらず、(そのエラーメッセージを表示するために)非httpsリクエストを処理していることは明らかです。デフォルトでリダイレクトを実行するだけでなく、私には非常に馬鹿げているように見えますが、同意しなくても、なぜ彼らがそうした動作を行ったのか理解できます。だから私の質問です:それを変更できますか?彼らはエラーSOMEWHEREを処理しており、Apacheが実際の構成の宝庫なので、この動作を処理するためのディレクティブがどこかにあるのは当然のことですが、私はこれまで数時間いじくり回してそれを見つけることができませんでした。

更新:

私は次のようなさまざまなことを試みました:

  • ErrorDocument 400ディレクティブを使用してCGIおよびPHP Status 301およびLocationヘッダーを送信するだけのスクリプトを取得するスクリプトを使用します。これにより、空白のページが生成されます。 ErrorDocument 400 https://hostname.tld:7443を指定すると、そのリンクがページに表示されます。

  • mod_rewriteのほとんどすべての組み合わせを使用して、サイト全体を指示する包括的なステートメントを含め、私またはGoogleが思いつくことができます。これらの機能しない。文字通り、彼らは何もしません。 Apacheが書き換えディレクティブの処理を試みる前に、上記のエラーを引き起こしているのではないかと思います。

カスタムポートを使用しているため、ポートベースのリダイレクトを使用できません。スクリプトベースのリダイレクトは、http/httpsの不一致のために配信されないため、使用できません。私はこれをバグまたは意図しない動作にまで踏み込みたいと思っていますが、誰かがそこに非常にカスタムのエラーメッセージを入れることを予見していました。彼らはあなたが単にカートに入れたいだけだとは考えていませんでした。 URLすでに提供されています

9
peelman

これはおそらく、Apache 2.2以下がこの特定の状況を処理する方法のバグだと思います。

SSL読み取り400 Bad Requestエラーの場合、Apache 2.2はHTTP応答コードまたはヘッダーを返さず、HTTP応答本文のみを返すようです。私はポート443にTelnet接続して送信することでテストします。

GET / HTTP/1.1

サーバーはすぐに戻ります(私にとって):

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
Reason: You're speaking plain HTTP to an SSL-enabled server port.<br />
Instead use the HTTPS scheme to access this URL, please.<br />
<blockquote>Hint: <a href="https://server.tld/"><b>https://server.tld/</b></a></blockquote></p>
</body></html>

HTTP応答コードまたはHTTPヘッダーがないことに注意してください。

これをApache 2.4サーバーに対して実行すると、次のようになります。

HTTP/1.1 400 Bad Request
Date: Sun, 10 Feb 2013 00:47:23 GMT
Server: Apache/2.4.3 (Unix) OpenSSL/1.0.0g
Content-Length: 462
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
Reason: You're speaking plain HTTP to an SSL-enabled server port.<br />
Instead use the HTTPS scheme to access this URL, please.<br />
</p>
<hr>
<address>Apache/2.4.3 (Unix) OpenSSL/1.0.0g Server at server.tld Port 443</address>
</body></html>

あなたがしたようにErrorDocument行をセットアップした場合:

ErrorDocument 400 https://server.tld/

次に、302リダイレクトのHTMLを取得しましたが、ヘッダーは1つもありません。 302リダイレクト応答コードとLocation:ヘッダーがないと、ブラウザーはリダイレクトしません。

Apache 2.4にアップグレードして、動作するかどうかを確認してください。私は少なくともApache 2.4.3でテストおよび確認しましたが、これが動作が更新された時期を正確に見つける努力はしていません。彼らが2.4を準備している大量の作業で、彼らは副作用として望ましくない振る舞いを修正したのではないかと思います。

関連するApache httpdバグ:

[〜#〜]更新[〜#〜]

スクリプトにヘッダー(クライアントに送信されない)を印刷させ、必要なヘッダーを手動で再度印刷させることにより、バグのあるApacheに強制的に必要な動作(リダイレクト)を与えることができます。 Apache 2.2.22で動作する基本的なPerlスクリプトは次のとおりです。

#!/usr/bin/Perl

use strict;
use CGI;

my $q = CGI->new();

# this will cause Apache to handle the response properly, but is meaningless otherwise
print $q->redirect("https://localhost/");

# this actually performs the redirect
print "HTTP/1.1 302 Found\r\n";
print "Location: https://localhost/\r\n";
print "\r\n";

# you can do whatever you want here; this will be the HTML body

SSLなしでSSLポートと通信するだけでなく、400が生成される理由は他にもあることに注意してください。これを判別する簡単な方法は、HTTPS環境変数を探すことです。設定されている場合、SSLは適切にネゴシエートされ、他の何かが400を引き起こしています(その場合は、ダブルヘッダートリックを実行しないでください)。 HTTPSが設定されていない場合は、上記のようにリダイレクトを返します。

6
hrunting