Dominik: htaccess hotlinken verhindern "blacklist" aber bild mit übergebe

Hallo

ich möchte gern für bestimmte Seiten das hotlinken meiner Bilder unterbinden

RewriteEngine on
RewriteCond %{HTTP_REFERER} ^http://www.example.com/.*$ [NC,OR]
RewriteCond %{REQUEST_FILENAME} !anderes-bild.php$
RewriteRule .(gif|jpg|GIF|JPG|png|PNG)$ http://www.example.org/anderes-bild.php [R,L]

wie man sieht will ich das "Ersatzbild" mit php generieren. Ich würde aber gerne wissen welches Bild versuch wurde zu hotlinken, am besten wäre es wenn ich es im GET Parameter mit an das PHP Script übergeben kann, nur wie stell ich das an? Es reicht hier auch NICHT der Dateiname sondern ich brauch die komplette Ordnerstruktur (ob dann http://www.example.org noch davor mit dran hängt ist mir egal kann ich im PHP dann schon passend anpassen aber mir reicht halt kein bild1.jpg sondern mindestens /ordner1/ordner2/bild1.jpg)

Vielen dank

Gruß Dominik

  1. Tach!

    RewriteRule .(gif|jpg|GIF|JPG|png|PNG)$ http://www.example.org/anderes-bild.php [R,L]
    Ich würde aber gerne wissen welches Bild versuch wurde zu hotlinken, am besten wäre es wenn ich es im GET Parameter mit an das PHP Script übergeben kann, nur wie stell ich das an?

    Alles was PHP über den Request weiß (auch die originale Adresse bei einem Rewrite-Vorgang) steht in $_SERVER. Dummerweise machst du aber einen Redirect (vollständige URL statt nur einem Dateinamen), das heißt du lässt den Client eine neue Ressource anfordern. Da stehen dann natürlich keine Daten vom vorhergehenden Request mehr mit drin (außer dem Referrer). Wenn du beim Redirect bleibst, musst du vom ursprünglichen Request die dich interessierenden Daten als Querystring mitgeben. Leider kann man die Servervariablen nicht in einer RewriteRule verwenden. Man kann sie nur in einer RewriteCond angeben und nur in Form einer Backreference in die RewriteRule einfügen.

    dedlfix.

    1. hallo

      ich bin ehrlich, es ist gerade etwas zu hoch für mich ;)

      Ich erkläre noch mal mein Ziel und vielleicht findet man ja dann eine passende Lösung

      Meine Seite ist www.example.org, sie besitzt einige Unterordner mit Bilder darin. Sollte nun eines dieser Bilder von www.example.com gehotlinked werden (und nur von dieser Seite, alle anderen Seiten dürfen normal hotlinken), möchte ich ein php script aufrufen, welches weiß welches Bild gehotlinked wurde und ein Ersatzbild (über gdlib) ausgibt. Um genauer zu sein, die gdlib läd das Originalbild aber ändert es ein wenig ab, deshalb muss ich auch wissen welches Bild versucht wurde zu hotlinken.

      Gruß Dominik

      1. Tach!

        ich bin ehrlich, es ist gerade etwas zu hoch für mich ;)

        Wenn du etwas nicht verstehst, informiere dich bitte in der Dokumentation des von dir verwendeten Systems oder durch anderweitige Recherche oder frag gezielt nach.

        Ich erkläre noch mal mein Ziel und vielleicht findet man ja dann eine passende Lösung

        Ich hatte bereits verstanden, was du willst. Meine Antwort passt immer noch auf deine Frage. Wir sind hier im Self-Forum, nicht im Ich-mach-das-mal-eben-für-dich-Forum. Ich helfe dir bei der Lösungsfindung, indem ich dir die Thematik zu erläutern versuche oder Informationsquellen nenne. Und du erarbeitest dir mit diesem Wissen die Lösung. Wenn du das nicht auf diese Weise möchtest, hab ich kein Interesse an einer Hilfestellung.

        dedlfix.

  2. RewriteRule .(gif|jpg|GIF|JPG|png|PNG)$ http://www.example.org/anderes-bild.php [R,L]

    Das ist ungünstig, weil es einen neuen Request auslöst und dann die von dedlfix beschriebenen Probleme auftreten.

    Entweder Du notierst (und das ist in Deinem Fall die beste Lösung)
    <IfModule rewrite.c>
      RewriteEngine On
      RewriteBase /
      RewriteRule .(gif|jpg|GIF|JPG|png|PNG)$ /anderes-bild.php [L]
    </IfModule>

    (gibst den Pfad zum Skript ohne Protokoll und ohne Servername an und vermeidest das [R] für den Redirect)

    ... und kannst in Deinem Skript $_SERVER["REQUEST_URI"] auswerten

    ============================================================
    Achtung! Das Folgende außer zu Testzwecken nicht nachmachen!

    ... oder Du hängst die ursprüngliche Adresse mit an den neuen Request:
    <IfModule rewrite.c>
      RewriteEngine On
      RewriteBase /
      RewriteRule ^(.*(gif|jpg|GIF|JPG|png|PNG))$ http://localhost/test.php?pic=$1 [L]
    </IfModule>

    ... umd dann $_GET['pic'] auszuwerten. Das ist aber so nötig wie nach einem Spaziergang an der Sonne die Jacke in der einzigen Absicht, sie dann zu trocknen, nass zu machen.

    Unter der URI http://httpd.apache.org/docs/current/mod/mod_rewrite.html ist ein ganz brauchbares Handbuch zu finden.

    Das "<IfModule rewrite.c>" dient dazu, dass Du Dir nicht den gesamten Server lahm legst (Es kommt dann nur "Error 500", wenn das Modul rewrite nicht installiert oder aktiviert ist.

    Jörg Reinholz

    1. Noch drei wichtige Nachträge:

      (1)
      Natürlich musst Du noch die Kondition eintragen.

      (2)
      In diesem Zusammenhang fällt mir folgendes auf:

      RewriteCond %{HTTP_REFERER} ^http://www.example.com/.*$ [NC,OR]

      Das hat auch Folgen! Nicht jeder Client sendet den HTTP_REFERER im Request-Header mit. So dürfte dieser Header bei Besuchern fehlen, die zum Schutz ihrer Privatsphäre privoxy oder ähnliches benutzen - und das könnten ein paar mehr sein als Du denkst. Vor allem Mitarbeiter von Firmen, die auch den durch Werbung verursachten Traffik begrenzen wollen.

      Die bekämen dann auf DEINEN Webseiten womöglich die "ausgetauschen" Grafiken...

      (3)
      Soweit ich das beurteilen kann wird das Erzeugen der Grafiken bei jedem Abruf eine nicht gerade geringe Serverlast verursachen. Viele Links zu den Grafiken könnten also die gleichen Folgen haben wie eine DDoS-Attacke - Der Server wäre recht schnell überlastet. Besser ist: Erzeuge besser die Grafiken nur einmal und sende diese dann statisch aus.

      Jörg Reinholz

    2. Tach!

      RewriteRule ^(.*(gif|jpg|GIF|JPG|png|PNG))$ http://localhost/test.php?pic=$1 [L]

      Achja, für den ursprünglichen Request muss man ja gar nicht die Servervariablen auswerten, denn den kennt ja auch die RewriteRule. Das kann man übrigens noch geringfügig vereinfachen/verbessern. Der gesamte vom Muster abgedeckte Teil des Requests ist in der Backreference $0 enthalten, also kann man die äußeren Klammern (Gruppierung für $1) weglassen. Und wenn der Anfang beliebig ist, muss man den Anfang (^) auch nicht weiter in die Regel aufnehmen, denn .* greift wegen der Greediness (Gierigkeit) regulärer Ausdrücke sowieso alles, was es zu fassen bekommt. Nicht vergessen sollte man aber den . vor der Endung, sonst findet die Regel auch foogif.

      RewriteRule .*.(gif|jpg|GIF|JPG|png|PNG)$ http://localhost/test.php?pic=$0 [L]

      dedlfix.

      1. Tach!

        Post :)

        RewriteRule .*.(gif|jpg|GIF|JPG|png|PNG)$ http://localhost/test.php?pic=$0 [L]

        Oh. Du hast im Prinzip Recht, auch als höchst ungünstige dargestellte Beispiele sollten lehrreich sein. Aber Du wirst mir hoffentlich nachsehen, dass ich die aus meiner Sicht sowieso höchst ungünstige Lösung (unnötiger erneuter Request) nicht noch bis in den letzten Prozessortakt optimiert habe, weil die eigentliche Geschwindigkeitsbremse nebst einer groben Laststeigerung um ca. 100% im erneuten Request liegt.

        Jörg Reinholz

        1. Tach!

          Du hast im Prinzip Recht, auch als höchst ungünstige dargestellte Beispiele sollten lehrreich sein. Aber Du wirst mir hoffentlich nachsehen, dass ich die aus meiner Sicht sowieso höchst ungünstige Lösung (unnötiger erneuter Request) nicht noch bis in den letzten Prozessortakt optimiert habe, [...]

          Die aufgezeigten Dinge sind so universell, dass man sie auch in weniger ungünstigen Anwendungsfällen anwenden kann. Es geht mir weniger darum, den Fragenden eine exakt maßgeschneiderte Lösung zu präsentieren, als vielmehr ihnen Wissen mitzugeben, das sie auch in anderen Fällen verwenden können.

          dedlfix.