apacheのアクセスログ(/var/log/apache2/access.log.*)を解析し、存在しないファイルのアクセスを試みるアクセス元のIPとアクセスのRequestなどを表示します。
ステップ1:一次処理。定期的にスクリプトを実行して不審なアクセス元のトップ5を出力する。(アクセス回数、アクセス元IP、国コード)
ステップ2:ブサウザーからの「ログ表示」の要求にしたがって、過去7日分の表を表示する。表中のアクセス元IPをクリックしたら、生ログ(/var/log/apache2/access.log*)からR該当する行を表示する。
cat /var/log/apache2/access.log /var/log/apache2/access.log.1 | /usr/bin/php /root/apt.php
ステップ1:apt.phpのソースコード
#!/usr/bin/php
<?php
$TOP=5;
$PATH="/var/www/html/log"; // 1次処理結果の保存先
$mDB=array('Jan','Feb','Mar','Apr','May','Jun','Jly','Aug','Sep','Oct','Nov','Dec');
$fp=fopen("php://stdin","r");
while($in=fgets($fp)){
$t=explode(' ',$in);
$ip=$t[0];
$tmp=substr($t[3],1);
$s=explode('/',$tmp);
$day=$s[0];
$year=substr($s[2],0,4);
$mo=array_search($s[1],$mDB)+1;
if($mo<10) $mo='0'.$mo;
$date=$year.$mo.$day;
#echo "$ip,$year$mo$day\n";
if(strpos($in,' 404 ')>0){
@$buf[$date][$ip]++;
}
}
fclose($fp);
arsort($buf);
foreach($buf as $date =>$ip_array){
arsort($ip_array);
echo "---$PATH/$date---\n";
$fw=fopen("$PATH/$date.txt","w");
$n=0;
foreach($ip_array as $ip =>$count){
// echo "$ip,$count\n";
if(substr($ip,0,10)!='192.168.68' && $ip!='::1'){
try{
$country=geoip_country_code_by_name($ip);
if(trim($country)=="") $country=`whois $ip | grep -m1 country | awk '{print $2}'`;
} catch (Exception $e ) {
$country=`whois $ip | grep -m1 country | awk '{print $2}'`;
if($country="") $country="??";
}
$country=trim($country);
$msg= "$count $ip $country\n";
fwrite($fw,$msg);
$n++;
if($n>$TOP) break;
}
}
fclose($fw);
}
?>
apt.phpスクリプト出力の一例
968 43.243.222.44 HK
61 92.63.196.29 RU
25 45.155.205.27 RU
16 104.131.73.21 US
6 121.196.182.183 CN
ログ表示のためにブラウザーからアクセスするPHPファイル
<HTML>
<head>
<link rel="stylesheet" type="text/css" href="/st1.css">
</head>
<?php
$TOP=5;
echo "<H3>怪しいアクセス元トップ5</H3>\n";
for($i=0;$i<=7;$i++){
$date=date("Ymd",time()- $i * 60 * 60 * 24); // $i days ago
$file="log/$date.txt";
if(file_exists($file)){
$data=file($file);
$msg="<H3>$date2</H3>\n";
if( $i % 2 ==1 ){
$msg="<TABLE width=400 border=1><CAPTION><B>$date</B></CAPTION><TR>";
} else {
$msg="<TABLE border=1><TD valign=\"top\">\n<TABLE width=400 border=1><CAPTION><B>$date</B></CAPTION><TR>";
}
$n=1;
foreach($data as $line){
$tmp=trim($line);
$t=explode(' ',$tmp);
for($m=0;$m<3;$m++){
if($m==1){
$ip=$t[$m];
$ref="<a href=proc.php?date=$date&ip=$ip>$ip</a>";
$msg.="<TD>$ref</TD>";
} else {
$msg.="<TD>$t[$m]</TD>";
}
}
$msg.="</TR>";
}
if( ($i % 2 ) == 1 ){
$msg.="</TR></TABLE></TD></TABLE>\n";
} else {
$msg.="</TR></TABLE></TD><TD valign=\"top\">";
}
echo "$msg\n";
// print_r($data);
}
}
?>
</HTML>
生ログから該当箇所を抽出するスクリプト
<?php
if (isset($argv)){
$date =$argv[1];
$ip =$argv[2];
} else {
$date = htmlspecialchars($_GET["date"]);
$ip = htmlspecialchars($_GET["ip"]);
}
$mDB=array('Jan','Feb','Mar','Apr','May','Jun','Jly','Aug','Sep','Oct','Nov','Dec');
$year=substr($date,0,4);
$day=substr($date,6,2);
$mo =$mDB[(int)(substr($date,4,2))-1];
$dateS= $day."/".$mo."/".$year;
$name="/var/log/apache2/$f_name";
echo "<H3>DATE:$date IP:$ip</H3>";
echo "\n";
$today = date("Ymd");
$tmp = mktime(0, 0, 0, date("m") , date("d")-1, date("Y"));
$yesterday= date('Ymd',$tmp);
function proc_msg($in,$date,$ip){
$msg="";
if(strpos($in,$ip)===0 && strpos($in,$date)>0){
$in=str_replace(' - - ','',$in);
$in=str_replace(' +0900','',$in);
$t=explode("\"",$in);
$s=explode(':',$t[0]);
$time="$s[1]:$s[2]:$s[3]";
$time=str_replace(']','',$time);
$msg= "<TR><TD>$time</TD><TD>$t[1]</TD><TD>$t[2]</TD></TR>\n";
}
return $msg;
}
function proc($fp,$date,$ip){
$msg= "<table><TR BGCOLOR=lightblue><TD>Time</TD><TD>Request</TD><TD>Result</TD></TR>\n";
$n=strlen($msg);
while ($in=fgets($fp)){
$msg.=proc_msg($in,$date,$ip);
}
if(strlen($msg)>$n){
$msg.="</TABLE>";
echo $msg;
}
fclose($fp);
}
function procGZ($fp,$date,$ip){
$msg= "<table><TR BGCOLOR=lightblue><TD>Time</TD><TD>Request</TD><TD>Result</TD></TR>\n";
$n=strlen($msg);
while ($in=gzgets($fp)){
$msg.=proc_msg($in,$date,$ip);
}
if(strlen($msg)>$n){
$msg.="</TABLE>";
echo $msg;
}
fclose($fp);
}
//echo "$date,$today,$yesterday<BR>";
$off=(int)$today - (int)$date;
if($off<=2){
$fp1=fopen("/var/log/apache2/access.log","r");
proc($fp1,$dateS,$ip);
$fp2=fopen("/var/log/apache2/access.log.1","r");
proc($fp2,$dateS,$ip);
} else {
$off--;
$gz_file="/var/log/apache2/access.log.$off.gz";
echo "$gz_file<BR>\n";
$fp3=gzopen($gz_file,"r");
procGZ($fp3,$dateS,$ip);
}
?>