Linux Tips

Menu

Cron

Cron

定時cron agentの追加

analog用の3時間間隔と、cron動作試験用の5分間隔のagent追加

/etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=logwatcher
HOME=/

# run-parts
01 * * * * root run-parts /etc/cron.hourly
01 0,3,6,9,12,15,18,21 * * * root run-parts /etc/cron.3hourly # この行を追加
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly

0-59/5 * * * * root run-parts /etc/cron.5min # この行を追加

0-59/5 * * * * root /usr/bin/mrtg /etc/mrtg/mrtg.cfg

レポートメール送信先の設定

/etc/log.d/conf/logwatch.conf
・MAILTO=rootをlogwatcherに変更
/etc/crontab
・MAILTO=rootをlogwatcherに変更
/etc/cron.weekly/tcpanalog.cron
・MAILTO=をlogwatcher@bravotouring.comに変更
/etc/cron.weekly/qmailanalog.cron
・MAILTO=をlogwatcher@bravotouring.comに変更

ログ解析用cronスクリプト

セキュリティホールを狙った不正アクセスの傾向をチェックしやすくする為に、ログ情報からレポートを作成してメールでするスクリプト。

/etc/cron.daily/logchk.cron
#!/bin/sh
#

MAILTO=logwatcher@bravotouring.com
MAILFROM=cron@bravotouring.com
MAILSUBJECT="security check"

# メール送信用出力ファイル
#
outfile=/tmp/$$mail.$RANDOM
trap 'rm -f $outfile' 0 1 2 3 5 9 15
touch $outfile

# ログに出力される日付が英語なのでusモードに
#
LANG=us;

# "perl: warning: Setting locale failed"の抑制
export PERL_BADLANG=0

# イベント抽出対象:昨日
#
TARGET='yesterday'
TARGET_DATE=`date -d "$TARGET" | awk '{printf("%s %2d",$2,$3)}'`;
TARGET_MONTH=`date -d "$TARGET" | awk '{print $2}'`;
TARGET_DAY=`date -d "$TARGET" | awk '{print $3}'`;
#TARGET_ACCDATE=`date -d "$TARGET" | awk '{printf("%02d/%s/%4d",$3,$2,$1)}'  | sed 's:/:\\\\/:g'`;
TARGET_ACCDATE=`date -d "$TARGET" | awk '{printf("%02d/%s/%4d",$3,$2,$1)}'`;

date | awk '{print "'$0' working at " $0}' >> $outfile

#
# routerのパケット廃棄ログをポート毎にサマライズし
# Internetからのポートスキャンの傾向などを分析
#
# format:
# Nov 30 21:25:42 router WAN:MSQ: Discard packet. TCP(218.049.***.***,4393 -> 211.127.***.***,1433)
# $1  $2    $3      $4     $5       $6      $7    $8  $9  $10 $11 $12 $13

# 日毎ログ出力ファイル
TMPLOG=/tmp/$$.dailylog

# IPアドレス出力ファイル
ADRFILE=/tmp/$$adr.$RANDOM

echo -e "\n# router packet discard summarize at $TARGET_DATE" >> $outfile
echo -e "#---------------------------------------\n" >> $outfile

grep "^$TARGET_DATE" /var/log/message* > $TMPLOG

# sed 's/(/ /g' $LOGFILE | sed 's/)/ /g' | sed 's/,/ /g' \
# | awk -v host=router -v month=$TARGET_MONTH -v day=$TARGET_DAY -v adrfile=$ADRFILE '
 sed -e "s/[(),]/ /g" -e 's/\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\):\([0-9]*\)/\1 \2/g' $TMPLOG \
 | awk -v host=router -v adrfile=$ADRFILE '
   BEGIN {
     max_port = 0;
     totals = 0;
   }
   /Discard packet./ {
     src_ip = $9;
     print $9 >> adrfile; # 国別のアタック数を検出する為のアドレス抽出
     if ( $8 == "ICMP" ){
       portnum = 1;
     } else {
       portnum = $13 + 1;
     }
     counts[portnum]++;
     totals++;
     if ( max_port < portnum ) max_port = portnum;
   }
   /last message repeated/ {
#     if ($1 == month && $2 == day && $4  == host && 0 < portnum){
     if ($4 == host && 0 < portnum){
       counts[portnum] += $8;
       totals += $8;
     }
   }
   END {
     close(adrfile);
     printf("total: %d packets discarded.\n", totals);
     print "detail\t port\t: packets";
     i=0;
     while (i<=max_port){
       if ( 0 < counts[i] ) {
         if ( i == 1 ){
           printf("\t ICMP\t: %5d\n", counts[i]);
         } else {
           printf("\t%5d\t: %5d\n", i-1, counts[i]);
         }
       }
       i++;
     }
   }' >> $outfile
rm -f $TMPLOG

#
# 国別のアタック数カウント
#
echo -e "\n# per countries" >> $outfile
echo -e "#---------------------------------------\n" >> $outfile
cat $ADRFILE \
  | /home/yano/etc/cron.sh/what_country.pl \
  | /home/yano/etc/cron.sh/count_cctld.pl >> $outfile
rm -f $ADRFILE

#
# apache accessログより、Code RedのMS01-033アタック数抽出
#
# format:
# 217.151.***.*** - - [07/Dec/2002:08:16:08 +0900] "GET /default.ida?NNNNNNNNNNNNNNNNN NNNNN…
#

LOGFILE=/var/log/httpd/access_log*

# ログファイルから処理対象期間のイベントを抽出する
#
TMPLOG=/tmp/$$.acclog
grep --no-filename $TARGET_ACCDATE $LOGFILE >$TMPLOG 2>/dev/null

echo -e "\n# apache access_log check at $TARGET_DATE" >> $outfile
echo -e "#---------------------------------------\n" >> $outfile

for CHKSTRING in 'default\.ida\?NNNNNNNNNNNNNN';
do
 echo -e "\nlookup CodeRed --\n" >> $outfile

 awk ' /'$CHKSTRING'/ ' $TMPLOG \
   | sed -e 's/\[//g' -e 's/\]//g' -e 's/(//g' -e 's/)//g' -e 's/:/ /'  \
   | awk '{print " at " $5 " from " $1}' >> $outfile
done

for CHKSTRING in 'default\.ida\?XXXXXXXXXXXXXX';
do
 echo -e "\nlookup CodeRed II --\n" >> $outfile

 awk ' /'$CHKSTRING'/ ' $TMPLOG \
   | sed -e 's/\[//g' -e 's/\]//g' -e 's/(//g' -e 's/)//g' -e 's/:/ /'  \
   | awk '{print " at " $5 " from " $1}' >> $outfile
done

for CHKSTRING in '\/c\/winnt\/system32\/cmd.exe';
do
 echo -e "\nlookup Nimda --\n" >> $outfile

 awk ' /'$CHKSTRING'/ ' $TMPLOG \
   | sed -e 's/\[//g' -e 's/\]//g' -e 's/(//g' -e 's/)//g' -e 's/:/ /'  \
   | awk '{print " at " $5 " from " $1}' >> $outfile
done

rm -f $TMPLOG

#
# apache errorログからノイズを取り除いて出力
#
# format:
# [Sun Dec  1 10:56:00 2002] [error] [client 211.*.*.*] File does  not exist: /var/www/html/MSADC/root.exe
#

LOGFILE=/var/log/httpd/error_log*
echo -e "\n# apache error_log check at $TARGET_DATE" >> $outfile
echo -e "#---------------------------------------\n" >> $outfile

awk -v month=$TARGET_MONTH -v day=$TARGET_DAY '$2 == month && $3 == day &&am p; /error/' $LOGFILE \
 | awk '! /client 192\.168\.199\./ && ! /winnt/ && ! /root\.exe/i && amp; ! /default\.ida/i && \
        ! /NULL\.IDA/i && ! /robots\.txt/ && ! /favicon\. ico/' \
 | sed -e 's/\[error\] //g' -e 's/\[client /[/g'   >> $outfile


#
# apache SSLエラーログより、
# SSLセキュリティホールを狙ったアタック数抽出
#
# format:
# [Sun Dec  1 10:56:00 2002] [error] [client 211.*.*.*] File does not exist: /var/www/html/MSADC/root.exe
#

LOGFILE=/var/log/httpd/ssl_error_log*
echo -e "\n# ssl_error_log check at $TARGET_DATE" >> $outfile
echo -e "#---------------------------------------\n" >> $outfile

for CHKSTRING in `cat /etc/logchk/ssl_error_log`;

do
 echo -e "lookup keyword by -- $CHKSTRING --\n" >> $outfile

 awk -v str=$CHKSTRING -v month=$TARGET_MONTH -v day=$TARGET_DAY '
  $2 == month && $3 == day { if ($0 ~ str) print} ' $LOGFILE \
   | sed -e 's/\[//g' -e 's/\]//g' -e 's/(//g' -e 's/)//g' \
    | awk '{print " at " $4 " from " $14}' >> $outfile
done

#
# メール送信
#

(echo "To: $MAILTO"
echo "From: $MAILFROM"
echo "Subject: $MAILSUBJECT for $TARGET_DATE"
echo ""
cat $outfile )| /var/qmail/bin/qmail-inject -f $MAILFROM
参照
不正アクセスの発信地の国別統計をとろう!http://www.mtl.t.u-tokyo.ac.jp/~nminoru/memo/ip-address/what_country_from.html

ダウンロード支援cronスクリプト

出先でナローバンド環境だったり自分のパソコンではなかったりして、直接ダウンロードできない場合に自宅サーバーでダウンロードさせる為の仕組み。/home/yano/down/todolist/に任意のファイル名でURLのリストを作成すれば、5分以内にwgetを起動して/home/yano/down/pool/にダウンロードを行う。エラーが発生した場合はcronがメッセージをキャプチャしてメールで送ってくれる。

download.cron
#!/bin/sh
#
# URLリスト指示でファイルをダウンロードする
#
#      /etc/cron.5min/download.cron

HOMEDIR=/home/yano/down
OWNMODE=yano:members
QUEUE=$HOMEDIR/todolist/*
DOWNLOG=$HOMEDIR/wget.log
BACKDIR=$HOMEDIR/backup
LOCKFILE=$HOMEDIR/wornking

PATH="/usr/local/bin:$PATH"
LANG=ja_JP.eucJP
export LANG

cd $HOMEDIR

if [ -f $LOCKFILE ]; then
  exit 1
fi

trap 'rm -f $LOCKFILE' 0 1 2 3 5 9 15
touch $LOCKFILE

cd pool

for infile in $QUEUE;
do
  if [ -f $infile ]; then
    date >> $DOWNLOG ;

# サイトによって--referer を設定する
#====================
    REFERER="";
    if (grep '/zm[0-9]*\.zip$' $infile >/dev/null;) ; 
    then REFERER="--referer=http://erozanmai.com/html/download.htm";
    elif (grep '/m[0-9]*\.zip$' $infile >/dev/null;) ; 
    then REFERER="--referer=http://crystalmiss.com/";
    fi;

    wget -nv -a $DOWNLOG --input=$infile $REFERER; # ダウンロード

# 最初のファイルがダウンロードできてたらinfileを待避
#===================================================
    fname=`head -1 $infile | sed 's#^.*/\([_@+\-\.0-9A-z]*$\)#\1#'`
    if [ -f $fname ]; then

      $HOMEDIR/dlremake.pl $infile;      # ダウンロードできなかったファイルを抽出してリストの再作成
      mv $infile $BACKDIR ;     # ファイルリストの待避
      sudo chown $OWNMODE *   2>/dev/null ;

    fi
  fi
done
dlremake.pl
#!/usr/local/bin/perl
#
# ダウンロードファイルがpoolされるディレクトリで実行すること。
#

$infile = shift @ARGV; # URLリストファイル名

# urllist に読み出し

open(IN, $infile);
@urllist=<IN>;
close(IN);

# poolに無いものをnewlist にピックアップ

foreach $url ( @urllist )
{
  $fname = $url;
  $fname =~ s/^.*\/([_@+\-\.\w]*)\s$/$1/;
  if ( ! -e "$fname" ){
    push @newlist, $url;
  }
}

# newlist が空でなければファイルに書き出し

if ( 0 < $#newlist ){
  $infile =~ s/^(.*)\.\d*$/$1/;
  $outfile = ">".$infile.".".time;
  open(OUT, $outfile);
  print OUT @newlist;
  close(OUT);
}

掲示板ログバックアップcronスクリプト

掲示板のログファイルを毎朝wgetでgetし、tar+gzipで単純なフルバックアップを行う。

#!/bin/sh
#
# /etc/cron.daily/bbsbackup.cron
#
# $HOMEDIR配下の$ID.tar.gzに日付ファイル名でバックアップ作成
# gzip -dc yano.tar.gz | tar tvf

HOMEDIR=/home/yano/backup
CGIURL='http://hpcgi3.nifty.com/yano/yyh.cgi'
IDLIST='yano sawapro'
DATE=`date +%Y%m%d`
OWNMODE=yano:members

PATH="/usr/local/bin:$PATH"
#LANG=ja_JP.eucJP
#export LANG

cd $HOMEDIR

for ID in $IDLIST ;
do
  if [ ! -d $ID ] ;
  then
    mkdir $ID
  fi

  LOGFILE=$ID/$DATE.log;
  wget -Y off -O $LOGFILE "$CGIURL?id=$ID&bak=1" > /dev/null 2>&1
  sudo chown -R $OWNMODE $ID;

  TAR_ARCHIVE=$ID.tar
  if [ -f $TAR_ARCHIVE.gz ] ;
  then
    cp -fp $TAR_ARCHIVE.gz $TAR_ARCHIVE.gz.bak;
    gzip -d $TAR_ARCHIVE.gz;
    tar -uf $TAR_ARCHIVE $ID/*;
  else
    tar -cf $TAR_ARCHIVE $ID;
  fi
  gzip $TAR_ARCHIVE
  sudo chown $OWNMODE $TAR_ARCHIVE.*;
  rm -fr $ID/*
done

Tipsに戻る | Topに戻る

Copyright (c) 2002-2004 by YANO
All rights reserved.