开发者

htaccess log forbidden access

开发者 https://www.devze.com 2023-03-26 16:47 出处:网络
I have a couple of lines in my .htaccess that block hot linking of images. This works great. I am curious however to find out who is doing it.

I have a couple of lines in my .htaccess that block hot linking of images. This works great. I am curious however to find out who is doing it.

Is there a possibility for me to log the HTTP_REFERER when the RewriteRule is triggered?

Thanks

RewriteCond %{HTTP_REF开发者_开发百科ERER} !^http://(www\.)?domain.com/.*$ [NC] 
RewriteRule \.(gif|jpg|png)$ - [F,NC,L]


I would redirect hot linkers via a RewriteRule to a given PHP site, and then process and save data like IP address ($_SERVER['REMOTE_ADDR']), referer ($_SERVER['HTTP_REFERER']), user agent ($_SERVER['HTTP_USER_AGENT']) and visit timestamp to database (e.g. MySQL) OR a single file.
But you have to take care not to overload server with lots of database/file writes (if there are many hotlinkers).

I tested my solution below, it works.

.htaccess file:

RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://(www\.)?domain.com/.*$ [NC] 
RewriteRule .*\.(jpe?g|gif|bmp|png)$ log_hotlinkers.php [L]

log_hotlinkers.php file:

<?php

    // I use PDO with a wrapper class
    require_once($_SERVER['DOCUMENT_ROOT'].'/PHP/classes/class.DB.php');

    $session_return_value = session_start();

    // is is already stored (per session)?
    $is_stored = (bool)!empty($_SESSION['user_visit_stored']);

    // we store this hotlinker only once per session
    if( !$is_stored ){

        // IP address
        $IP_address = $_SERVER['REMOTE_ADDR'];
        // user agent variable is not always set, in this case we set variable to "unknown"
        $HTTP_USER_AGENT = !empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'unknown';

        // session id
        $session_id = session_id();            

        // the $_SERVER['HTTP_REFERER'] variable is not always set (in this case we will store it with a NULL value)
        $HTTP_REFERER = !empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : 'NULL';



        // we store hotlinker's data in MySQL database (e.g. in a table called hotlinkers with an auto_increment id with the following fields)

        $query  = 'INSERT INTO hotlinkers ( IP_address, user_agent, session_id,  HTTP_REFERER ) ';
        $query .= '       VALUES ( :REMOTE_ADDR, :HTTP_USER_AGENT, :session_id, :HTTP_REFERER ) ;';

        // I use PDO with a wrapper class
        $stmt = DB::getDB()->prepare($query);
        $stmt->bindParam(':REMOTE_ADDR',     $IP_address );      // IP address
        $stmt->bindParam(':HTTP_USER_AGENT', $HTTP_USER_AGENT ); // user agent
        $stmt->bindParam(':session_id',      $session_id );      // session_id()
        $stmt->bindParam(':HTTP_REFERER',    $HTTP_REFERER );    // referer

        $exec_result = $stmt->execute();
        if( $exec_result ){
            // we store that agent is beállítjuk a megfelelő session-változót: a látogató eltárolva
            $_SESSION['user_visit_stored'] = true;
            $_SESSION['user_visit_time'] = time();
        }
        else{
            // throw new PDOException('Couldn\'t store hotlinker\'s data...');
        }   
    }

    // we output another image which signs blocking

    $path = './block-hotlinking-image.png';

    $im = imagecreatefrompng($path);

    header('Content-Type: image/png');

    imagepng($im);
    imagedestroy($im);

?>

In MySQL, my hotlinker table's structure is the following:

CREATE TABLE `hotlinkers` (
   `id` int(11) not null auto_increment,
   `IP_address` varchar(40) not null default '0.0.0.0',
   `visit_timestamp` timestamp not null default CURRENT_TIMESTAMP,
   `user_agent` text not null,
   `session_id` char(32) not null,
   `HTTP_REFERER` varchar(255),
   PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

You can test hotlinking here: Hotlink checker.
I hope this was helpful.


I don't know about possibility of loging something by .htacess command. I think the easiest is to analyse the apache access.log files. It should contain the REFERER already, if not, use the LogFormat directive.


All forbidden access logs are already in your access.log file. It should be accessible from the client panel of your hosting.

If you do not have access to them, the only solution would be to redirect these request to php file (or other script), which would log them and send forbidden header to the browser.

0

精彩评论

暂无评论...
验证码 换一张
取 消