Knowing when a file on your server changes

  • camperjohn
  • Guru
  • Guru
  • User avatar
  • Posts: 1127
  • Loc: San Diego

Post 3+ Months Ago

I had someone the other day trying to get into my site. Just off the cuff, I wrote this script to hopefully alert me if he actually gets in.

It takes a snapshot of my server, and emails me if there are any new files, or if any existing files change. It allows me to monitor what I want, yet exclude log file folders that I know will change.

So when I work on the site, I get an email about every hour of the things that change on the server. I am hoping that if this guy does get in, I may get an email at 10pm while I am at a party, telling me a file has changed and I should take action.

I have this on a cron job every 15 minutes.

PHP Code: [ Select ]
 
 
    // Sanity test on server files - email self when something changes
    sanity_test_folders();
   
//
// Snapshot sanity test of server
//
 
function sanity_test_folders()
{
    // Load up old filelist snapshot
    $snn = '/home/yoursite/include/cache/snapshot-latest.txt';
    $f = @file_get_contents($snn);
   
    // Create new filelist snapshot, '.*\.html$'        
    $a = directory_to_array("/home/yoursite/include",true,array('^/home/yoursite/include/cache$','^/home/yoursite/include/apps/yoursite/logs$'));
    $a = array_merge($a,directory_to_array("/home/yoursite/public_html",false,array('^/home/yoursite/public_html/cl_cache$')));
    $a = array_merge($a,directory_to_array("/home/yoursite/public_html/images",true));
    $a = array_merge($a,directory_to_array("/home/yoursite/public_html/ads",true));
    $a = array_merge($a,directory_to_array("/home/yoursite/public_html/cron",true,array("^/home/yoursite/public_html/cron/cache$")));
    $a = array_merge($a,directory_to_array("/home/yoursite/public_html/captcha",true));
    $a = array_merge($a,directory_to_array("/home/yoursite/public_html/bugs",true));
    $a = array_merge($a,directory_to_array("/home/yoursite/public_html/uploads",true));
    $a = array_merge($a,directory_to_array("/home/photof/public_html",true,array('/home/photof/public_html/cache','.*\.jpg$','.*\.nfo$','.*\.css$','.*\.rss$','.*\.txt$','.*\.gif$','.*\.ico$')));
           
    // Save out latest snapshot
    @unlink($snn);
    logprintf($snn,serialize($a));
   
    // Compare old and new
    if ($f != '')
    {
        $diff = sanity_filelist_cmp($a,unserialize($f));
 
        $t = '';
       
        // Construct email of everything that changed and email to john
        if (is_array($diff['newfiles']))
        {
            $t .= "<h2>New Files</h2><br /><table class=\"cp\"><tr><td><b>Filename</b></td><td><b>File Size</b></td><td><b>File Date</b></td></tr>";
           
            foreach ($diff['newfiles'] as $k => $l)
            {
                $t .= "<tr><td>$k</td><td>{$l['filesize']}</td><td>{$l['filetime']}</td><br />";
            }
           
            $t .= "</table>";
        }
 
        if (is_array($diff['olddeleted']))
        {
            $t .= "<h2>Deleted Files</h2><br /><table class=\"cp\"><tr><td><b>Filename</b></td><td><b>File Size</b></td><td><b>File Date</b></td></tr>";
           
            foreach ($diff['olddeleted'] as $k => $l)
            {
                $t .= "<tr><td>$k</td><td>{$l['filesize']}</td><td>{$l['filetime']}</td><br />";
            }
           
            $t .= "</table>";
        }
 
        if (is_array($diff['changed']))
        {
            $t .= "<h2>Changed Files</h2><br /><table class=\"cp\"><tr><td><b>Filename</b></td><td><b>Original Size</b></td><td><b>New Size</b></td><td><b>Last Date</b></td><td><b>New Date</b></td></tr>";
           
            foreach ($diff['changed'] as $k => $l)
            {
                $t .= "<tr><td>$k</td><td>{$l['originalfilesize']}</td><td>{$l['filesize']}</td><td>{$l['originalfiledate']}</td><td>{$l['filedate']}</td></tr>";
            }
           
            $t .= "</table>";            
        }
 
        if ($t != '')
        {
            // Save out archived snapshot
            $snnarchive = '/home/yoursite/include/cache/snapshot-' . date("m.d.y.g.ia") . '.txt';        
            logprintf($snnarchive,serialize($a));
 
            // Mail self harcoded
            include (INCLUDE_PATH . '/lib/class.mailer.php');        
            mm_sendemail("SERVER FILES CHANGED!","john@mccarthy.net","SERVER FILES CHANGED!","john@mccarthy.net","SERVER FILES CHANGED!","<html><head><style>.cp tr td { padding:2px; }</style></head><body>$t</body></html>",$t);
       
            echo "<style>.cp tr td { padding:2px; }</style>" . $t;
        }
    }
}
 
// This is the meat of the function. Compare old and new snapshots
function sanity_filelist_cmp($a,$b)
{
    $ak = array_keys($a);
    $bk = array_keys($b);
   
    // Check for changed files
    foreach ($a as $k => $l)
    {
        if (($b[$k]['filesize'] != $a[$k]['filesize']) || ($b[$k]['filedate'] != $a[$k]['filedate']))
        {
            $changed[$k] = array_merge($l,array('originalfilesize' => $b[$k]['filesize'],'originalfiledate' => $b[$k]['filedate']));
        }
    }
 
    // Check for new files or deleted files    
    foreach ($a as $k => $l)
    {
        if (!in_array($k,$bk))
        {
            // New file, old doesn't exist
            $newfiles[$k] = $l;
           
            // Don't duplicate files that are new as they show up in changed list also
            unset($changed[$k]);
        }
    }
   
    foreach ($b as $k => $l)
    {
        if (!in_array($k,$ak))
        {
            // Old file deleted, new doesn't exist
            $olddeleted[$k] = $l;
 
            // Don't duplicate files that are new as they show up in changed list also
            unset($changed[$k]);
        }
    }
       
    $tr['newfiles']   = $newfiles;
    $tr['olddeleted'] = $olddeleted;
    $tr['changed']    = $changed;
   
    return $tr;
}
 
// Get all files, sizes and timestamps of a folder. Exclude regular expression patterns on folders or files (for log file folders)
function directory_to_array($directory, $recursive, $patterns = '')
{
    if (is_array($patterns)) { $patterns = '!' . implode('|',$patterns) . '!'; }
    $array_items = array();
   
    if ($handle = opendir($directory))
    {
        while (false !== ($file = readdir($handle)))
        {
            if ($file != "." && $file != "..")
            {
                $file = $directory . "/" . $file;
               
                if (($patterns == '') || (!@preg_match($patterns,$file)))
                {
                    if (is_dir($file))
                    {
                        if ($recursive)
                        {
                            $array_items = array_merge($array_items, directory_to_array($file, $recursive, $patterns));
                        }
                    }
 
                    $filedate = date ("F d Y g:ia",filemtime($file));
                    $filesize = filesize($file);
                    $filename = preg_replace("/\/\//si", "/", $file);
                                       
                    $array_items[$filename] = array('filedate' => $filedate,'filesize' => $filesize);
                }
            }
        }
 
        closedir($handle);
    }
 
    return $array_items;
}
 
 
 
 
  1.  
  2.  
  3.     // Sanity test on server files - email self when something changes
  4.     sanity_test_folders();
  5.    
  6. //
  7. // Snapshot sanity test of server
  8. //
  9.  
  10. function sanity_test_folders()
  11. {
  12.     // Load up old filelist snapshot
  13.     $snn = '/home/yoursite/include/cache/snapshot-latest.txt';
  14.     $f = @file_get_contents($snn);
  15.    
  16.     // Create new filelist snapshot, '.*\.html$'        
  17.     $a = directory_to_array("/home/yoursite/include",true,array('^/home/yoursite/include/cache$','^/home/yoursite/include/apps/yoursite/logs$'));
  18.     $a = array_merge($a,directory_to_array("/home/yoursite/public_html",false,array('^/home/yoursite/public_html/cl_cache$')));
  19.     $a = array_merge($a,directory_to_array("/home/yoursite/public_html/images",true));
  20.     $a = array_merge($a,directory_to_array("/home/yoursite/public_html/ads",true));
  21.     $a = array_merge($a,directory_to_array("/home/yoursite/public_html/cron",true,array("^/home/yoursite/public_html/cron/cache$")));
  22.     $a = array_merge($a,directory_to_array("/home/yoursite/public_html/captcha",true));
  23.     $a = array_merge($a,directory_to_array("/home/yoursite/public_html/bugs",true));
  24.     $a = array_merge($a,directory_to_array("/home/yoursite/public_html/uploads",true));
  25.     $a = array_merge($a,directory_to_array("/home/photof/public_html",true,array('/home/photof/public_html/cache','.*\.jpg$','.*\.nfo$','.*\.css$','.*\.rss$','.*\.txt$','.*\.gif$','.*\.ico$')));
  26.            
  27.     // Save out latest snapshot
  28.     @unlink($snn);
  29.     logprintf($snn,serialize($a));
  30.    
  31.     // Compare old and new
  32.     if ($f != '')
  33.     {
  34.         $diff = sanity_filelist_cmp($a,unserialize($f));
  35.  
  36.         $t = '';
  37.        
  38.         // Construct email of everything that changed and email to john
  39.         if (is_array($diff['newfiles']))
  40.         {
  41.             $t .= "<h2>New Files</h2><br /><table class=\"cp\"><tr><td><b>Filename</b></td><td><b>File Size</b></td><td><b>File Date</b></td></tr>";
  42.            
  43.             foreach ($diff['newfiles'] as $k => $l)
  44.             {
  45.                 $t .= "<tr><td>$k</td><td>{$l['filesize']}</td><td>{$l['filetime']}</td><br />";
  46.             }
  47.            
  48.             $t .= "</table>";
  49.         }
  50.  
  51.         if (is_array($diff['olddeleted']))
  52.         {
  53.             $t .= "<h2>Deleted Files</h2><br /><table class=\"cp\"><tr><td><b>Filename</b></td><td><b>File Size</b></td><td><b>File Date</b></td></tr>";
  54.            
  55.             foreach ($diff['olddeleted'] as $k => $l)
  56.             {
  57.                 $t .= "<tr><td>$k</td><td>{$l['filesize']}</td><td>{$l['filetime']}</td><br />";
  58.             }
  59.            
  60.             $t .= "</table>";
  61.         }
  62.  
  63.         if (is_array($diff['changed']))
  64.         {
  65.             $t .= "<h2>Changed Files</h2><br /><table class=\"cp\"><tr><td><b>Filename</b></td><td><b>Original Size</b></td><td><b>New Size</b></td><td><b>Last Date</b></td><td><b>New Date</b></td></tr>";
  66.            
  67.             foreach ($diff['changed'] as $k => $l)
  68.             {
  69.                 $t .= "<tr><td>$k</td><td>{$l['originalfilesize']}</td><td>{$l['filesize']}</td><td>{$l['originalfiledate']}</td><td>{$l['filedate']}</td></tr>";
  70.             }
  71.            
  72.             $t .= "</table>";            
  73.         }
  74.  
  75.         if ($t != '')
  76.         {
  77.             // Save out archived snapshot
  78.             $snnarchive = '/home/yoursite/include/cache/snapshot-' . date("m.d.y.g.ia") . '.txt';        
  79.             logprintf($snnarchive,serialize($a));
  80.  
  81.             // Mail self harcoded
  82.             include (INCLUDE_PATH . '/lib/class.mailer.php');        
  83.             mm_sendemail("SERVER FILES CHANGED!","john@mccarthy.net","SERVER FILES CHANGED!","john@mccarthy.net","SERVER FILES CHANGED!","<html><head><style>.cp tr td { padding:2px; }</style></head><body>$t</body></html>",$t);
  84.        
  85.             echo "<style>.cp tr td { padding:2px; }</style>" . $t;
  86.         }
  87.     }
  88. }
  89.  
  90. // This is the meat of the function. Compare old and new snapshots
  91. function sanity_filelist_cmp($a,$b)
  92. {
  93.     $ak = array_keys($a);
  94.     $bk = array_keys($b);
  95.    
  96.     // Check for changed files
  97.     foreach ($a as $k => $l)
  98.     {
  99.         if (($b[$k]['filesize'] != $a[$k]['filesize']) || ($b[$k]['filedate'] != $a[$k]['filedate']))
  100.         {
  101.             $changed[$k] = array_merge($l,array('originalfilesize' => $b[$k]['filesize'],'originalfiledate' => $b[$k]['filedate']));
  102.         }
  103.     }
  104.  
  105.     // Check for new files or deleted files    
  106.     foreach ($a as $k => $l)
  107.     {
  108.         if (!in_array($k,$bk))
  109.         {
  110.             // New file, old doesn't exist
  111.             $newfiles[$k] = $l;
  112.            
  113.             // Don't duplicate files that are new as they show up in changed list also
  114.             unset($changed[$k]);
  115.         }
  116.     }
  117.    
  118.     foreach ($b as $k => $l)
  119.     {
  120.         if (!in_array($k,$ak))
  121.         {
  122.             // Old file deleted, new doesn't exist
  123.             $olddeleted[$k] = $l;
  124.  
  125.             // Don't duplicate files that are new as they show up in changed list also
  126.             unset($changed[$k]);
  127.         }
  128.     }
  129.        
  130.     $tr['newfiles']   = $newfiles;
  131.     $tr['olddeleted'] = $olddeleted;
  132.     $tr['changed']    = $changed;
  133.    
  134.     return $tr;
  135. }
  136.  
  137. // Get all files, sizes and timestamps of a folder. Exclude regular expression patterns on folders or files (for log file folders)
  138. function directory_to_array($directory, $recursive, $patterns = '')
  139. {
  140.     if (is_array($patterns)) { $patterns = '!' . implode('|',$patterns) . '!'; }
  141.     $array_items = array();
  142.    
  143.     if ($handle = opendir($directory))
  144.     {
  145.         while (false !== ($file = readdir($handle)))
  146.         {
  147.             if ($file != "." && $file != "..")
  148.             {
  149.                 $file = $directory . "/" . $file;
  150.                
  151.                 if (($patterns == '') || (!@preg_match($patterns,$file)))
  152.                 {
  153.                     if (is_dir($file))
  154.                     {
  155.                         if ($recursive)
  156.                         {
  157.                             $array_items = array_merge($array_items, directory_to_array($file, $recursive, $patterns));
  158.                         }
  159.                     }
  160.  
  161.                     $filedate = date ("F d Y g:ia",filemtime($file));
  162.                     $filesize = filesize($file);
  163.                     $filename = preg_replace("/\/\//si", "/", $file);
  164.                                        
  165.                     $array_items[$filename] = array('filedate' => $filedate,'filesize' => $filesize);
  166.                 }
  167.             }
  168.         }
  169.  
  170.         closedir($handle);
  171.     }
  172.  
  173.     return $array_items;
  174. }
  175.  
  176.  
  177.  
  178.  
  • Anonymous
  • Bot
  • No Avatar
  • Posts: ?
  • Loc: Ozzuland
  • Status: Online

Post 3+ Months Ago

Post Information

  • Total Posts in this topic: 1 post
  • Users browsing this forum: No registered users and 2 guests
  • You cannot post new topics in this forum
  • You cannot reply to topics in this forum
  • You cannot edit your posts in this forum
  • You cannot delete your posts in this forum
  • You cannot post attachments in this forum
 
 

© 1998-2014. Ozzu® is a registered trademark of Unmelted, LLC.