Apache: Unsichere Anfrage an sicheren Port gesendet ... möchte umleiten

9

Vorwort

Erstens: Ein einfaches Umschreiben von Port 80 -> Port 443 behebt dies NICHT . In fast jeder vorherigen Frage, jedem Mail-Thread, Forum-Thread usw. habe ich festgestellt, dass dies die erste ignorante Antwort war und mehrmals nachgeprüft wurde.

Zweitens: Ja, ich weiß, dass Sie keinen HTTP- und HTTPS-Verkehr auf demselben Port bereitstellen können. Das ist das nicht.

Szenario:

Apache Server, der mehrere Sites über Portmultiplikation hostet. Port 80 dient einer öffentlichen Site. Port 443 dient der sicheren Version dieser Site.

Die Ports 7443, 8443 und 9443 bedienen jeweils separate SSL-gesicherte Standorte.

Wenn ein Benutzer die URL falsch eingibt oder einen ungültigen Link erhält, z. B. http: //hostname.tld: 7443 , wird ihm die folgende lächerliche Seite angezeigt :

Apache Bad Request Fehlermeldung

Anstatt dass der Server sie nur zu https: //hostname.tld: 7443 umleitet .

Meine Frage ist, wie können Sie im Namen von Zeus 'Arschloch das Verhalten von Apache oder diese Fehlermeldung ändern, um den Benutzer automatisch umzuleiten?

Apache bedient offensichtlich eine Nicht-https-Anforderung (um diese Fehlermeldung anzuzeigen), obwohl sie für HTTPS konfiguriert ist. Es erscheint mir bemerkenswert dumm, nicht nur standardmäßig die Weiterleitung durchzuführen, sondern ich kann auch verstehen, warum sie sich so verhalten haben, auch wenn ich damit nicht einverstanden bin. Meine Frage ist also: Kannst du es ändern? Sie behandeln den Fehler ÜBERALL, und da Apache das Füllhorn für die Konfiguration ist, liegt es nahe, dass es irgendwo eine Anweisung gibt, um dieses Verhalten zu behandeln, aber ich konnte es in mehreren Stunden des Bastelns bisher nicht finden.

Aktualisieren:

Ich habe verschiedene Dinge versucht, darunter:

  • Verwenden von ErrorDocument 400Anweisungen, um zu einem CGI und einem PHP-Skript zu gelangen, die nur senden Status 301und LocationHeader. Dies führt zu einer leeren Seite. Wenn Sie ErrorDocument 400 https://hostname.tld:7443einfach verwenden, wird dieser Link auf der Seite angezeigt.

  • Wenn Sie fast jede Kombination von mod_rewriteI oder Google verwenden, können Sie sich ein Bild machen, einschließlich pauschaler Aussagen, die die Website vollständig steuern. diese funktionieren nie . Sie tun buchstäblich nichts. Ich vermute, dass Apache den oben genannten Fehler behebt, bevor er überhaupt versucht, die Anweisungen zum Umschreiben zu verarbeiten.

Ich kann aufgrund der benutzerdefinierten Portverwendung keine portbasierten Weiterleitungen verwenden. Ich kann keine skriptbasierten Weiterleitungen verwenden, da sie aufgrund der Nichtübereinstimmung von http / https nie bereitgestellt werden. Ich bin fast bereit, dies auf einen Fehler oder ein unbeabsichtigtes Verhalten zurückzuführen, aber jemand hatte die Voraussicht, eine sehr benutzerdefinierte Fehlermeldung einzutragen. Er machte sich nicht die Mühe zu denken, dass Sie vielleicht nur zum Wagen fahren möchten URL, die sie bereits bereitstellen ?

Peelman
quelle
Siehe die akzeptierte Antwort für SSL und Nicht-SSL auf einem Port
Daniel Vérité
Daniel, das war eine der vielen Fragen und Lösungen, die ich gefunden hatte, bevor ich diese Frage gestellt hatte. Ich denke, das Problem war die PHP-Komponente, aber da das Update der Antwort von @ hrunting im Moment für mich wunderbar funktioniert, werde ich nicht mehr Zeit darauf verwenden, als ich es bereits getan habe. Zumindest nicht, bis ich muss.
Peelman
2
upvote für das verlinkte Video, es vermittelt meine Emotionen perfekt
michele b

Antworten:

6

Ich denke, dies ist wahrscheinlich ein Fehler darin, wie Apache 2.2 und niedriger mit diesem besonderen Umstand umgeht.

Es scheint, dass 400 Bad RequestApache 2.2 bei einem SSL- Lesefehler nicht den HTTP-Antwortcode oder die Header zurückgibt, sondern nur den HTTP-Antworttext. Ich teste durch Telnetting an Port 443 und sende:

GET / HTTP/1.1

Der Server kehrt sofort zurück (für mich):

<!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>

Beachten Sie das Fehlen eines HTTP-Antwortcodes oder von HTTP-Headern.

Wenn ich dies auf einem Apache 2.4-Server mache, erhalte ich:

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>

Wenn ich eine ErrorDocument-Zeile wie Sie einrichte:

ErrorDocument 400 https://server.tld/

Dann bekomme ich den HTML-Code für eine 302-Umleitung, aber auch hier keinen der Header. Ohne den 302-Umleitungsantwortcode und den Location:Header wird der Browser nicht umleiten.

Versuchen Sie ein Upgrade auf Apache 2.4 und prüfen Sie, ob es funktioniert. Ich habe mindestens Apache 2.4.3 getestet und bestätigt, aber ich habe mich nicht bemüht, genau herauszufinden, wann dieses Verhalten aktualisiert wurde. Ich vermute, dass sie in der großen Menge an Arbeit, die sie für die Vorbereitung von 2.4 geleistet haben, das unerwünschte Verhalten als Nebeneffekt korrigiert haben.

Relevante Apache httpd-Fehler:

AKTUALISIEREN

Sie können einen fehlerhaften Apache zwingen, Ihnen das gewünschte Verhalten (die Umleitung) zu geben, indem Sie das Skript seine Header ausdrucken lassen (die nicht an den Client gesendet werden) und dann die gewünschten Header manuell erneut ausdrucken. Hier ist ein grundlegendes Perl-Skript, das unter Apache 2.2.22 funktioniert:

#!/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

Sie sollten sich bewusst sein, dass es andere Gründe gibt, warum ein 400 generiert werden kann, als nur mit einem SSL-Port ohne SSL zu sprechen. Der einfache Weg, dies festzustellen, besteht darin, nach der HTTPSUmgebungsvariablen zu suchen . Wenn es eingestellt ist, wurde SSL ordnungsgemäß ausgehandelt und etwas anderes verursacht die 400 (machen Sie nicht den Doppelheader-Trick, wenn dies der Fall ist). Wenn HTTPSnicht festgelegt, geben Sie Ihre Weiterleitung wie oben beschrieben zurück.

Jagd
quelle
1
Heilig. Mist. Perfekte Antwort. Gracias.
Peelman
Wissen Sie, während ich das lese, denke ich mir: "Mann, es ist wirklich scheiße, wenn Sie Apache 2.2 haben und diese Art von Umleitungsverhalten wollen." Ich werde mich nicht bemühen, ein geeignetes Apache 2.4-Deb (oder ein eigenes) für mein Ubuntu-System zu finden. Ich wette, Sie können eine Lösung aus Ihrem PHP-Skript hacken. Apache gibt die Ausgabe eindeutig nur an den Client aus. Wenn Sie also den spezifischen erwarteten Inhalt zurückgeben, können Sie das gewünschte Verhalten erhalten, ohne Apache zu aktualisieren. Versuchen Sie, Ihr PHP-Skript "HTTP / 1.1 302 Found \ r \ nLocation: server.tld \ r \ n \ r \ n" ausdrucken zu lassen .
Jagd
Das Problem dort ist, dass es nicht so aussieht, als würde das PHP-Skript verarbeitet. Ich sollte beachten, dass dies derzeit auf Apache 2.2.22 unter Ubuntu Server 12.04 sitzt. Und ja, es ist wirklich, wirklich scheiße; Besonders wenn Sie feststellen, dass in diesen Fehlerberichten völlig gegen die Bereitstellung einer Option für die automatische Umleitung vorgegangen zu sein scheint, scheint es nicht viel Hoffnung zu geben, dass 2.2 jemals die Lösung erhält.
Peelman
1
Und wie ich oben sagte, macht es für mich einfach keinen Sinn, warum Sie sich die Mühe machen, diese Fehlermeldung zu schreiben, anstatt sie zur Sicherung umzuleiten (im Ernst, warum nicht einfach umleiten? Je mehr ich darüber nachdenke, desto weniger Ich halte das für eine schlechte Idee.
Peelman
1
Ich habe das gesamte Dateisystem durchsucht und nach dem Text dieser blutigen Nachricht gesucht, um zu sehen, ob ich kann, woher sie ihn entlocken. Bei der Gelegenheit könnte ich ein <javascriptTag injizieren und Glück haben, wenn ich die Umleitung auf diese Weise hacke, aber bisher nein Würfel. Nichts davon scheint auf eine Weise gehandhabt zu werden, die der ansonsten ziemlich starren Apache-Großartigkeit folgt ...
Peelman
-1

Sie können dies mit mod-rewrite beheben. Stellen Sie eine Regel ein, die mit allem übereinstimmt. Siehe diese Antwort auf Stackoverflow

trent
quelle
Nein, das habe ich schon versucht, es funktioniert nicht. Es ist so, als würde es nicht einmal zu den ModRewrite-Schritten gelangen, weil es zuerst die http / https-Nichtübereinstimmung trifft.
Peelman
Hrm so dass ich nehme an, Sie von der Spitze der Sie Apache - Konfiguration begonnen haben Datei und arbeitete dem Weg nach unten , um zu sehen , was es fordert
trent
Ich habe praktisch das gesamte sites-availableVerzeichnis auswendig gelernt . Selbst wenn Sie es nur in Unsinn umleiten oder auf eine andere Site, einen anderen Port usw. umleiten, wird diese 400 Bad Request immer wieder geladen.
Peelman