3

I'm trying to block access to images on my server if they are linked from some common "baddies", i.e. sites with users that tend to use other peoples bandwidth:

  • livejounal.com
  • blogger.com
  • myspace.com
  • ...

There are two things that differentiate my question from others like this question and that question:

  • I want to do it "serverwide", i.e. configured in apache.conf for all hosts/domains, not in .htaccess or individual virtual hosts
  • I want to redirect the request to an image of my choice, not just send a 403 FORBIDDEN

I tried to include RewriteRules in apache.conf, but it does not do anything at all. And there doesn't seem to be an option that allows me to redirect depending on SetEnv.

Any suggestions?

BlaM
  • 3,816
  • 5
  • 26
  • 27

4 Answers4

2

I have a solution, even if it is not very beautiful, because it leaves the default error 403 document changed even if the image is not hotlinked:

This goes into apache2.conf:

    SetEnvIfNoCase Referer "livejournal.com" hotlink

    <FilesMatch ".(gif|jpg|jpeg|png)$">
            ErrorDocument 403 /server404/no_hotlink.php
    </FilesMatch>
    <FilesMatch ".(gif|jpg|jpeg|png|mpg|avi|flv)$">
            deny from env=hotlink
    </FilesMatch>

    Alias /server404 "/var/www/_404"
    <Directory "/var/www/_404">
        AllowOverride AuthConfig
        Order allow,deny
        Allow from all
    </Directory>

We used the /server404 path for a serverwide 404 error document for some time, so we already had that. You could also call it 403 or GlobalNoHotlink or whatever you want.

For images (first FilesMatch) we set the "forbidden" ErrorDocument to a PHP file in our /server404 directory. Then we check if it is hotlinked (there we also do that for video files, thus two FilesMatch tags) and forbid access if hotlinked.

This goes into /var/www/_404/no_hotlink.php - the PHP file called on forbidden image:

    <?PHP
    $file = dirname(__FILE__) . '/_default/no_hotlink.png';

    header('HTTP/1.1 200 OK', true, 200);
    header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
    header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
    header("Cache-Control: no-cache, must-revalidate");
    header("Pragma: no-cache");
    header('Content-length: ' . filesize($file));
    header('Content-type: image/png');
    readfile($file);
    ?>
  • The first line is used to identify the image file we want to send out.
  • Then we set the HTTP header to 200 (this is optional. Decide for yourself),
  • add some headers to avoid caching of the image (we don't want to let that 8000x8000 pink pixel file appear "from cache" on our site if the person decides to go to our site, do we?).
  • Content-length according to the dummy file's size and
  • MIME type (You might have to change the latter of not using PNG).
  • Then we read the file.

It works - but it is not as beautiful as I'd like to have it, so will still be happy about other solutions.

BlaM
  • 3,816
  • 5
  • 26
  • 27
0

I have something like this in my httpd.conf:

RewriteCond "%{HTTP_REFERER}" !=""
RewriteCond "%{HTTP_REFERER}" "!^http://www.mydomain.com/.*$" [NC]
RewriteRule "\.(jpg|png)$ - [F]

You might need to use this as well if you haven't used RewriteConds and RewriteRules before:

RewriteEngine On

I found it googleing or in the Apache Cookbook. Can't remember anymore.

f.ederi.co
  • 69
  • 1
  • 3
  • You can change the last line of this to rewrite the url to point at another image, rather than returning 403. – David Pashley Jun 03 '09 at 16:36
  • As stated in my Question: RewriteEngine does not work in my environment. Not sure why. I use it all over the place. Maybe RewriteRules specified in global scope are overwritten by local .htaccess files. – BlaM Jun 03 '09 at 16:43
-1

The only effective way to do is is with mod rewrite rules. If the referrer is not from your own domain, then rewrite the image url to be one that is non-existant, somewhere else, or a 1px by 1px transparent gif.

A lot of people do this with an image that says 'No leeching, buddy' or similar

Iain
  • 363
  • 1
  • 4
-1

referer checking not always works, some proxies or even browsers strip HTTP_REFERER header from http requests.

it's much better to check some cookies in your content-generating code [ eg index.php that generates picture gallery ] and check on mod-rewrite or apache2 level if cookie is set to expected value.

look here or here.

pQd
  • 29,561
  • 5
  • 64
  • 106
  • 1
    I think there are much more people without cookies than without referer. Also: I can live with a few hotlinked images slipping through if almost every other person sees the wrong image. That should be annoying enough for the "stealing webmaster" to remove the file altogether. In the end, that's what I want. – BlaM Jun 03 '09 at 16:43