mod_rewrite klappt nicht
Progger
- programmiertechnik
Hallo!
Ich habe die links
"http://klaus-mustermann.de/12.34.56/login.php"
und
"http://klausmustermann.de/12.34.56/login.php"
und möchte gerne, dass der Nutzer - egal auf welchen Link bzw. welchen pfad man in seinem Browser eingibt (ob mit oder auch ohne http://) immer auf folgender Linkadresse landet:
"https://klaus-mustermann.de/12.34.56/login.php"
Nach meinen Recherchen schaffe ich das mit einer ".htaccess" Datei, die ich in meinem root-Verzeichnis abspeicher mit einer entsprechenden Regel drin.
Nach einigem gegoolge bin ich auf folgender Seite gelandet
"http://www.modrewrite.de/mod-rewrite/syntax/"
aus der ich mir folgende Regel zusammengereimt habe:
[...
Options +FollowSymLinks
RewriteEngine on
RewriteRule .+laus.*.de/12.34.56/login.php https://www.klaus-mustermann.de/12.34.56/login.php
...]
Zur Erklärung:
da der Nutzer auch einfach nur "klausmustermann.php/..." eingeben könnte, habe ich den ersten Buchstaben meiner Domain "k" weggelassen und mit dem Zeichen ".+" ersetzt, was laut der Seite für "Ein oder mehrere beliebige Zeichen" steht. Entsprechend sollte ich somit sämmtliche Eingaben wie
"http://k", "www.k", "k" abfangen - anschließend folgt "laus".
Da es nun die beiden Varianten "-mustermann.de" oder auch direkt "mustermann.de" gibt, habe ich die Regel ".*" verwendet, was beides abfangen sollte. Anschließend folgt der Rest des Pfades, der bei allen Varianten gleich ausfallen sollte und somit keiner weiteren Beachtung bedarf.
Demnach müsste meines erachtens alle folgenden Schreibweisen...
"http://klaus-mustermann.de/12.34.56/login.php"
"http://klausmustermann.de/12.34.56/login.php"
"klaus-mustermann.de/12.34.56/login.php"
"klausmustermann.de/12.34.56/login.php"
... auf folgenden Link umgeleitet werden:
"https://www.klaus-mustermann.de/12.34.56/login.php"
DAT FUNZT ABER NICHT!
Ich habe die Datei "htaccess" nur mit den beiden oben dargestellten Zeile sowohl im root-Verzeichnis meiner Domain, als auch im Unterverzeichnis "klausmustermann/12.34.56/" gespeichert.
Egal was ich in meiner Browser-Adress-Leiste eingebe, es wird NICHTS geändert!
Wo ist hier mein Denkfehler?
Wer kann mir helfen?
Wie mache ich es richtig?
Vielen Dank für hilfreiche Tipps.
Prooger
Hi,
RewriteRule .+laus.*.de/12.34.56/login.php https://www.klaus-mustermann.de/12.34.56/login.php
...]Zur Erklärung:
da der Nutzer auch einfach nur "klausmustermann.php/..." eingeben könnte,
Selbst wenn du hier offensichtlich .de statt .php stattdessen meinst, bringt das RewriteRule trotzdem immer noch nicht dazu, sich für den Hostnamen des Requests auch nur das geringste Bisschen zu interessieren – RewriteRule matcht ausschließlich die Path-Komponente des URL, sonst nichts.
Wenn du den Hostnamen auswerten willst, musst du das mit einer vorgeschalteten RewriteCond machen.
[…] Entsprechend sollte ich somit sämmtliche Eingaben wie
"http://k", "www.k", "k" abfangen - anschließend folgt "laus".
Da es nun die beiden Varianten "-mustermann.de" oder auch direkt "mustermann.de" gibt, habe ich die Regel ".*" verwendet, was beides abfangen sollte.
Das ist der nächste Fehler – du *willst* nicht „alles“ abfangen, was den Hostnamen angeht – sonst landest du nämlich in einer Endlos-Schleife von Umleitungen, wenn der Nutzer bereits den „richtigen“ Hostnamen in seiner Anfrage verwendet hat, und du trotzdem wieder einen Redirect dorthin ausgibst.
Und wenn er bereits diesen richtigen Hostnamen verwendet hat, aber die Anfrage per HTTP gestellt hat, dann willst du ihn trotzdem noch zur HTTPS-Variante umleiten – das ist also noch eine zusätzliche Bedingung, die du ebenfalls mit prüfen musst.
MfG ChrisB
Hallo ChrisB! :-)
Der "Allwissende" ist wieder da - wie schön das es Dich gibt!
Das ist echt ernst gemeint. Deine Kommentar helfen mir "meistens" weiter.
In diesem Fall scheint es mir doch sehr kompliziert zu sein, da ich mit diesem "RewriteRules" absoluter Leihe bin und mich mit Deinem Link schon sehr überfordert fühle. Zu allem Überfluss ist auch noch alles auf Englisch, was das ganze nicht wirklich leichter macht. Dennoch werde ich versuchen Dir zu folgen, sodass Du mir hoffentlich zum Ziel verhelfen kannst:
Selbst wenn du hier offensichtlich .de statt .php stattdessen meinst, bringt das RewriteRule trotzdem immer noch nicht dazu, sich für den Hostnamen des Requests auch nur das geringste Bisschen zu interessieren – RewriteRule matcht ausschließlich die Path-Komponente des URL, sonst nichts.
Da hatte ich mich tatsächlich verhaspelt, ich meinte natürlich .de.
Wenn ich Dich richtig verstanden habe komme ich hier mit RewriteRule nicht wirklich weiter.
Stattdessen sollte ich mich mit RewriteCond auseinander setzen...
Wenn du den Hostnamen auswerten willst, musst du das mit einer vorgeschalteten RewriteCond machen.
[…] Entsprechend sollte ich somit sämmtliche Eingaben wie
"http://k", "www.k", "k" abfangen - anschließend folgt "laus".
Da es nun die beiden Varianten "-mustermann.de" oder auch direkt "mustermann.de" gibt, habe ich die Regel ".*" verwendet, was beides abfangen sollte.
Das ist der nächste Fehler – du *willst* nicht „alles“ abfangen, was den Hostnamen angeht – sonst landest du nämlich in einer Endlos-Schleife von Umleitungen, wenn der Nutzer bereits den „richtigen“ Hostnamen in seiner Anfrage verwendet hat, und du trotzdem wieder einen Redirect dorthin ausgibst.
Das ist wohl richtig. Zu kurz gedacht - der User könnte ja auch mal was richtig machen :)
Und wenn er bereits diesen richtigen Hostnamen verwendet hat, aber die Anfrage per HTTP gestellt hat, dann willst du ihn trotzdem noch zur HTTPS-Variante umleiten – das ist also noch eine zusätzliche Bedingung, die du ebenfalls mit prüfen musst.
Dass schaffe ich hoffentlich auch mit RewriteCond?
Nachdem ich bei Google nochmal nach deutsch-sprachigen Seiten gesucht habe, bin ich auf folgende gestoßen: Link
Ich habe mir jetzt folgende Zeile für mein Beispiel erarbeitet:
RewriteCond %{HTTP_HOST} !^https://www.klaus-mustermann.de/12.34.56/login.php$
Das ergibt folgende Ergebnisse:
aus "klaus-mustermann.de/12.34.56/login.php" wird "https://www.klaus-mustermann.de/12.34.56/login.php" - SO SOLL ES SEIN! :o)
Ebenso bei der Eingabe "www.klaus-mustermann.de/12.34.56/login.php" KLAPPT WUNDERBAR!
Wenn ich jedoch "http://www.klaus-mustermann.de/12.34.56/login.php" eingebe, wird daraus "www.klaus-mustermann.de/12.34.56/login.php", was mich sehr wundert, da ich ja mit dieser direkten Eingabe zu "https..." gelange...?
Bei der Angabe der Domain ohne Bindestrich wird noch nichts weiter geänder, was wahrscheinlich damit zusammenhängt, dass es eine komplett andere Domain ist. Ich denke mal, ich könnte eine zweite Zeile hinzufügen in der der Bindestrich nicht vorkommt...? Werde ich gleich mal testen...
Ich bin also schon mal einen großen Schritt weiter, allerdings wäre es jetzt noch schön, dass auch bei der Eingabe von "http://www.klaus-mustermann.de/12.34.56/login.php" in eine verschlüsselte Seite (https) umgeleitet wird...
Hast Du hier vielleicht noch einen Tipp?
Vielen Dank schon mal für Deine Hilfe!
Besten Gruß Progger
Hello Progger,
"Leihe" oder Laie?
Ich leihe Dir mal das Statement, das dich ggf. weiterbringen sollte:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^kleine-kapelle\.com$
RewriteRule ^(.*)$ http://kleine-kapelle\.com/$1 [L,R=302]
Bedeutet:
Wenn die Bedingung zutrifft, dass der Host-Anteil des Requests nicht "kleine-kapelle.com" lautet, dann leite alles um auf http://kleine-kapelle.com und hänge den Requeststring an.
L = Letzte Angabe
R = Response-Status = 302
http://httpd.apache.org/docs/current/mod/mod_rewrite.html
http://httpd.apache.org/docs/2.2/rewrite/flags.html
Die Flags muss ich auch immer nachgucken...
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hallo Progger,
vielen Dank für die Lösung - die FAST perfekt ist.
Dennoch habe ich einen Weg gefunden, wie man die Verschlüsselung umgehen kann:
Ich gebe meinen Wunschpfad ein (alle Varianten gtestet) und werde wie gewünscht auf die verschlüsselte "https"-Domain umgeleitet.
Wenn ich nun jedoch in die Adresszeile klicke und das "s" von https entferne, anschließend auf Enter klicke, lande ich auf der unverschlüsselten login.php und lade alle Spionageprogramme ein meine Zugangsdate mitzulesen. - Bei einem großen Auktionshaus geht das nicht...!
Da gibt es also noch Handlungsbedarf! - Hast Du dazu auch noch eine Idee?
Ich möchte die aktuelle Lösung aber gerne noch nachvollziehen können und fasse es hier in meinen Worten nochmal zusammen, um sicher zu gehen, dass ich alles richtig verstanden habe:
RewriteCond %{HTTP_HOST} !^kleine-kapelle.com$
RewriteRule ^(.*)$ http://kleine-kapelle.com/$1 [L,R=302]
In der ersten Zeile wird geprüft, ob die Adresse ungleich "kleine-kapell.com" ist.
Wenn dem so ist, werden "in Zeile 2" alle Zeichen NACH "kleine-kapelle.com/" in der Variable $1 gespeichert, eine Umleitung (hier http://kleine-kapelle.com) definiert und der ursprüngich gewünschte Pfad aus der gespeicherten Variable $1 an die Domain angefügt.
Abschließend wird mit dem Buchstaben "L" die letzte Zeile gekennzeichnet.
Wofür steht R=302?
R = Response-Status = 302 sagt mir in diesem Fall nichts, finde auch nichts auf Deinen verlinkten Seiten darüber
Besten Dank für Deine Hilfe
Es bleibt noch ein Sicherheitsloch, welches ich gerne geschlossen hätte.
Kann mir hier noch jemand helfen?
Besten Gruß
Hello,
Da gibt es also noch Handlungsbedarf! - Hast Du dazu auch noch eine Idee?
Wenn keine "normale" Webseite besteht, kann man die auch nicht aufrufen.
Außerdem hat Dir Chris ja schon geschrieben, dass man auch für das Protokoll eine Condition benötigt.
Guckst Du nach:
%{SERVER_PROTOCOL}
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hi,
Guckst Du nach:
%{SERVER_PROTOCOL}
Nein, das nicht – da steht nur HTTP/1.1 drin.
MfG ChrisB
Hello,
Guckst Du nach:
%{SERVER_PROTOCOL}
Nein, das nicht – da steht nur HTTP/1.1 drin.
Siccher?
Ich habe es jetzt nicht extra ausprobiert, aber dann sollten wir den Apache-Leuten mal einen Tipp für ihre Doku geben.
Or, for example, to redirect a portion of your site to HTTPS, you might do the following:
<If "%{SERVER_PROTOCOL} != 'HTTPS'">
Redirect /admin/ https://www.example.com/admin/
</If>
If, for whatever reason, you still want to use mod_rewrite - if, for example,
you need this to work with a larger set of RewriteRules - you might use one
of the recipes below.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hi,
%{SERVER_PROTOCOL}
Nein, das nicht – da steht nur HTTP/1.1 drin.
Siccher?
Zumindest, wenn es gleich dem ist, was $_SERVER['SERVER_PROTOCOL'] in PHP liefert – das ist nämlich HTTP/1.1 (oder HTTP/1.0, je nachdem).
Und das wäre m.E. auch logisch, weil das das Protokoll ist, dass der Server mit dem Client spricht. HTTPS ist ja „nur“ HTTP *over* SSL/TLS.
Ich habe es jetzt nicht extra ausprobiert, aber dann sollten wir den Apache-Leuten mal einen Tipp für ihre Doku geben.
<If "%{SERVER_PROTOCOL} != 'HTTPS'">
Okay, das müsste noch mal explizit geprüft werden.
MfG ChrisB
Hello,
Ich habe es jetzt nicht extra ausprobiert, aber dann sollten wir den Apache-Leuten mal einen Tipp für ihre Doku geben.
<If "%{SERVER_PROTOCOL} != 'HTTPS'">
Okay, das müsste noch mal explizit geprüft werden.
Sonst gäbe es noch %{REQUEST_SCHEME} und %{HTTPS}
HTTPS
Will contain the text "on" if the connection is using SSL/TLS, or "off" otherwise. (This variable can be safely used regardless of whether or not mod_ssl is loaded).
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hello,
und schau Dir auch noch diese Seite an:
http://httpd.apache.org/docs/current/rewrite/remapping.html
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Selbst grüßen ist doch auch ne feine Sache :))
Ich meinte natürlich HALLE TOM!
Sorry für dieses Off-Topic, aber eine richtige BEgrüßung ist mir dieser Umstand wert ;)
Okay, ich habe da noch mal etwas weitergelesen und so einige Fehler bei mir festgestellt.
Meine neue Zeile bzw. Zeilen sehen jetzt so aus:
RewriteEngine on
RewriteCond %{HTTP_HOST} !^https://www.klaus-mustermann.de/12.34.56/login.php$
RewriteCond %{HTTP_HOST} !^https://www.klausmustermann.de/12.34.56/login.php$
RewriteRule ^(.*)$ https://www.klaus-mustermann.de/12.34.56/login.php [R=301,L]
Das Problem was sich nur aber darstellt ist, dass (wie Du bereits erwähnt hast) eine Endlosschleife läuft, da ja eine Eingabe immer Abweicht.
Wie kann ich also die Abfrage so gestalten, dass nur dann RewriteRule in kraft treten soll, wenn beide Bedingungen nicht erfüllt sind?
thx
Hi,
RewriteCond %{HTTP_HOST} !^https://www.klaus-mustermann.de/12.34.56/login.php$
Hier versuchst du, den kompletten URL gegen den Hostnamen (umgangssprachlich auch der „Domainname“) zu matchen – der Hostname ist aber nur ein Teil des URL.
www.klaus-mustermann.de ist der Hostname – ihn mit dem kompletten URL zu vergleichen, kann also nur mit einem nicht-Match enden.
Wie kann ich also die Abfrage so gestalten, dass nur dann RewriteRule in kraft treten soll, wenn beide Bedingungen nicht erfüllt sind?
Erst mal brauchst du die *korrekten* Bedingungen.
Der Hostname (und nur der) ist das eine, und ob HTTPS verwendet wird oder nicht, das andere.
In der Beschreibung zu RewriteCond¹ wird HTTPS explizit erwähnt – also lese dort noch mal nach, welchen Wert du diesbezüglich abfragen solltest.
(Und da es zwei verschiedene Bedinungen sind, wirst du auch zwei einzelne RewriteCond brauchen. Dass diese per Default mit einem impliziten AND verknüpft sind, steht ja ebenfalls dort.)
MfG ChrisB
¹ Link diesmal auf das Handbuch zu Apache Version 2.2, da 2.0 wie im anderen Dokument oben erwähnt gar nicht mehr maintained wird. Das macht aber bzgl. des Rewritings hier keinen nennenswerten Unterschied.