Robot pro omezení zahlcujícího provozu: Porovnání verzí

Z HKfree wiki
Skočit na navigaci Skočit na vyhledávání
Řádek 4: Řádek 4:
 
  # mkdir /var/lib/kladivo
 
  # mkdir /var/lib/kladivo
  
Potřebý záznam pro běh v crontabu:
+
Potřebný záznam pro běh v crontabu:
  
 
  */5 * * * * /root/kladivo.sh cronjob
 
  */5 * * * * /root/kladivo.sh cronjob
Řádek 17: Řádek 17:
 
  #!/bin/sh
 
  #!/bin/sh
 
   
 
   
  # Verze 1.03 -> doplnujte aktualni verzi
+
  # Verze 1.04 -> doplnujte aktualni verzi
 
  # autor pavkriz@hkfree.org
 
  # autor pavkriz@hkfree.org
 
  # iptables rules kendy@hkfree.org
 
  # iptables rules kendy@hkfree.org
Řádek 37: Řádek 37:
 
  WATCHNET=10.107.12.0/24:10.107.42.0/24
 
  WATCHNET=10.107.12.0/24:10.107.42.0/24
 
   
 
   
  # jak je definovana denni doba (7:00-23:00) (nesmi se prehoupnout pres pulnoc, to neumi)
+
  # jak je definovana denni doba (7:00-23:00)
 +
# muze se prehoupnout pres pulnoc, pak je prvni cislo vetsi nez druhe (700-200)
 
  # v noci se banovani vypina (bany bezi casove dal, ale nejsou "provadeny")
 
  # v noci se banovani vypina (bany bezi casove dal, ale nejsou "provadeny")
 
  DAYTIME="700-2300"
 
  DAYTIME="700-2300"
Řádek 52: Řádek 53:
 
     # ziskame obsah reportu do tempfile
 
     # ziskame obsah reportu do tempfile
 
     TMPF="$TMP/kladivo.$$.tmp"
 
     TMPF="$TMP/kladivo.$$.tmp"
     cat - > $TMPF
+
     cat - > "$TMPF"
 
     # ziskame IP ktere se report tyka
 
     # ziskame IP ktere se report tyka
 
     IP=`awk '/Network: / { print $2 }' $TMPF`
 
     IP=`awk '/Network: / { print $2 }' $TMPF`
 
     # ziskame cas z reportu (jak dlouho presahuje limit) - jako desetinne cislo v minutach
 
     # ziskame cas z reportu (jak dlouho presahuje limit) - jako desetinne cislo v minutach
 
     OVERTIME=`awk '/exceeded for: / { print $7 }' $TMPF`
 
     OVERTIME=`awk '/exceeded for: / { print $7 }' $TMPF`
     # odsekneme deseetinnou cast
+
     # odsekneme desetinnou cast
     OVERTIME=`echo $OVERTIME | awk 'BEGIN { FS = "." } ; { print $1 }'`
+
     OVERTIME="${OVERTIME%%.*}"
 
     # debug
 
     # debug
 
     ###echo $IP $OVERTIME
 
     ###echo $IP $OVERTIME
     if [ $OVERTIME -gt $MAXOVERTIME ]; then
+
     if [ "$OVERTIME" -gt "$MAXOVERTIME" ]; then
 
         # limit prekrocen na dobu delsi nez je povolena -> zabanovat
 
         # limit prekrocen na dobu delsi nez je povolena -> zabanovat
 
         FILE="$LISTDIR/$IP"
 
         FILE="$LISTDIR/$IP"
         if [ ! -e $FILE ]; then
+
         if [ ! -e "$FILE" ]; then
 
             # pokud jeste neni zabanovan, tak zalozime soubor se znackou pro zabanovani
 
             # pokud jeste neni zabanovan, tak zalozime soubor se znackou pro zabanovani
 
             # vypocteme timestamp do kdy budem IP banovat
 
             # vypocteme timestamp do kdy budem IP banovat
             NOW=`date +%s`
+
             NOW="`date +%s`"
             BANTOTIME=`expr $BANTIME \* 60 + $NOW`
+
             BANTOTIME="$(($BANTIME * 60 + $NOW))" 
 
             # zapiseme timestamp do souboru
 
             # zapiseme timestamp do souboru
             echo $BANTOTIME > $FILE
+
             echo "$BANTOTIME" > "$FILE"
 
             # zapiseme report na jehoz zaklade ban vznikl
 
             # zapiseme report na jehoz zaklade ban vznikl
             echo "" >>$FILE
+
             echo "" >> "$FILE"
             cat $TMPF >>$FILE
+
             cat "$TMPF" >> "$FILE"
 
         fi
 
         fi
 
     fi
 
     fi
     rm $TMPF
+
     rm "$TMPF"
 
     exit 0
 
     exit 0
 
     ;;
 
     ;;
Řádek 83: Řádek 84:
 
     # vyprazdnit chain
 
     # vyprazdnit chain
 
     $IPTABLES -F SOSACI
 
     $IPTABLES -F SOSACI
     NOW=`date +%s`
+
     NOW="`date +%s`"
 +
    NOWTIME="`date +%k%M`"
 +
    DAYTIME1="${DAYTIME%%-*}"
 +
    DAYTIME2="${DAYTIME##*-}"
 
     # projit vsechny zabanovane
 
     # projit vsechny zabanovane
 
     for FILE in $LISTDIR/* ; do
 
     for FILE in $LISTDIR/* ; do
 
         if [ -e "$FILE" ]; then
 
         if [ -e "$FILE" ]; then
           BANTO=`head -n 1 "$FILE"`
+
           BANTO="`head -n 1 "$FILE"`"
           if [ $BANTO -lt $NOW ]; then
+
           if [ "$BANTO" -lt "$NOW" ]; then
 
               # uz vyprsel ban
 
               # uz vyprsel ban
 
               # smazat znacku o zabanovani (casem asi presunout do nejakeho archivu)
 
               # smazat znacku o zabanovani (casem asi presunout do nejakeho archivu)
Řádek 94: Řádek 98:
 
           else
 
           else
 
               # je-li stale zabanovan, obnovit banovani
 
               # je-li stale zabanovan, obnovit banovani
               # ovsem jen v pripade ze je "den"
+
               BANME='no'
              DAYTIME1=`echo $DAYTIME | awk 'BEGIN { FS = "-" } ; { print $1 }'`
+
              if [ "$DAYTIME1" -gt "$DAYTIME2" ]; then
              DAYTIME2=`echo $DAYTIME | awk 'BEGIN { FS = "-" } ; { print $2 }'`
+
                if [ "$NOWTIME" -gt "$DAYTIME1" ]; then
              NOWTIME=`date +%k%M`
+
                  BANME='yes'
              # je den? (podle DAYTIME)
+
                elif [ "$NOWTIME" -lt "$DAYTIME2" ]; then
               if [ $NOWTIME -ge $DAYTIME1 -a $NOWTIME -lt $DAYTIME2 ]; then
+
                  BANME='yes'
                   IP=`basename $FILE`
+
                fi
 +
               elif [ "$NOWTIME" -ge "$DAYTIME1" -a "$NOWTIME" -lt "$DAYTIME2" ]; then
 +
                BANME='yes'
 +
              fi
 +
     
 +
              if [ "$BANME" = 'yes' ]; then
 +
                   IP="${FILE##*/}"
 
                   $IPTABLES -I SOSACI  -p ! icmp -s $IP -m limit --limit 10/s -j ACCEPT
 
                   $IPTABLES -I SOSACI  -p ! icmp -s $IP -m limit --limit 10/s -j ACCEPT
 
                   $IPTABLES -I SOSACI 2 -p ! icmp -s $IP -j DROP
 
                   $IPTABLES -I SOSACI 2 -p ! icmp -s $IP -j DROP

Verze z 24. 8. 2005, 11:40

Postaveno na http://ipband.sourceforge.net/

Vyžaduje adresář /var/lib/kladivo - zrobíme snadno:

# mkdir /var/lib/kladivo

Potřebný záznam pro běh v crontabu:

*/5 * * * * /root/kladivo.sh cronjob

Někde v init skriptech je záhodno nastartovat sledování pomocí:

/root/kladivo.sh startwatch

Skript /root/kladivo.sh:

(proměnné v hlaviččne si račte upravit k obrazu svému, nezapomenout do sledovanych sítí přidat i veřejné IP)

#!/bin/sh

# Verze 1.04 -> doplnujte aktualni verzi
# autor pavkriz@hkfree.org
# iptables rules kendy@hkfree.org
# detekce casoveho useku jezz@hkfree.org

# rychlostni limit v kB/s
LIMIT=70

# maximalni doba na jakou lze prekrocit limit (minut)
MAXOVERTIME=15

# doba, na jakou danou IP zabanujeme (minut)
BANTIME=180

# interface ktery sledujeme
WATCHIF=eth2

# podsite ktere sledujeme
WATCHNET=10.107.12.0/24:10.107.42.0/24

# jak je definovana denni doba (7:00-23:00)
# muze se prehoupnout pres pulnoc, pak je prvni cislo vetsi nez druhe (700-200)
# v noci se banovani vypina (bany bezi casove dal, ale nejsou "provadeny")
DAYTIME="700-2300"

KLADIVO=/root/kladivo.sh
LISTDIR=/var/lib/kladivo

TMP=/tmp
IPTABLES=/sbin/iptables
IPBAND=/usr/sbin/ipband

case "$1" in
 report)
   # ziskame obsah reportu do tempfile
   TMPF="$TMP/kladivo.$$.tmp"
   cat - > "$TMPF"
   # ziskame IP ktere se report tyka
   IP=`awk '/Network: / { print $2 }' $TMPF`
   # ziskame cas z reportu (jak dlouho presahuje limit) - jako desetinne cislo v minutach
   OVERTIME=`awk '/exceeded for: / { print $7 }' $TMPF`
   # odsekneme desetinnou cast
   OVERTIME="${OVERTIME%%.*}"
   # debug
   ###echo $IP $OVERTIME
   if [ "$OVERTIME" -gt "$MAXOVERTIME" ]; then
       # limit prekrocen na dobu delsi nez je povolena -> zabanovat
       FILE="$LISTDIR/$IP"
       if [ ! -e "$FILE" ]; then
           # pokud jeste neni zabanovan, tak zalozime soubor se znackou pro zabanovani
           # vypocteme timestamp do kdy budem IP banovat
           NOW="`date +%s`"
           BANTOTIME="$(($BANTIME * 60 + $NOW))"   
           # zapiseme timestamp do souboru
           echo "$BANTOTIME" > "$FILE"
           # zapiseme report na jehoz zaklade ban vznikl
           echo "" >> "$FILE"
           cat "$TMPF" >> "$FILE"
       fi
   fi
   rm "$TMPF"
   exit 0
   ;;

 cronjob)
   # vyprazdnit chain
   $IPTABLES -F SOSACI
   NOW="`date +%s`"
   NOWTIME="`date +%k%M`"
   DAYTIME1="${DAYTIME%%-*}"
   DAYTIME2="${DAYTIME##*-}"
   # projit vsechny zabanovane
   for FILE in $LISTDIR/* ; do
       if [ -e "$FILE" ]; then
         BANTO="`head -n 1 "$FILE"`"
         if [ "$BANTO" -lt "$NOW" ]; then
             # uz vyprsel ban
             # smazat znacku o zabanovani (casem asi presunout do nejakeho archivu)
             rm "$FILE"
         else
             # je-li stale zabanovan, obnovit banovani
             BANME='no'
             if [ "$DAYTIME1" -gt "$DAYTIME2" ]; then
               if [ "$NOWTIME" -gt "$DAYTIME1" ]; then
                 BANME='yes'
               elif [ "$NOWTIME" -lt "$DAYTIME2" ]; then
                 BANME='yes'
               fi
             elif [ "$NOWTIME" -ge "$DAYTIME1" -a "$NOWTIME" -lt "$DAYTIME2" ]; then
               BANME='yes'
             fi
	       
             if [ "$BANME" = 'yes' ]; then
                 IP="${FILE##*/}"
                 $IPTABLES -I SOSACI   -p ! icmp -s $IP -m limit --limit 10/s -j ACCEPT
                 $IPTABLES -I SOSACI 2 -p ! icmp -s $IP -j DROP
                 $IPTABLES -I SOSACI   -p ! icmp -d $IP -m limit --limit 10/s -j ACCEPT
                 $IPTABLES -I SOSACI 2 -p ! icmp -d $IP -j DROP
             fi
         fi
       fi
   done
   exit 0
   ;;

 startwatch)
   # vytvorit chain kam strkame banovaci pravidla
   $IPTABLES -N SOSACI && $IPTABLES -I FORWARD -j SOSACI
   # spustit sledovaci ipband, ktery nam bude posilat reporty a detekovanych prekroceni
   $IPBAND -F -L $WATCHNET -m 32 -b $LIMIT -a 60 -r 240 -t 5 -M root@localhost -T "$KLADIVO report" $WATCHIF
   exit 0
   ;;

 stopwatch)
   killall $IPBAND
   exit 0
   ;;

 *)
   echo "usage: $0 startwatch"
   exit 1
   ;;
esac

CGI skript pro sledování stavu černé listiny:

#!/bin/sh
#
#Verze 1.01
#Autor PavKriz
# 
LISTDIR=/var/lib/kladivo

SEP="--------------------------------------------"
echo "Content-type: text/plain"
echo ""
TODAY=`date`
echo "Report k datu: $TODAY"
echo $SEP
NOW=`date +%s`

   for FILE in $LISTDIR/* ; do
       if [ -e "$FILE" ]; then
           IP=`basename $FILE`
           HOST=`host $IP | awk "{ print \\$5 }"`
           BANTO=`head -n 1 $FILE`
           UNBAN=`expr $BANTO - $NOW`
           UNBAN=`expr $UNBAN / 60`
           # print report
           echo "Host: $HOST"
           echo "Minutes to unban: $UNBAN"
           echo "Ban-causing report:"
           tail +8 $FILE
           echo
       fi
   done