ツイートする このエントリーを含むはてなブックマーク [rNote Tips]

迷惑投稿ログ採取 / 2011-05-31 (火)

最近迷惑コメントの投稿が間隔を空けて投稿されると言う状態が続いているため
この状況を打開するための情報採取を行いたいと思い簡易的な投稿ログ採取機能を作成してみました。

以下に作成したコードを公開させて頂きます。

☆迷惑投稿ログを採取する(ログ採取関数)

 通常のコメントログでは採取されないエージェント名やIPアドレスを取得して
 ログファイルに出力する以下のコードをrnote_config.phpに追加します。

rnote_config.php

function comLogWrite($msg){
    // 書き込み時間を取得する
    $now = gmdate("Y/m/d(D) h:i a",time()+60*60*9);

    // 投稿IPとホスト名の取得
    $host = $_SERVER['REMOTE_HOST'];
    $ipaddr = $_SERVER['REMOTE_ADDR'];

    if($host == null || $host == $ipaddr){
        $host = gethostbyaddr($ipaddr);
    }

    // 投稿エージェント名の取得
    $agent = $_SERVER['HTTP_USER_AGENT']; 
    $mode = $_POST['mode'];

    // トラックバックの場合
    if(strlen($mode) == 0){
        $mode = "tb";
    }

    // 引数にメッセージがあるときはNGステータスに追加
    if(strlen($msg) > 0){
        $ngstat = $msg;
    }
    else{
        $ngstat = "OK_STATUS";
    }

    // BBSまたは記事コメント
    if($mode == "bbs_write"){
        // 改行コードを<br>に変換
        $comText = nl2br($_POST['tag_Text']);
        // コメントの改行コードを削除
        $comText = str_replace(array("\r\n","\r","\n"), '', $comText);
        // BBSの書き込みの場合(このサイトだと不要だけれど記載)
        $comment = $_POST['tag_AuthorName'] . "\t" . $comText . "\t" . $_POST['tag_AuthorUrl'];
    }
    elseif($mode == "wb_write"){
        // 改行コードを<br>に変換
        $comText = nl2br($_POST['Text']);
        // コメントの改行コードを削除
        $comText = str_replace(array("\r\n","\r","\n"), '', $comText);
        // コメント書き込みの場合
        $comment = $_POST['AuthorName'] . "\t" . $comText . "\t" . $_POST['AuthorUrl'];
    }
    else{
        // 改行コードを<br>に変換
        $comText = nl2br($_POST['excerpt']);
        // コメントの改行コードを削除
        $comText = str_replace(array("\r\n","\r","\n"), '', $comText);
        // トラックバックの場合
        $comment = $_POST['blog_name'] . "\t" . $comText . "\t" . $_POST['url'];
    }

    // 1行分のデータを作成
    $dat = "$now\t$host\t$ipaddr\t$agent\t$mode\t$ngstat\t$comment\n";

    $lines = file("comlog/comlog.log");    // いままでのログを配列に読み込む
    $fp = fopen("comlog/comlog.log","w");  // ログをオープン(空になる)
    fputs($fp, $dat);               // データを書き込む(先頭に)

    // いままでの分を追記
    for($i = 0; $i < 5000; $i++){
        fputs($fp, $lines[$i]);     //(配列0-4998→現ログ1-4999行目)
    }

    fclose ($fp);
}

☆ログ採取関数の設置場所

 ログ採取関数の設置場所は迷惑コメント対策のbbs_writeまたはwb_writeの
 投稿判定を行っているif文の直下に追加することで使えるようになります。

 なお、ログファイルはUTF-8N(BOMなし)形式での保存とパーミッション666の付与
 他ユーザから見えないようにログファイルを格納しているディレクトリへの
 アクセス制限(.htaccessに記述)を忘れず実施してください。

rnote_config.php

    // コメント
    if($_POST['mode']=='wb_write'){
        // 逆引き参照が出来ないホストからの投稿を禁止する
        if(checkReverseHost() != TRUE){
            // 投稿記録の取得(Spam Comment Host Error)
            comLogWrite("NG_SPAM_COMMENT_HOST_ERROR");
            if(ereg('ja', $_SERVER['HTTP_ACCEPT_LANGUAGE'])){
                error('逆引き参照が出来ないホストからの投稿は禁止しています。');
            }
            else{
                error('The contribution no host name is prohibited.');
            }
        }
        // プロクシを使った投稿を禁止する
        if(checkProxy() != FALSE){
            // 投稿記録の取得(Spam Bbs Proxy Error)
            comLogWrite("NG_SPAM_BBS_PROXY_ERROR");
            // 投稿されたブラウザの言語設定によってエラー表示を変える
            if(ereg('ja', $_SERVER['HTTP_ACCEPT_LANGUAGE'])){
                error('プロクシを通しての投稿は禁止しています。');
            }
            else{
                error('The contribution through proxy is prohibited.');
            }
        }

        (省略)

        // 全条件を抜けてきた投稿ログを採取する(採取しない場合は記述しない)
        comLogWrite();
    }

☆ログの内容を表示する

 ログを作成しただけでは毎回FTPにつないでファイルを見なくてはならないため
 同じサイトから確認できるようログ確認用のPHPファイルを作成します。

 このスクリプトではパスワード制限をかけていませんが、出来るだけパスワードによる
 アクセス制限をかける方が望ましいです。

comlog.php

<?php
$title = "rNote Comment Log Viewer";
$back_url = "http://www.hogehoge.com/";

// ヘッダ処理
print "<html>\n<head>\n";
print "<title>$title</title>\n";
print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">";
print "</head><body>\n";
print "<h2>$title</h2><hr />\n";

// ファイルを開く
$contents = @file('comlog/comlog.log');

foreach($contents as $line){
    // 文字列をタブ区切りで分割する
    list($now, $host, $ip, $agent, $stat, $name, $com, $url) = explode("\t", $line);

    // 投稿時刻の表示
    print "Date:$now<br />\n";

    // 投稿ホストの表示(ホスト名が表示される場合はホスト名と一緒に表示)
    $ip_serch = "http://ip-address-lookup-v4.com/lookup.php?ip=".$ip;

    if($host != $ip){
        print "Host:$host (<a href=\"$ip_serch\" target=\"_blank\">$ip</a>)<br />\n";
    }
    else{
        print "Host:<a href=\"$ip_serch\" target=\"_blank\">$ip</a><br />\n";
    }

    // エージェント名を表示する
    if($agent != ""){
        print "Agent:$agent<br />\n";
    }
    else{
        print "Agent:Unknown<br />\n";
    }

    // 書き込み方法を確認する
    if($stat == "bbs_write"){
        print "Method:BBS<br />\n";
    }
    else if($stat == "wb_write"){
        print "Method:Entry Comment<br />\n";
    }
    else{
        print "Method:TrackBack<br />\n";
    }

    // NGステータス(OK_STATUS)を表示する
    print "Status:$ngstat<br />\n";

    // 投稿者名を表示する
    if($name != ""){
        print "Name:$name<br />\n";
    }
    else{
        print "Name:Unknown<br />\n";
    }

    // コメントを表示する
    $com = htmlspecialchars($com);
    $com = str_replace('&lt;br /&gt;', '<br />', $com);
    print "Comments:<br />".autoLinker($com)."<br />\n";

    // 投稿URLを表示する
    if(preg_match('/^(http|HTTP|ftp)(s|S)?:\/\/+[A-Za-z0-9]+\.[A-Za-z0-9]/',$url)){
        $aguse_url = "http://www.aguse.jp/?m=w&url=".$url."&x=0&y=0";
        print "URL:<a href=\"$aguse_url\" target=\"_blank\">$url</a><br />\n";
    }
    elseif(preg_match('/^(http|HTTP|ftp)(s|S)?:\/\//',$url)){
        $aguse_url = "http://www.aguse.jp/?m=w&url=".$url."&x=0&y=0";
        print "URL:<a href=\"$aguse_url\" target=\"_blank\">$url</a><br />\n";
    }
    else{
        if(strlen($url)>=1){
            print "Error URL Value:".$url."<br />\n";
        }
    }

    print "<hr />\n";
}

print "<a href=\"$back_url\">Back rNote Site</a><br />\n";
print "</body>\n</html>\n";

// $str にURLが含まれていたらリンク
function autoLinker($str){
    $pat_sub = preg_quote('-._~%:/?#[]@!$&\'()*+,;=', '/'); // 正規表現向けのエスケープ処理
    $pat  = '/((http|https):\/\/[0-9a-z' . $pat_sub . ']+)/i'; // 正規表現パターン
    // \\1が正規表現にマッチした文字列に置き換わります
    $rep  = '<a href="http://www.aguse.jp/?m=w&url=\\1&x=0&y=0" target=\"_blank\">\\1</a>';
    $str = preg_replace ($pat, $rep, $str); // 実処理
    return $str;
}

?>