SSH不正アクセス集計プログラム

投稿日: 2008年5月18日 | カテゴリ:『自宅サーバー』>自作プログラム

SSHのポートを開放しておくと大量のピンポンダッシュ攻撃を受けることは周知の事実となています。今回は、secureログをベースにして不正アクセスしてきたIPアドレスとその情報を集計し、表示するプログラムを作成してみました。

プログラムの特徴

  1. SSHで鍵方式のアクセスだけを許可している条件で、secureログに残る不正アクセスをベースに集計し、表示します。集計項目は、不正アクセスしてきたIPアドレス、アタック回数、アタック開始時刻、アタック切断時刻、継続時間です。表示する件数を指定することができます。
  2. 複数アタックしてきたIPアドレスの集計を行い、表示します。集計項目はIPアドレス、アタック開始時刻とアタック切断時刻、及び複数アタックの件数とアタック回数の合計となります。これにより、悪質なIPアドレスを特定することができます。
  3. 不正アクセスしてきたIPアドレスの情報を全て表示します。項目は、IPアドレス、切断時刻と不正入力ユーザー名です。表示する件数を指定することができます。
  4. アクセスを承認されたユーザーの情報を集計します。集計項目は、最初の表で、IPアドレス、アクセス回数、最後のログイン時刻、及び別の表で、IPアドレス、ユーザー名とログイン時刻となります。これにより、不正ユーザーのアクセスが承認されていないかを監視すると共に、正規のユーザーのログイン情報をモニターすることができます。

以下は、集計プログラムのサンプルです。承認アクセス集計プログラムはセキュリティ上IPアドレスを変更しています。
不正アクセス集計プログラム・サンプル
承認アクセス集計プログラム・サンプル

実行方法

    1. SSHの設定を認証不可に設定し、ユーザーの認証を鍵方式(注1)に切り替えます。
      /etc/ssh/sshd.configを編集し以下の設定を行います。

      PermitRootLogin no
      PasswordAuthentication no
      PermitEmptyPasswords no
      

      最初の設定は、rootでのログインを禁止する設定です。#PermitRootLogin yesの行の#を削除し、上記のように書き換えます。
      2番目は、通常のpasswordでのログインを禁止する設定です。
      最後は、空パスワードの禁止設定です。
      以上の設定をすれば、/var/log/secureに次のような不正アクセスのログが残ります。必ずsecureログを確認し、次のようなログが記録されているか確認してください。

      Feb 27 20:54:07 localhost sshd[13049]: Invalid user murray from XXX.XXX.XXX.XXX
      Feb 27 20:54:07 localhost sshd[13050]: input_userauth_request: invalid user murray
      Feb 27 20:54:07 localhost sshd[13050]: Received disconnect from XXX.XXX.XXX.XXX: 11: Bye Bye
      

      1行目はユーザー(murray)を入力してアクセスを試みていますが、システムに不正と認識されています(以下、この行をInvalid行と呼びます)。XXX.XXX.XXX.XXXは不正アクセスのIPアドレスです。localhostのところはコンピュータ名によって異なります。
      2行目は認証が認められなかったことを示します。
      3行目は当該IPアドレスから切断の信号を受け取ったことを示しています(以下、この行をDis行と呼びます)。
      1、2行目がなく3行目だけの場合もありますので、集計プログラムは3行目(Dis行)を基本にして不正アクセスの集計を行っています。
      注(1):鍵方式の設定についてはさしあたり次のサイトを参照してください。
      「初めての自宅サーバー:SSH2の鍵作成」

    2. ファイルのダウンロードと解凍
      次のパッケージをダウンロードしてください。
      sshlog_package.tar

      1. ダウンロードしたパッケージを解凍します。例えば、rootディレクトリで解凍すれば/root/pakageディレクトリに全てのファイルが解凍されます。
      2. sshlog_invalid.php(不正アクセス集計プログラム)とsshlog_accept.php(承認アクセス集計プログラム)を実行可能にします。次に、/rootに/programディレクトリを作成し、これらのファイルをコピーします。
      3. /var/www/html/sshlogディレクトリを作成し、invalid_html.phpとaccept_html.phpをコピーします。sshlogディレクトリのパーミッションを再帰的に755に設定します。
      4. 以上の作業が終わったら、sshlog_package.tgzと/root/packageディレクトリを削除してください。

以下にプロセスの流れを示します。

[root]# tar -xf sshlog_package.tgz
[root]# mkdir /root/program
[root]# cd /root/package
[root@package]# ls
accept_html.php  invalid_html.php  sshlog_accept.php  
sshlog_invalid.php
[root@package]# chmod 700 sshlog_invalid.php
[root@package]# chmod 700 sshlog_accept.php
[root@package]# ls -l
-rw-r--r-- 1 root root 1728 2008-03-23 05:24 accept_html.php
-rw-r--r-- 1 root root 2221 2008-03-28 03:20 invalid_html.php
-rwx------ 1 root root 3819 2008-03-23 05:01 sshlog_accept.php
-rwx------ 1 root root 6222 2008-04-23 03:51 sshlog_invalid.php
[root@package]# cp sshlog_invalid.php /root/program/
[root@package]# cp sshlog_accept.php /root/program/
[root@package]# mkdir /var/www/html/sshlog
[root@package]# cp invalid_html.php /var/www/html/sshlog/
[root@package]# cp accept_html.php /var/www/html/sshlog/
[root@package]# chmod -R 755 /var/www/html/sshlog
[root@package]# ls -l /var/www/html/sshlog
-rwxr-xr-x 1 root root  1728 2008-05-18 04:41 accept_html.php
-rwxr-xr-x 1 root root  2221 2008-05-18 04:40 invalid_html.php
[root@package]# cd ../
[root]# rm sshlog_package.tgz
rm: remove 通常ファイル `sshlog_package.tgz'? y
[root]# rm -rf package

次に、sshlog_invalid.phpファイルを適当なエディタで開いて次の部分を編集してください。

$myip="192.168.X";
$dis_limit=50;
$inv_limit=200;

1行目は、集計対象にしたくないローカルのIPアドレスを、指定します。以上の設定をすれば、ローカルPCからのアクセスが万が一不正アクセスの対象となる場合でも集計から除外されます。Xの部分はルータによって異なってきます。
2行目は、Dis行の表示行数を必要に応じて設定します。
3行目は、Invalid行の表示行数を必要に応じて設定します。
サーバー名をデフォルト以外に変えた場合(つまり、localhost.localdomainでない場合)には、「Dis行:ファイルから獲得した情報を整理」と「Invalid行:ファイルから獲得した情報を整理」の各7行目の「localhost」を自身のサーバー名に変更してください(secureログを確認のこと)。

次に、sshlog_accept.phpファイルを適当なエディタで開いて次の部分を編集してください。

$acc_limit=20;
$all_limit=200;

1行目は、集計するユーザーの数を指定します。正規のログインユーザーの数よりも多めに設定してください。というのは、不正アクセスが承認された場合のスペースを空けておく必要があるからです。
2行目は、ユーザーのログイン履歴の表示行数を指定します。
サーバー名をデフォルト以外に変えた場合(localhost.localdomainでない場合)には、「localhost」の部分を自身のサーバー名に変更してください。

    1. sshlogディレクトリは一般ユーザーのアクセスが可能なので、集計結果を一般に公開したくない場合には、次のように設定してローカルからのアクセスだけを可能にします。/etc/httpd/conf.dディレクトリにsshlog.confファイルを作成し、次の行を書き加えます。192.168.X.のXはルータによって異なります。
vi /etc/httpd/conf.d/sshlog.conf
<Directory "/var/www/html/sshlog">
    Options None
    AllowOverride None
    Order deny,allow
    Deny from all
    Allow from 192.168.11.
</Directory>

httpを再起動して上記の設定を有効にします。

[root] /etc/rc.d/init.d/httpd restart
httpd を停止中:                                    [  OK  ]
httpd を起動中:                                    [  OK  ]
    1. プログラムを実行させるシェルス・スクリプトを作ります。このスクリプトを実行可能にし、root権限で実行します。スクリプトの2行目と5行目のコメントアウト#を削除すれば、ログが残ります。
      [root]# vi mksshlog.sh
      #!/bin/sh
      #LOG=/var/log/mkssh.log
      php /root/program/sshlog_invalid.php > /dev/null
      php /root/program/sshlog_accept.php > /dev/null
      #echo "`date` SSHLOGを集計しました。">>$LOG
      [root]# chmod 700 /root/mksshlog.sh
      [root]# ./mksshlog.sh
      

      うまく実行されれば、sshlogディレクトリにaccept_all.txt、accept_sum.txt、dis_sum.txt、header.txt、header2.txt、inv_sum.txt、multi_access.txtファイルができているはずです。確認してください。
      定期的に実行する場合にはcrontabに登録してください。次の例は3時間ごとに02分に集計を行う設定です。

      [root]# crontab -e
      02 */3 * * * /root/mksshlog.sh
      

 

  1. 以上の作業を終了したら、ローカルPC(サーバーが接続されているルータ配下にあるPC)からhttp://192.168.X.X/sshlog/invalid_html.phpにアクセスします。192.168.X.Xはサーバーがルーターによって割り当てられたローカルIPアドレスです。Xの部分はルータによって異なります。アクセスが成功すれば、サンプルの様な集計表が表示されるはずです。但し、不正アクセスがまだない段階では、ラベルだけの表示になります

プログラムの詳細説明
以下は、プログラムの内容説明です。閲覧の便宜上、長い行は改行してありますので、本体のプログラムとは一部レイアウトが異なっています。PHPの場合、途中で改行しても区切り文字「;」があるのでプログラムの内容には変化はありません。
プログラムの変更が必要な場合に活用してください。

設定部分
$logdir="/var/log";
$htmldir="/var/www/html/sshlog";
$myip="192.168.X";
$dis_limit=50;
$inv_limit=200;

1行目:Secureログのあるディレクトリを指定
2行目:HTML作成ファイルを置くディレクトリを指定
3行目:アクセスするローカルIPアドレスを指定。Xはルータによって異なります
4行目:Dis行の表示数を指定
5行目:Invalid行の表示数を指定

SSHログファイルから必要な情報を取得
$dirh = opendir("$logdir");
$dis_AR=array();
$inv_AR=array();
while ($file = readdir($dirh)){
  if (ereg("^secure",$file)){
    if (! $fp = @fopen("$logdir/$file", "r")){
      print "Could not open file<BR>";
      exit();
    }
    while (! feof($fp)){
      $data = fgets($fp);
      if (ereg("Received disconnect", $data) && 
         !ereg("$myip",$data)){
      $rep_data=str_replace("  "," ",$data);
      array_push($dis_AR,$rep_data); 
      }elseif(ereg("Invalid user", $data) && 
       !ereg("$myip",$data)){
      $rep_data=str_replace("  "," ",$data);
      array_push($inv_AR,$rep_data); 
      }
    }
    fclose($fp);
  }
}

1行目:ログ ディレクトリを開く
2~3行目:配列変数の定義
4行目:ログ ディレクトリのファイルを変数$fileに取得するループの開始
5行目:取得したファイルがsecureで始まっていれば以下を実行
6~9行目:取得ファイルを開く規定のスクリプト
10行目:ファイル終端(EOF)まで以下を実行するループの開始
11行目:変数dataにファイルの各行を読み込む
12~13行目:この行が「 Received disconnect 」を含み、myipを含まなければ以下を実行
14行目:2重スペースを単一スペースに変換。一桁の日付の場合には二重スペースになる(例えば、「Jan 6」)。この場合、行を分割する際にエラーが発生する
15行目:加工された行を配列に保存
16~17行目:「 Invalid user 」を含み、myipを含まなければ以下を実行
18行目:2重スペースを単一スペースに変換(後に、行を分割する際のエラーを防ぐため)
19行目:加工された行を配列に保存
22行目:ファイルをクローズ

Dis行:ファイルから獲得した情報を整理
$discon_AR=array();
$date_now = strtotime("now");
foreach ($dis_AR as $factor){
  $split_AR1=split(" Received disconnect from ", $factor);
  $split_AR2=split(":", $split_AR1[1]);
  $ip=$split_AR2[0];
  $split_AR3=split(" localhost ", $split_AR1[0]);
  $date=$split_AR3[0];
  $date_num=strtotime("$date");
  if ($date_num > $date_now){
    $date_num=strtotime("-1 year",$date_num);
  }
  array_push($discon_AR,"$ip<>$date_num"); 
}

1行目:配列変数の定義
2行目:現在の時刻のタイムスタンプを取得
3行目:dis行の情報の保存されている配列について以下を実行
4行目:「 Received disconnect from 」を境にして行を分割しそれを配列に保存
5行目:配列split_AR1の2番目の分割文字列を「:」で分割し、配列split_AR2に保存
6行目:IPアドレスを変数ipに保存
7行目:配列split_AR1の1番目の文字列を「 localhost 」で分割し、配列split_AR3に保存。
[注意]この「 localhost」の部分 は、コンピュータ名のつけ方によって違います。この場合には、インストール時にデフォルトのコンピュータ名を選択しています(localhost.localdomain)。独特な名前を設定した場合には、sshlogを確認してこの部分を修正してください。
8行目:日付部分を変数dateに保存
9行目:日付をタイムスタンプに変換(1970年からの経過秒数)
10~12行目:現時刻よりも大きいタイムスタンプは1年前の日付とみなす。つまり、Secureログに残っている日付は年号を含んでいない(例えば、Feb 11 12:15:23)ので、現時点(例えば2008年2月11日)から遡って1年前の西暦の日付(2007年12月11日)は、2008年12月11日と判断されてしまう。したがって、現時点よりもタイムスタンプの大きい日付は全て1年前の日付に変換する。これによって、年度をまたいての日付の比較が可能になる。
13行目:ipアドレス<>タイムスタンプのフォーマットで配列に保存

Invalid行:ファイルから獲得した情報を整理
$invalid_AR=array();
foreach ($inv_AR as $factor){
  $split_AR1=split(" Invalid user ", $factor);
  $split_AR2=split(" ", $split_AR1[1]);
  $usr=$split_AR2[0];
  $ip=$split_AR2[2];
  $split_AR3=split(" localhost ", $split_AR1[0]);
  $date=$split_AR3[0];
  $date_num=strtotime("$date");
  if ($date_num > $date_now){
    $date_num=strtotime("-1 year",$date_num);
  }
  array_push($invalid_AR,"$date_num<>$ip<>$usr"); 
}

3行目:「 Invalid user 」を境にして行を分割しそれを配列に保存
4行目:配列split_AR1の2番目の文字列を半角スペースで分割し、配列split_AR2に保存
5行目:不正ユーザーを変数usrに保存
6行目:不正IPアドレスを変数ipに保存
7行目:配列split_AR1の1番目の文字列を「 localhost 」で分割し、配列split_AR3に保存
[注意]この「 localhost」の部分 は、コンピュータ名のつけ方によって違います。この場合には、インストール時にデフォルトのコンピュータ名を選択しています(localhost.localdomain)。独特な名前を設定した場合には、sshlogを確認してこの部分を修正してください。
8行目:日付部分を変数dateに保存
9行目:日付をタイムスタンプに変換(1970年からの経過秒数)
10~12行目:現時刻よりも大きいタイムスタンプは1年前の日付とみなす。
13行目:タイムスタンプ<>IP<>ユーザーのフォーマットで配列に保存

Disconnect行の集計
sort($discon_AR);
array_push($discon_AR,"xxx.yyy.zzz.ddd&lt;&gt;10000");
rsort($invalid_AR);
$sum_dis_AR=array();
$nn=count($discon_AR);
$cc=0;$count=0;
for ($aa=0;$aa&lt;=($nn-2);$aa++){
$temp_AR=split("&lt;&gt;", $discon_AR[$aa]);
$ip1=$temp_AR[0];$date1=$temp_AR[1];
$temp2_AR=split("&lt;&gt;", $discon_AR[$aa+1]);
$ip2=$temp2_AR[0];$date2=$temp2_AR[1];
$diff=abs($date2-$date1);
$flag=0;
if ($ip1==$ip2 &amp;&amp; $diff &lt;=60){
$cc++;
if ($cc==1){$dateF=$date1;}
$flag=1;
$count++;
}
if ($count==0 &amp;&amp; $flag==0){
$count++;
$sum_line="$date1&lt;&gt;$count&lt;&gt;$date1&lt;&gt;$ip1";
array_push($sum_dis_AR,$sum_line);
$cc=0;$count=0;
}
if ($count&gt;0 &amp;&amp; $flag==0){
$count++;
$sum_line="$dateF&lt;&gt;$count&lt;&gt;$date1&lt;&gt;$ip1";
array_push($sum_dis_AR,$sum_line);
$cc=0;$count=0;
}
}

1行目:Dis行を保存している配列を先頭のIPでソート。結果は、優先度1:IPごとの並び、優先度2:日付順の並び、となる
2行目:配列の最後にダミー用として1行を追加。配列要素の数をnnとした場合、最初の要素はnn=0となるから、最後の要素はnn-1となる。配列の連続する2要素を比較する場合、最後の比較は、nn-1と仮想配列要素(実際にない要素)となる。この設定で行えば最後の要素もうまく処理される。しかし、PHPはこのような要素を許可していないので、このまま実行するとエラーが出力される。この矛盾を解消するために、ダミー行を最後に挿入している
3行目:Inv行、先頭のTime Stampでソート
4~6行目:変数の定義
7行目:Dis行が保存されている配列のn番目とn+1版目を比較するループの開始
8~11行目:連続した2配列の情報(IPと日付スタンプ)を取得
12行目:連続する日付の差の絶対値($diff)を計算。
13行目:flagを0に設定
14行目:連続する配列のIPが等しく、$diffが60秒よりも小さければ(60秒以上経過してアタックしてきたIPは別口として扱う)、以下を実行
15行目:$ccに1を加える
16行目:$cc=1のときは最初のアタック時刻と想定できるので、これをアタック開始時刻として取得する
17行目:$flagに1を代入
18行目:$countに1を加える
20行目:$count=0(連続するIPが同一でない場合)かつフラグが0(連続するIPが同一でないか、あるいは同一IPアドレスのループを抜けた時)の場合(すなわち、IPのアタック回数が1回の場合)に、以下を実行
21行目:数合わせのためにカウントに1を加える
22行目:保存フォーマットラインの設定(アタック開始時刻+アタック回数+切断時刻+IPアドレス)
23行目:フォーマットラインを配列に保存
24行目:変数ccとcountを初期化
26~30行目:同一IPのアタックが2回以上の場合($countが1以上の場合)、同様の保存フォーマットで配列に保存

複数回アタックのあったIPの取得
rsort($sum_dis_AR);
$ip_AR=array();
$zz=$sum_dis_AR;
foreach ($sum_dis_AR as $data){
  $temp_AR=split("<>", $data);$ip=$temp_AR[3];
  $n=0;$xx=0;
  foreach ($zz as $data1){if (ereg("$ip",$data1)){$n++;}}
  foreach ($ip_AR as $dd){if (ereg("$ip",$dd)){$xx=1;}}
  if ($n >= 2 && $xx==0){array_push($ip_AR,$ip);}
}

1行目:IP集計配列を日付の新しい順にソート
2行目:配列の定義
3行目:ソートしたIP集計配列を比較のために配列zzに代入
4行目:配列sum_dis_ARの全ての要素について以下を実行
5行目:該当する行から変数($ip)を取得
6行目:変数の初期化
7行目:配列zzの全ての要素について$ipが含まれていたら$nに1を加える
8行目:配列$ip_ARに$ipが含まれていたら$xxに1を加える
9行目:もし$nが2よりも大きく(同一IPが複数回アタックしている)かつ $xxが0(配列ip_ARに$ipが含まれていない=2重登録を避けるため)場合、$ipを配列ip_ARに保存する。この配列を基にして次の集計を行う。

複数回アタックのあったIPの集計と保存フォーマット作成
$sameip_sum=array();
foreach ($ip_AR as $ip){
  $n=0;$sum_count=0;
  foreach ($sum_dis_AR as $data){
  if (ereg("$ip",$data)){
    $temp_AR=split("<>",$data);
    $dateF=$temp_AR[0];$count=$temp_AR[1];
    $date=$temp_AR[2];$ip2=$temp_AR[3];
    $sum_count+=$count;$n++;
    $date1=date("n月j日 G:i:s",$dateF);
    $date2=date("n月j日 G:i:s",$date);
    $line="

<TR align=\"center\">

<TD>$ip2</TD>


<TD>$count</TR>


<TD>$date1</TD>


<TD>$date2</TD>

</TR>


\n";
    array_push($sameip_sum,$line);
    }
  }
  $line="

<TR bgcolor=\"#ccffff\" align=\"center\">
    

<TD>計$n 回</TD>


<TD>合計$sum_count 回</TD>


<TD>***</TD>


<TD >***</TD>

</TR>


\n";
  array_push($sameip_sum,$line);
}

1行目:配列の定義
2行目:配列ip_ARの各要素(複数アタックしてきたIP)に対して以下の処理を行う。
3行目:変数の初期化
4行目:配列sum_dis_ARの各要素に対して次の処理を行う。
5行目:要素dataが複数アタックipを含んでいたら次を実行
6行目:要素dataを<>で分割
7~8行目:アタック時刻、アタック回数、切断時刻とipを変数に代入
9行目:$sum_countは、同IPアドレスのアタック回数の和、$nはアタックしてきた回数
10行目:開始時刻のタイムスタンプを日付に変換
11行目:切断時刻のタイムスタンプを日付に変換
12~13行目:HTML方式で保存フォーマット作成(ipアドレス+アタック回数+開始時刻+切断時刻)
14行目:配列の保存
17~19行目:ipの集計結果(ipの複数アタック件数、アタック回数)の保存フォーマット
20行目:配列に保存

[追記](2008年9月16日)バグを発見。12行目の保存フォーマットで<TD>$count</TR>は、<TD>$count</TD>の間違い。IEでうまく表示されていたので気がつかなかった。FireFoxで表示してみた所、表示が乱れたので気がついた。sshlog_package.tgzには修正済みのプログラムを入れ替えてあります。

Dis行:保存フォーマット作成
$n=0;
$dis_save=array();
foreach ($sum_dis_AR as $data){
$temp_AR=split("&lt;&gt;",$data);$dateF=$temp_AR[0];
$count=$temp_AR[1];$dateL=$temp_AR[2];$ip=$temp_AR[3];
$n++;
$diff=abs($dateL-$dateF);
if ($diff &lt;= 60){
$dtime="$diff 秒";
}else{
$min=floor($diff/60);$sec=$diff%60;$dtime="$min 分$sec 秒";
}
$date1=date("n月j日 G:i:s", $dateF);
$date2=date("n月j日 G:i:s", $dateL);
$line="

$n$ip$count$date1$date2$dtime

\n";
array_push($dis_save,$line);
if ($n&gt;=$dis_limit){break;}
}

3行目:配列sum_dis_ARの各要素に対して以下の処理を行う
4~5行目:要素を<>で分割して、アタック時刻、アタック回数、切断時刻とipを変数に代入
6行目:nに1を加える。
7行目:開始時刻と切断時刻の差の絶対値($diff)を計算する
8行目:絶対値が60秒よりも少なければ、次を実行
9行目:変数$dtimeに「$diff 秒」を代入
10行目:60秒よりも大きければ、分+秒に変換し、変数$dtimeに「$min 分$sec 秒」を代入
11行目:開始時刻のタイムスタンプを日付に変換
13行目:切断時刻のタイムスタンプを日付に変換
15~18行目:HTML方式で保存フォーマット作成(ipアドレス+アタック回数+開始時刻+切断時刻)し、配列に保存する
19行目:指定した行数を過ぎたらプロセスを終了し、ネストを抜ける

Invalid行:保存フォーマット作成
$n=0;
$inv_save=array();
foreach ($invalid_AR as $data){
  $temp_AR=split("<>",$data);$date=$temp_AR[0];
  $ip=$temp_AR[1];$usr=$temp_AR[2];
  $n++;
  $date1=date("n月j日 G:i:s", $date);
  $line="

<TR>

<TD align=\"center\">$n</TD>


<TD>$ip</TD>


<TD>$date1</TD>


<TD>$usr</TD>

</TR>


\n";
  array_push($inv_save,$line);
  if ($n>=$inv_limit){break;}
}

3行目:配列invalid_ARの各要素に対して以下の処理を行う
4~5行目:要素を<>で分割して、アタック時刻、IPアドレス、入力ユーザー名を変数に代入
6行目:nに1を加える。
7行目:切断時刻のタイムスタンプを日付フォーマットに変換
8~10行目:HTML方式で保存フォーマット作成し、配列に保存
11行目:指定した行数を過ぎたらプロセスを終了し、ネストを抜ける

Dis行の集計情報を保存
if (! $fp1 = @fopen("$htmldir/dis_sum.txt", "w")){
  print "Could not open file<BR>";
  exit();
}
foreach($dis_save as $data){
  fwrite($fp1,$data);
}
fclose($fp1);

1~4行目:dis_sum.txtファイルを上書き形式で開く
5~7行目:配列$dis_saveに保存してあったデータをdis_sum.txtnに保存
8行目:ファイルを閉じる

Invalid行集計情報を保存
if (! $fp2 = @fopen("$htmldir/inv_sum.txt", "w")){
  print "Could not open file<BR>";
  exit();
}
foreach ($inv_save as $data){
  fwrite($fp2,$data);
}
fclose($fp2);

Dis行に同じ

複数アタックの集計データを保存
if (! $fp3 = @fopen("$htmldir/multi_access.txt", "w")){
  print "Could not open file<BR>";
  exit();
}
foreach ($sameip_sum as $data){
  fwrite($fp3,$data);
}
fclose($fp3);

同上

プログラム実行時の時刻を保存
$datenow=date("n月j日 G時i分");
if (! $fp4 = @fopen("$htmldir/header.txt", "w")){
  print "Could not open file<BR>";
  exit();
}
$head="$datenow";
fwrite($fp4,$head);
fclose($fp4);

ファイルを作成した時刻をheader.txtに保存



コメントを残す




空欄に計算式を満たす数値を記入してください(必須)