Sunday, May 22, 2011

Shell script 搭配 ipfw table 阻擋入侵 sshd 攻擊

自己用來偷懶的 script. 自動化使用 ipfw table 阻擋 IP 也會在定義時間後判斷是否有繼續受到攻擊, 再決定是否將該 IP 解除鎖定.

1. ipfw table 語法
${fwcmd} add 06000 set 5 deny log tcp from table\(3\) to any dst-port PORT1,PORT2 in via ${INTIF}
${fwcmd} add 06000 set 5 deny log tcp from table\(4\) to any dst-port PORT11,PORT12 in via ${INTIF}

2. authlog_banip_init.sh (只需要執行一次)
#!/usr/local/bin/bash

LOGFILE="/var/log/auth.log"
PROCFOLDER="/var/log/auth_sshd_banip"
TOTALBANLOGFILE="/var/log/auth_sshd_banip.log"
TODAYLOGFM=`date +%b %d`

TODAY=`date +"%Y%m%d"`
OLDDAY=`date -v-30d +"%Y%m%d"`
OLDYEAR=`date -v-30d +"%Y"`

fwcmd="/sbin/ipfw"

echo "Prepare folder and file"
mkdir -p $PROCFOLDER
touch $TOTALBANLOGFILE

if [ `cat $LOGFILE | grep sshd | grep "Invalid user" | awk '{ print $10 }' | sort -n | sort -u | wc -l` -ne 0 ]; then
 echo "Write pre-process file"
 cat $LOGFILE | grep sshd | grep "Invalid user" | awk '{ print $10 }' | sort -n | sort -u > $PROCFOLDER/sshdpre-$TODAY.log

 echo "Collect new ban IP"
 for ip in $(awk '{ print }' $PROCFOLDER/sshdpre-$TODAY.log)
 do
  if [ `grep $ip $PROCFOLDER/sshd-*.log | wc -l` -gt 0 ]; then
   echo $ip "Old bad boy"
  else
   echo $ip
   
   touch $PROCFOLDER/sshd-$TODAY.log
   echo $ip >> $PROCFOLDER/sshd-$TODAY.log
   echo $ip >> $TOTALBANLOGFILE
  fi
 done

 echo "Ban bad boy"
 if [ -f $PROCFOLDER/sshd-$TODAY.log ]; then
  for banip in $(awk '{ print }' $PROCFOLDER/sshd-$TODAY.log)
  do
   #Ban IP
   echo $banip
   
   ${fwcmd} table 3 add $banip/32
   ${fwcmd} table 4 add $banip/32
  done
 else
  echo "No bad boy"
 fi

 echo "Rescue good boy"
 if [ -f $PROCFOLDER/sshd-$OLDDAY.log ]; then
  for rescueip in $(awk '{ print }' $PROCFOLDER/sshd-$OLDDAY.log)
  do
   #Rescue IP
   echo $rescueip
   
   if [ `grep $rescueip $PROCFOLDER/sshd-*.log | wc -l` -eq 1 ]; then
    ${fwcmd} table 3 delete $rescueip/32
    ${fwcmd} table 4 delete $rescueip/32
    
    grep -v $rescueip $TOTALBANLOGFILE > /tmp/stillbanip-$TODAY
    cp /tmp/stillbanip-$TODAY $TOTALBANLOGFILE
    echo "Rescued"
   else
    echo "Still bad boy"
   fi
  done
  
  #Move to old folder
  echo "Move old file to storage folder"
  mkdir -p $PROCFOLDER/$OLDYEAR
  mv $PROCFOLDER/sshd*-$OLDDAY.log $PROCFOLDER/$OLDYEAR
 else
  echo "No candidate file"
 fi
 
else
 echo "No bad boy"
fi

3. authlog_banip.sh
#!/usr/local/bin/bash

LOGFILE="/var/log/auth.log"
PROCFOLDER="/var/log/auth_sshd_banip"
TOTALBANLOGFILE="/var/log/auth_sshd_banip.log"
TODAYLOGFM=`date +%b %d`

TODAY=`date +"%Y%m%d"`
OLDDAY=`date -v-30d +"%Y%m%d"`
OLDYEAR=`date -v-30d +"%Y"`

fwcmd="/sbin/ipfw"

echo "Prepare folder and file"
mkdir -p $PROCFOLDER
touch $TOTALBANLOGFILE

if [ `cat $LOGFILE | grep "$TODAYLOGFM" | grep sshd | grep "Invalid user" | awk '{ print $10 }' | sort -n | sort -u | wc -l` -ne 0 ]; then
 echo "Write pre-process file"
 cat $LOGFILE | grep "$TODAYLOGFM" | grep sshd | grep "Invalid user" | awk '{ print $10 }' | sort -n | sort -u > $PROCFOLDER/sshdpre-$TODAY.log

 echo "Collect new ban IP"
 for ip in $(awk '{ print }' $PROCFOLDER/sshdpre-$TODAY.log)
 do
  if [ `grep $ip $PROCFOLDER/sshd-*.log | wc -l` -gt 0 ]; then
   echo $ip "Old bad boy"
  else
   echo $ip
   
   touch $PROCFOLDER/sshd-$TODAY.log
   echo $ip >> $PROCFOLDER/sshd-$TODAY.log
   echo $ip >> $TOTALBANLOGFILE
  fi
 done

 echo "Ban bad boy"
 if [ -f $PROCFOLDER/sshd-$TODAY.log ]; then
  for banip in $(awk '{ print }' $PROCFOLDER/sshd-$TODAY.log)
  do
   #Ban IP
   echo $banip
   
   ${fwcmd} table 3 add $banip/32
   ${fwcmd} table 4 add $banip/32
  done
 else
  echo "No bad boy"
 fi

 echo "Rescue good boy"
 if [ -f $PROCFOLDER/sshd-$OLDDAY.log ]; then
  for rescueip in $(awk '{ print }' $PROCFOLDER/sshd-$OLDDAY.log)
  do
   #Rescue IP
   echo $rescueip
   
   if [ `grep $rescueip $PROCFOLDER/sshd-*.log | wc -l` -eq 1 ]; then
    ${fwcmd} table 3 delete $rescueip/32
    ${fwcmd} table 4 delete $rescueip/32
    
    grep -v $rescueip $TOTALBANLOGFILE > /tmp/stillbanip-$TODAY
    cp /tmp/stillbanip-$TODAY $TOTALBANLOGFILE
    echo "Rescued"
   else
    echo "Still bad boy"
   fi
  done
  
  #Move to old folder
  echo "Move old file to storage folder"
  mkdir -p $PROCFOLDER/$OLDYEAR
  mv $PROCFOLDER/sshd*-$OLDDAY.log $PROCFOLDER/$OLDYEAR
 else
  echo "No candidate file"
 fi
 
else
 echo "No bad boy"
fi

4. 在 crontab 加上
59      23      *       *       *       root    /PATH/TO/authlog_banip.sh

5. 開機時執行 authlog_banip.sh
5.1. 在 /etc/rc.local 加上
### For Firewall
/PATH/to/authlog_banip_boot.sh

5.2. authlog_banip_boot.sh
#!/usr/local/bin/bash

TOTALBANLOGFILE="/var/log/auth_sshd_banip.log"
fwcmd="/sbin/ipfw"

if [ -f $TOTALBANLOGFILE ]; then
 for banip in $(awk '{ print }' $TOTALBANLOGFILE)
 do
  #Ban IP
  echo $banip
  
  ${fwcmd} table 3 add $banip/32
  ${fwcmd} table 4 add $banip/32
 done
else
 echo "No bad boy"
fi

No comments: