Inotify-tools + php script for Linux Server File monitoring and email reminder,
Requirement Description:
Because servers are infected with Trojans and are often written into sensitive html pages, leaders are often invited to drink tea by cyber police, you know. Therefore, there are two requirements: one is to find out the server's Trojan backdoor and fix code vulnerabilities, and the other is to monitor the server's files involving addition, deletion, modification, and query.
The first is not included in this discussion, so we only need to talk about the second requirement.
Inotify introduction:
Inotify is a Linux feature that monitors file system operations, such as reading, writing, and creating. Inotify is responsive, easy to use, and much more efficient than the busy polling of cron tasks. Learn how to integrate inotify into your application and discover a group of command line tools that can be used to further automate system governance. (From Baidu Baike inotify)
Inotify-tools is a tool that simplifies the use of the inotify service.
Install inotify-tools.
Server System: centos 6.5 file directory:/data/rise purpose: to record and save logs when any files in the/data/rise Directory change.
Specific operations:
1. Install inotify-tools
1. Check whether the server kernel supports the inotify service.Command: ll/proc/sys/fs/inotify # list the file directories. The following content is displayed, indicating that the server supports Note: Linux supports inotify with a minimum kernel of 2.6.13, run the [uname-a] command to check whether the kernel of centOS 5.x is 2.6.32. inotify is supported by default.
2. Install inotify-tools
Yum install make gcc-c ++ # install the compilation tool
Inotify-tools: Click here to download inotify-tools-3.14.tar.gz to the/usr/local/src directory.
cd /usr/local/src
Tar-zxvf inotify-tools-3.14.tar.gz
CD inotify-tools-3.14 enter the unzip directory
. / configure -- prefix = / usr / local / inotify
Make compile
Make install
3. Set Environment Variables
echo "PATH=/usr/local/inotify/bin:$PATH" >>/etc/profile.d/inotify.sh
Source / etc / profile.d/inotify.sh to make the settings take effect immediately
echo "/usr/local/inotify/lib" >/etc/ld.so.conf.d/inotify.conf
ln -s /usr/local/inotify/include /usr/include/inotify
4. Modify the default inotify parameter (the default inotify Kernel Parameter is too small)
Execute the following command to view the results:
Sysctl - a | grep Max ﹐ queued ﹐ events ﹐ the result is: fs.inotify.max ﹐ queued ﹐ events = 16384
Sysctl - a | grep Max ﹐ user ﹐ watches ﹐ the result is: fs.inotify.max ﹐ user ﹐ watches = 8192
Sysctl - a | grep Max ﹐ user ﹐ instances ﹐ the result is: fs.inotify.max ﹐ user ﹐ instances = 128
#Modify the above parameters to the following values
sysctl -w fs.inotify.max_queued_events="99999999"
sysctl -w fs.inotify.max_user_watches="99999999"
sysctl -w fs.inotify.max_user_instances="65535"
#Modification method
VI / etc / sysctl.conf add the following code
fs.inotify.max_queued_events=99999999
fs.inotify.max_user_watches=99999999
fs.inotify.max_user_instances=65535
WQ! Save exit
Parameter description: max_queued_events: Maximum inotify Queue length. If the value is too small, an error "** Event Queue Overflow **" will occur, resulting in inaccurate monitoring files. max_user_watches: the number of directories in the file to be synchronized can be found/home/www.osyunwei.com-type d | wc-l, make sure that the max_user_watches value is greater than the statistical result (here/home/www.osyunwei.com is the synchronization file directory) max_user_instances: maximum value of inotify instance created by each user
2. Create a Real-Time script (skip step 3)
Mkdir -p /home/inotify # create directories
Vim /home/inotify/inotif.sh # edits and adds the following
#! / bin/sh
/ usr/local/way/bin/inotifywait MRQ - e modify, create, move, delete -- fromfile '/ home/way/excludedir' - timefmt '% % y - m - H: % d % % m' - the format '% T % f % e'
/ data/rise / > > / TMP/rsync. TXT
Wq! # save exit
Vim /home/inotify/excludedir # edits and adds the following
/data/rise/ # directory to monitor
@/data/rise/cache/ # to exclude monitored directories
Wq! # save exit
Chmod +x /home/inotify/inotif.sh # add execute permissions
Vim /etc/rc.d. /rc.local # is edited and the following is added on the last line. Boot automatically starts
Sh/home/way/inotif. Sh
Wq! # save exit
Reboot in effect
Reboot takes effect
3. directly run the command manually (this step can be taken if you do not want to create a script)Switch to the directory with inotifywait or directly add the file path to the command. The command is as follows:
/usr/local/inotify/bin/inotifywait -m -r -d -o /tmp/file_change.log --timefmt '%F %T' --format '%T %w%f %e' -e close_write -e create /data/riseweb/ @/data/riseweb/data/ @/data/riseweb/riseimg/
Command Parsing:
/Tmp/file_change.log is the log path. The generated log is written here.
/Data/riseweb/is the monitored file directory, and the following two @ are the directories to be excluded from monitoring.
4. Monitor and send emails using PHP scripts
Implementation ideas:
Create a row_mark.txt file under the/tmpfolder to save the last row of the last file_change.log. Execute the php script regularly in the crontab to obtain the last row of file_change.log, and compare it with the last row of the row_mark file, the numbers are consistent, indicating that no operation logs are added. Hosts file.
Php script code:
<!--?</span--> PHP
/ * *
* Created by PhpStorm.
* the User: jimmyRen
* the Date: 16/10/24
* Time: 1:56 p.m
* main role: check whether there is a new file or folder under the server project directory, if so, send an email notification
* implementation idea: if the server has a new file,inotify will write in/TMP /file_change.log, open the file, get the last line, if the number of lines is greater than 0 or greater than the last saved line, additional write to the number of files, and send an email notification
* /
Require_once (dirname (__FILE__). "/ include/common. Inc., a PHP");
The date_default_timezone_set (" PRC ");
$url = '/ TMP/';
// open the log file
$change_log = file_get_contents ($url. 'file_change. Log);
// open the file that records the number of lines
$row_log = file_get_contents ($url. 'row_mark. Log);
// converts the file into an array per line
$change_array = explodes (" \ n ", $change_log);
$row_array = explodes (" \ n ", $row_log);
// gets the total length of the array
$change_count = count ($change_array);
$row_count = count ($row_array);
// get the key of the last line of the log file
$change_row = $change_count - 2;
// gets the value of the last line of the line file
$row_value = substr ($row_array [$] row_count - 1, 0, strpos ($row_array $row_count [1], "["));
$row_date = date (" Y -m - d H: I: s ", time ());
If ($change_row > 0 && $row_log== "")
$file_write = file_put_contents ($url. 'row_mark. Log, $change_row. "[". $row_date."] ", FILE_APPEND to);
Echo "first write record successful "; The exit;
}elseif($change_row > 0 && $change_row > $row_value){
$file_write2 = file_put_contents ($url. 'row_mark. The log, "\ n". $change_row. "[". $row_date."] ", FILE_APPEND to);
} else {
Echo "current time". The date (" Y -m - d H: I: s ", time ()). "without a new written documents;
The exit;
}
// the number of newly written lines, loop out the newly written contents of the log, generate a file, and then send an email
If ($file_write2) {
Ini_set (" memory_limit ", "512 m");
$new_array = array ();
For ($I = $row_value; $I < $change_row; ${i++)
$new_array [] = "\ n \ r \ n". $change_array ($I);
}
// converts the received array into a string in line format
$text = the implode (" \ n \ r \ n ", $new_array);
$file_time = date (" Y -m - d_H: I ");
// file the contents
$file = fopen ($url. "checkChangeLog". $file_time. ". TXT ", "w +");
If ($file) {
Iconv (" utf-8 ", "GB2312 / / IGNORE", $text);
$write = fwrite ($file, $text);
}
The fclose ($file);
// send an email
The function sendmail ($email, $mailtitle, $mailbody)
{
Global $cfg_sendmail_bysmtp, $cfg_smtp_server, $cfg_smtp_port, $cfg_smtp_usermail, $cfg_smtp_user, $cfg_smtp_password, $cfg_adminemail,$cfg_webname;
If ($cfg_sendmail_bysmtp == 'Y' &&! Empty ($cfg_smtp_server))
{
$mailtype = 'TXT';
Require_once (DEDEINC. '/ mail. Class. PHP);
$SMTP = new SMTP ($cfg_smtp_server, $cfg_smtp_port, true, $cfg_smtp_usermail, $cfg_smtp_password);
$SMTP - > debug = false;
If (! $SMTP - > smtp_sockopen ($cfg_smtp_server)) {
ShowMsg(' message failed, please contact administrator ','-1');
The exit ();
}
$SMTP - > sendmail ($email, $cfg_webname, $cfg_smtp_usermail, $mailtitle, $mailbody, $mailtype);
} else {
@ mail ($email, $mailtitle, $mailbody, $headers);
}
}
$email = "906691 xxx.qq.com"; // fill in the email address to be sent here
$mailtitle = date (" Y -m - d H: I ", time ()). "rise file write situation";
$mailbody = $text;
The sendmail ($email, $mailtitle, $mailbody);
Echo "script executed successfully!" ; The exit;
}
Tip: Remember to load the class that sent the email.
V. crontab scheduled task
It must be executed every 5 hours from to, and every 7-21, once every 1 hour, and once every 2 hours, therefore, the crontab script command is as follows.
# Regularly check Server File write status and send email notifications 0 0-7/5, 7-21/1, 21-23/2 *** php/data/rise/checkfile. php
Vi. Summary
The requirement must have been met. Because it is not professional O & M, this time it has only met the requirement. Great gods have a better way to discuss it.