Friday, October 15, 2010

keeping track of invalid server requests

I like to know what's going on in my server , who scan me ,and how . But mainly i like to keep nosy inspector out of my servers private parts .That is one of the reasons I'm so fond of the denyhosts script. As so I like keeping track of invalid server requests ( 404 page) , since scanning web server for known vulnerabilities is  a common practice this days as much as port scanning .

To do so I've changed my 404 page to log any request ( in fact it is a redirect  ) to a DB. Visitor that get a 404 error in my servers still see the usual 404 page but behind the scenes it logs the request details to a database table.

To do this you first need to have apache + PHP + MySQL installed.
Then establish a MySQL DB ,for this example lets call it "invalidReqests" ,in MySQL prompt type:
 > create database invalidReqests;
and create a new table in it, lets call it "pagerequests " ,which has the fields: id ( int), servername ( varchar 255 ), requestedUrl  ( varchar 255 ) ,clientIp ( varchar 255 ) ,insdate (datetime)
 >CREATE TABLE pagerequests (
          id INT (16) NOT NULL AUTO_INCREMENT ,
          servername VARCHAR(255),
          requestedUrl VARCHAR(255),
          clientIp VARCHAR(255),
          insdate DATATIME,
        );

Create a mysql user and grant insert and select permissions to invalidReqests DB.( google how to to it)
Create a DB connection/ disconnection php file
dbcon.inc.php
<?  $username = "userA";
$password = "reallyStrongOne";
$hostname = "localhost";
$dbh = mysql_connect($hostname, $username, $password)
        or die("Unable to connect to MySQL");

$selected = mysql_select_db("invalidReqests",$dbh)
        or die("Could not select invalidReqests");
?>
 dbdis.in.php
<?
mysql_close($dbh);

?>
This is useful in case you have several sites and you would like each to have different looking  page but record requests to the same DB .
Now create a php file ( or copy your HTML 404 file and post-fix it as php ) 
add the following code ( prefer at the end of page ,so it could partially load in case of a problem ) 
404.php

       <? include 'dbcon.inc.php';
        $ip = $_SERVER["REMOTE_ADDR"];
        $url = $_SERVER["REQUEST_URI"];
        $srvname= $_SERVER["SERVER_NAME"];

        $query= "INSERT INTO pagerequests (servername,requestedUrl,clientIP,insdate)
        values('".$srvname."','".$url. "','".$ip."','".date( "Y-m-d H:i:s"). "')";

        mysql_query ($query);
        include 'dbdis.inc.php'
?>

make apache use it as 404 error page. in apache2.conf replace the line start with ErrorDocument 404 to the page 
 ErrorDocument 404 /404.php
 I also created a simple page to view the table :
404request.php
<center>
<table border="1"  id="table4">
                        <tr>
                                <td align="center"><b>Server name</b></td>
                                <td align="center"><b>Requsted url</b></td>
                                <td align="center"><b>Client ip</b></td>
                                <td align="center"><b>Date</b></td>
                        </tr>
                        <?

                        include 'dbcon.inc.php';

                        $result = mysql_query("SELECT * FROM pagerequests order by id desc limit 50" );
                        while ($row = mysql_fetch_array($result,MYSQL_ASSOC)) {
                                print "<tr><td><p align='center'>".
                                $row{'servername'}."</td><td><p align='center'>".
                                $row{'requestedUrl'}."</td><td><p align='center'>".
                                $row{'clientIp'}."</td> <td><p align='center'>"
                                .$row{'insdate'}." </td></tr>";
                        }
                        include 'dbdis.inc.php'
                        ?>
                </table>
</center>