[PLUG] Fwd: xerxes_ipblock

plug_0 at robinson-west.com plug_0 at robinson-west.com
Sun May 15 01:59:36 UTC 2005


The following script calls two support scripts, clean_file504 is
supposed to remove from my list of smtp failures by ip and time
the ip addresses that are blocked.  The mailblock_web_page script
just updates the web page.  The script seems to have a bug, I have
seen the same ip multiple times in a blocks_needed file for the
same day.  Every ip in the blocks_needed and blocked_permanently
file should be unique.  If anyone can spot the bugs, I'd very
much appreciate the help.

     --  Michael Robinson

----- Forwarded message from root <webadmin at robinson-west.com> -----
    Date: Sat, 14 May 2005 18:55:46 -0700 (PDT)
    From: root <webadmin at robinson-west.com>
Reply-To: root <webadmin at robinson-west.com>
 Subject: xerxes_ipblock
      To: plug_0 at robinson-west.com

#!/bin/bash
#
# The purpose of this is to temporarily packet filter ip addresses that
# are getting 504's, 554's, 550's, or 555's on this Postfix relay.
#
# Additionally blocks 450, Domain not found and Host not found errors.
#
# This goes on the primary mail server...


prefix="/root/firewall/mail_504"

file504="$prefix/file504"            
file504bak="$prefix/file504.bak"
maillog="/var/log/maillog"

copy_location_xerxes="$prefix/web_files/file504xerxes"
copy_location_web="$prefix/web_files/file504web"

copy_location_web_pblocks="$prefix/web_files/perm_blocks_web"
copy_location_xer_pblocks="$prefix/web_files/perm_blocks_xerxes"

ipt="$prefix/iptables"

err_terminal="/dev/tty9"
screen_len=100
top_count=0



#echo "Clear file504 of any currently blocked ip's..."

$prefix/clean_file504



# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#echo " Clear the output terminal. "

while [ "$top_count" -le "$screen_len" ]
do
        echo "" > $err_terminal
        let top_count+=1
done

# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



# -s-m-b---s-m-b---s-m-b---s-m-b---s-m-b---s-m-b---s-m-b---s-m-b---s-m-b---smb-
#echo " Mount the network filesystem containing web's block information. "

umount $prefix/web_files 2>/dev/null

mount -t smbfs -o username=smbadmin,password=gizmo02 \
      //web/smbadmin $prefix/web_files 

# -s-m-b---s-m-b---s-m-b---s-m-b---s-m-b---s-m-b---s-m-b---s-m-b---s-m-b---smb-



if [ ! -e $file504 ]
then
    touch $file504
    chmod 600 $file504
fi



# If a file504 from the secondary is available,
# use it...  Protect our own $file504 to avoid
# copying listings from the secondary server
# into our own listings multiple times.

cp -f $file504 $file504bak

# $file504 will be corrupted in this step.

if [ -e $copy_location_web ]
then
    cat $file504bak $copy_location_web > $file504
fi



date_today=`date +%A|tr -s ' '|tr -d ' '`
blocks_needed=$prefix/blocks_needed.$date_today
blocks_Mon="$prefix/blocks_needed.Monday"
blocks_Tue="$prefix/blocks_needed.Tuesday"
blocks_Wed="$prefix/blocks_needed.Wednesday"
blocks_Thu="$prefix/blocks_needed.Thursday"
blocks_Fri="$prefix/blocks_needed.Friday"
blocks_Sat="$prefix/blocks_needed.Saturday"
blocks_Sun="$prefix/blocks_needed.Sunday"
blocked_before="$prefix/ip_block_tmp/blocked_before"
perm_block="$prefix/blocked_permanently"
add_new_blocks="$prefix/ip_block_tmp/add_new_blocks"
all_ip_blocks="$prefix/ip_block_tmp/all_ip_blocks"



#echo "No new blocks have been added..."

if [ -e $add_new_blocks ]
then
     rm -f $add_new_blocks 
     touch $add_new_blocks
     chmod 600 $add_new_blocks
fi



################################################################################
#
#echo "Part 1, Add blocks and ip / date records......"
#
#  Find out any new 'ip date' combinations that should be added to local 
#  $file504bak file from the local maillog adding them to the $file504 
#  file as well.
#
#  Never put ip numbers of the opus mail servers into $file504, $file504bak,
#  or $blocks_needed.
#
#  Update $file504 and $file504bak with every new 'ip date' combination found
#  and count occurrence of ip's added from local maillog to determine if new 
#  blocks are needed.  The file, $file_504bak, is all 'ip date' combinations 
#  on xerxes and web.
#
#  Take the diff of file504bak and file504 to make certain that ip's erring
#  out the third time on web are blocked here.



# CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
# Make sure that an ip address does not match one of opus's ip addresses.
#

opus_1="209.210.200.6"
opus_2="66.45.48.45"
opus_mx="209.210.200.7"
dnsreport="69.2.200.182"
mypcc="209.152.32.70"



opus_check()
{
     local_count=1

     echo "Checking for Opus and other whitelisted sources..." >> $err_terminal


     # Never block backup mail exchangers at Opus or opus itself...
     # Never blocks mx-opus.opusnet.com...
     # Don't block the dnsreport ip address...
     # Don't block the mypcc ip address...
     while [ "$curr_ip" ==   "$opus_1"  ] || \
           [ "$curr_ip" ==   "$opus_2"  ] || \
           [ "$curr_ip" ==   "$opus_mx" ] || \
           [ "$dnsreport" == "$curr_ip" ] || \
           [ "$mypcc"     == "$curr_ip" ]
     do
          let local_count+=1
 
          if [ "$local_count" -le "$count_list" ]
          then
                curr_ip=`echo $list_ip | cut -d ' ' -f $local_count`
          else
                curr_ip=""
                break;
          fi

     done
}

# CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC



     check_ip_date()
     {
          # See if $curr_ip at $list_date_curr already listed on web or xerxes.
          testing=`cat $file504bak 2>/dev/null | grep $curr_ip | grep
$list_date_curr` 

          if [ ! "$testing" ]
          then
             
               # Record in $file504bak and $file504 this new 'ip date' record.
               echo "$curr_ip $list_date_curr" >> $file504bak 2>/dev/null
               echo "$curr_ip $list_date_curr" >> $file504 2>/dev/null
          else
               echo "This $curr_ip at $list_date_curr is already listed." >
$err_terminal
          fi    

          # Find out how many times this ip is recorded on xerxes and web.
          count_this_ip=`cat $file504bak 2>/dev/null | grep $curr_ip | wc -l`

          # If this ip has ip has been recorded three or more times,
          # it should be blocked.  Add it to today's block list if 
          # it's not already on there.
          if [ $count_this_ip -ge 3 ]
          then

               cat $prefix/blocks_needed.* > $all_ip_blocks
               testing=`cat $all_ip_blocks|grep $curr_ip|tail -n1`

               echo -n "Testing for already recorded: " >> $err_terminal
               echo "$testing" >> $err_terminal

               # Add this ip to the block file for today.
               if [ ! "$testing" ]
               then
                    echo "$curr_ip" >> $blocks_needed
                    echo "$curr_ip" >> $add_new_blocks
               fi
          else
               echo "$curr_ip has erred out $count_this_ip times"  > $err_terminal
               echo > $err_terminal
          fi 
     }



#-------------------------------------------------------------------------------
#echo " Added for smtp 450 domain not found errors... "

list_ip=`cat $maillog | grep ' 450 ' | grep 'Domain not found' | cut -d '[' -f3
| cut -d ']' -f1`
smtp450_dnf_date=`cat $maillog | grep ' 450 ' | grep 'Domain not found' | tr -s
' ' | cut -d ' ' -f3`
count_list=` cat $maillog | grep ' 450 ' | grep 'Domain not found' | cut -d '['
-f3 | cut -d ']' -f1 | wc -l | tr -d ' '`

top_count=1

while [ "$top_count" -le "$count_list" ]
do
         curr_ip=`echo $list_ip | cut -d ' ' -f $top_count`

         opus_check

         if [ "$curr_ip" ]
         then

               echo "curr_ip: $curr_ip to check for adding a mail block" >
$err_terminal

               # Grab the time that this ip got into the maillog, HH:MM:SS.
               list_date_curr=`echo $smtp450_dnf_date | cut -d ' ' -f $top_count`

               check_ip_date

         fi

         let top_count+=1

done

#-------------------------------------------------------------------------------



#-------------------------------------------------------------------------------
#echo " Added for smtp 450 host not found errors... "

list_ip=`cat $maillog | grep ' 450 ' | grep 'Host not found' | cut -d '[' -f3 |
cut -d ']' -f1`
smtp450_hnf_date=`cat $maillog | grep ' 450 ' | grep 'Host not found' | tr -s '
' | cut -d ' ' -f3`
count_list=`cat $maillog | grep ' 450 ' | grep 'Host not found' | cut -d '[' -f3
| cut -d ']' -f1 | wc -l | tr -d ' '`

top_count=1

while [ "$top_count" -le "$count_list" ]
do
         curr_ip=`echo $list_ip | cut -d ' ' -f $top_count`
         
         opus_check

         if [ "$curr_ip" ]
         then

               echo "curr_ip: $curr_ip to check for adding a mail block" >
$err_terminal

               # Grab the time that this ip got into the maillog, HH:MM:SS.
               list_date_curr=`echo $smtp450_hnf_date | cut -d ' ' -f $top_count`

               check_ip_date
         fi

         let top_count+=1

done

#-------------------------------------------------------------------------------



#-------------------------------------------------------------------------------
#echo " Check general 5[0-9][0-9] errors... "

list_ip=`cat $maillog | grep ' 5[0-9][0-9] ' | cut -d '[' -f3 | cut -d ']' -f1`
gen_list_date=`cat $maillog | grep ' 5[0-9][0-9] ' | tr -s ' ' | cut -d ' ' -f3`
count_list=`cat $maillog | grep ' 5[0-9][0-9] ' | cut -d '[' -f3 | cut -d ']'
-f1 | wc -l | tr -d ' '`

top_count=1

while [ "$top_count" -le "$count_list" ]
do
         curr_ip=`echo $list_ip | cut -d ' ' -f $top_count`

         opus_check

         if [ "$curr_ip" ]
         then
               echo "curr_ip: $curr_ip to check for adding a mail block" >
$err_terminal
 

               # Grab the time that this ip got into the maillog, HH:MM:SS.
               list_date_curr=`echo $gen_list_date | cut -d ' ' -f $top_count`

               check_ip_date
         fi

         let top_count+=1

done

#-------------------------------------------------------------------------------



#-------------------------------------------------------------------------------
# If there's a file called $add_new_blocks, then there are
# probably new drops to be added to maili and mailo.

new_blocks()
{
if [ -e $add_new_blocks ]
then

     new_blocks_length=`cat $add_new_blocks | wc -l`

     top_count=1

     while [ $top_count -le $new_blocks_length ]
     do

        curr_ip=`cat $add_new_blocks | tail -n $top_count | head -n1`

        echo "Adding: $curr_ip" > $err_terminal

  testing=`$ipt -nL bad_maili|grep $curr_ip|tr -s ' ' | cut -d ' ' -f4|tail -n1`

        # If $current_block_ip isn't blocked in bad_maili, 
        # put it in bad_maili and bad_mailo.
        if [ ! "$testing" ]
        then

           $ipt -A bad_maili -p tcp -s  $curr_ip --dport 25  -j DROP
           $ipt -A bad_maili -p udp -s  $curr_ip --dport 25  -j DROP
           $ipt -A bad_maili -p tcp -s  $curr_ip --dport 465 -j DROP
 
           $ipt -A bad_mailo -p tcp -d  $curr_ip --dport 25  -j DROP
           $ipt -A bad_mailo -p udp -d  $curr_ip --dport 25  -j DROP
           $ipt -A bad_mailo -p tcp -d  $curr_ip --dport 465 -j DROP

        fi

        let top_count+=1

     done

fi
}

new_blocks

#-------------------------------------------------------------------------------
#echo "End of Part 1, Add blocks and ip / date records......"
################################################################################






################################################################################
#
# Part 2, Remove blocks.
#
# Decide which day of temporary blocks needs to be jerked...
#
# Remove blocked ip's from bad_maili and bad_mailo that are from that day. 
# Block lists are good for three days before they expire.  Any ip that 
# doesn't resolve won't be removed...
#

check_res_err_str="Host not found."
temp_err_res="$prefix/ip_block_tmp/temp_err_res"
temp_maili="$prefix/ip_block_tmp/temp_maili"
temp_mailo="$prefix/ip_block_tmp/temp_mailo"



#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

remove_blocks()
{ 
     top_list=1
     total_blocks_removing=`cat $block_switch | wc -l`

     while [ $top_list -le $total_blocks_removing ]
     do
         curr_ip_to_remove=`cat $block_switch | tail -n $top_list | head -n1`

             # Don't remove any ip that isn't resolvable...
             host $curr_ip_to_remove 2> $temp_err_res > /dev/null
             check_res=`cat $temp_err_res`

             if [ ! "$check_res" == "$check_res_err_str" ]
             then



                  # If this isn't in the all blocks ever done list, add it.

                  testing=`cat $blocked_before | grep $curr_ip_to_remove`

                  if [ ! "$testing" ]
                  then
                       echo "$curr_ip_to_remove" >> $blocked_before
                  else
                       # If this isn't the permanent blocks list, add it.

                       testing=`cat "$perm_block" | grep $curr_ip_to_remove`

                       if [ ! "$testing" ]
                       then
                            echo "$curr_ip_to_remove" >> $perm_block
                            testing=$perm_block
                       fi
                  fi



                  # Don't remove an ip on the permanent block list...
                  if [ ! "$testing" ]
                  then
                  counter_2=1
                  while [ $counter_2 -le 3 ]
                  do # There are three block rules in bad_maili and bad_mailo...

                         # Relist what's in bad_maili and bad_mailo...
                         $ipt -nL bad_maili --line-numbers > $temp_maili
                         chmod 600 $temp_maili
                         $ipt -nL bad_mailo --line-numbers > $temp_mailo
                         chmod 600 $temp_mailo

                         # Find the ip in the output chain, remove it once...
                         close_number=
`cat $temp_mailo | grep $curr_ip_to_remove | tail -n1 | cut -d 'D' -f1`
                         if [ $close_number ]
                         then
                             $ipt -D bad_mailo $close_number
                         fi

                         # Find the ip in the input chain and remove it once...
                         close_number=
`cat $temp_maili | grep $curr_ip_to_remove | tail -n1 | cut -d 'D' -f1`
                         if [ $close_number ]
                         then
                             $ipt -D bad_maili $close_number
                         fi

                         let counter_2+=1
                  done

                  echo "$curr_ip_to_remove is not blocked anymore" >> $err_terminal
                  fi

             # If the ip to be removed doesn't resolve, it will never be
             # automatically removed by this script.  This should improve 
             # the block list over time.
             else
                  echo "$curr_ip does not resolve, no expiration." >> $err_terminal 
                  echo "$curr_ip" >> $blocks_needed
             fi

             let top_list+=1  # Go to next ip that needs triple removal.
     done
}

#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=



# ------------------------------------------------------------------------------

if [ $date_today == "Thursday" ]
then
     if [ -e $blocks_Mon ]
     then
          block_switch=$blocks_Mon
          remove_blocks
          rm -f $blocks_Mon
     fi

     if [ -e $blocks_Sun ]
     then
          block_switch=$blocks_Sun
          remove_blocks
          rm -f $blocks_Sun
     fi

     if [ -e $blocks_Sat ]
     then
          block_switch=$blocks_Sat
          remove_blocks
          rm -f $blocks_Sat
     fi

     if [ -e $blocks_Fri ]
     then
          block_switch=$blocks_Fri
          remove_blocks
          rm -f $blocks_Fri
     fi
fi


if [ $date_today == "Friday" ]
then
     if [ -e $blocks_Tue ]
     then
          block_switch=$blocks_Tue
          remove_blocks 
          rm -f $blocks_Tue
     fi

     if [ -e $blocks_Mon ]
     then
          block_switch=$blocks_Mon
          remove_blocks 
          rm -f $blocks_Mon
     fi

     if [ -e $blocks_Sun ]
     then
          block_switch=$blocks_Sun
          remove_blocks 
          rm -f $blocks_Sun
     fi

     if [ -e $blocks_Sat ]
     then
          block_switch=$blocks_Sat
          remove_blocks 
          rm -f $blocks_Sat
     fi
fi


if [ $date_today == "Saturday" ]
then
     if [ -e $blocks_Wed ]
     then
          block_switch=$blocks_Wed
          remove_blocks 
          rm -f $blocks_Wed
     fi

     if [ -e $blocks_Tue ]
     then
          block_switch=$blocks_Tue
          remove_blocks 
          rm -f $blocks_Tue
     fi

     if [ -e $blocks_Mon ]
     then
          block_switch=$blocks_Mon
          remove_blocks 
          rm -f $blocks_Mon
     fi

     if [ -e $blocks_Sun ]
     then
          block_switch=$blocks_Sun
          remove_blocks 
          rm -f $blocks_Sun
     fi
fi


if [ $date_today == "Sunday" ]
then
     if [ -e $blocks_Thu ]
     then
          block_switch=$blocks_Thu
          remove_blocks 
          rm -f $blocks_Thu
     fi

     if [ -e $blocks_Wed ]
     then
          block_switch=$blocks_Wed
          remove_blocks 
          rm -f $blocks_Wed
     fi

     if [ -e $blocks_Tue ]
     then
          block_switch=$blocks_Tue
          remove_blocks 
          rm -f $blocks_Tue
     fi

     if [ -e $blocks_Mon ]
     then
          block_switch=$blocks_Mon
          remove_blocks 
          rm -f $blocks_Mon

     fi
fi


if [ $date_today == "Monday" ]
then
     if [ -e $blocks_Fri ]
     then
          block_switch=$blocks_Fri
          remove_blocks 
          rm -f $blocks_Fri
     fi

     if [ -e $blocks_Thu ]
     then
          block_switch=$blocks_Thu
          remove_blocks 
          rm -f $blocks_Thu
     fi

     if [ -e $blocks_Wed ]
     then
          block_switch=$blocks_Wed
          remove_blocks 
          rm -f $blocks_Wed
     fi

     if [ -e $blocks_Tue ]
     then
          block_switch=$blocks_Tue
          remove_blocks 
          rm -f $blocks_Tue
     fi
fi


if [ $date_today == "Tuesday" ]
then
     if [ -e $blocks_Sat ]
     then
          block_switch=$blocks_Sat
          remove_blocks 
          rm -f $blocks_Sat
     fi

     if [ -e $blocks_Fri ]
     then
          block_switch=$blocks_Fri
          remove_blocks
          rm -f $blocks_Fri
     fi

     if [ -e $blocks_Thu ]
     then
          block_switch=$blocks_Thu
          remove_blocks
          rm -f $blocks_Thu
     fi

     if [ -e $blocks_Wed ]
     then
          block_switch=$blocks_Wed
          remove_blocks
          rm -f $blocks_Wed
     fi
fi


if [ $date_today == "Wednesday" ]
then

     if [ -e $blocks_Sun ]
     then
          block_switch=$blocks_Sun
          remove_blocks
          rm -f $blocks_Sun
     fi

     if [ -e $blocks_Sat ]
     then
          block_switch=$blocks_Sat
          remove_blocks
          rm -f $blocks_Sat
     fi

     if [ -e $blocks_Fri ]
     then
          block_switch=$blocks_Fri
          remove_blocks
          rm -f $blocks_Fri
     fi

     if [ -e $blocks_Thu ]
     then
          block_switch=$blocks_Thu
          remove_blocks
          rm -f $blocks_Thu
     fi

fi

# ------------------------------------------------------------------------------
# End Part 2, Remove blocks.
################################################################################






# -C-P-B-C-P-B-C-P-B-C-P-B-C-P-B-C-P-B-C-P-B-C-P-B-C-P-B-C-P-B-C-P-B-C-P-B-C-P-B
#echo " Add new permanent blocks from web, cat them with $perm_block... "

length_file_web_pblocks=`cat $copy_location_web_pblocks|wc -l`

top_count=1

while [ "$top_count" -le "$length_file_web_pblocks" ]
do

       curr_ip=`cat $copy_location_web_pblocks | head -n $top_count | tail -n1`

       testing=`cat $perm_block | grep $curr_ip`

       if [ ! "$testing" ]
       then

            echo "$curr_ip" >> $perm_block

       fi


       # Make sure anything being added to $perm_block is on $blocked_before 
       # as well.
       testing=`cat $blocked_before | grep $curr_ip`

       if [ ! "$testing" ]
       then

            echo "$curr_ip" >> $blocked_before
       fi
      

       let top_count+=1

done

# -C-P-B-C-P-B-C-P-B-C-P-B-C-P-B-C-P-B-C-P-B-C-P-B-C-P-B-C-P-B-C-P-B-C-P-B-C-P-B



# -s-m-b---s-m-b---s-m-b---s-m-b---s-m-b---s-m-b---s-m-b---s-m-b---s-m-b---smb-
#echo " Send xerxes $file504 and $perm_block to web. "

length_file_504=`cat $file504 | wc -l`


# Assume there is a network 
# exported filesystem to 
# copy our $file504bak to 
# web.

if [ $length_file_504 -ge 1 ]
then
    cp -f $file504bak $copy_location_xerxes


else
    rm -f $copy_location_xerxes
fi

cp -f $perm_block $copy_location_xer_pblocks
chmod 660 $copy_location_xer_pblocks

umount $prefix/web_files 2>/dev/null
# -s-m-b---s-m-b---s-m-b---s-m-b---s-m-b---s-m-b---s-m-b---s-m-b---s-m-b---smb-



#echo " Restore the records that are only on this server... "

if [ -e $file504bak ]
then
    mv $file504bak $file504
fi



#echo " If 3000 recorded 5[0-9][0-9], dump $file504... "

if [ $length_file_504 -ge 3000 ]
then
     rm -f $file504 2> /dev/null
fi

$prefix/mailblock_web_page

----- End forwarded message -----




-------------------------------------------------
This mail sent through IMP: http://horde.org/imp/



More information about the PLUG mailing list