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

Z HKfree wiki
Skočit na navigaci Skočit na vyhledávání
Řádek 206: Řádek 206:
  
 
==Kladivo na node d-network==
 
==Kladivo na node d-network==
 +
*integrace se shaperem od martink, vyuziva se htb a imq
 +
*zavedeny 2 rychlostni urovne
 +
*drobna uprava - po vytvoreni banovaciho reportu se ihned spusti cronjob (zabanovani se projevi driv)
 +
 +
co je treba dodelat:
 +
*mozna ve vychozim stavu si skript vystaci s -m limit --limit XX; mel by tedy asi tak byt publikovany zde na wiki (staci zakomentovat moje iptables pravidla a odkomentovat ty puvodni)
 +
*pokud jde o htb, aby ve vychozim stavu vsichni shaper obchazeli (nebyli omezeni), je vyuzito znacky -j MARK --set-mark 3, ktera je vicemene interni funkci unishaperu; bylo by dobre, kdyby se default trida v unishaperu mohla nastavit jako neshapovana... neni to ale kriticke
 +
 +
 +
kladivo.sh:
 +
<bash>#!/bin/sh
 +
# Verze 1.07 -> doplnujte aktualni verzi
 +
# autor pavkriz@hkfree.org
 +
# iptables rules kendy@hkfree.org
 +
# detekce casoveho useku jezz@hkfree.org
 +
# vzorova integrace s unishaperem od martink@hkfree.org a lowlimit lada@hkfree.org
 +
 +
# rychlostni limit v kB/s
 +
LIMIT=200
 +
# limit pod kterym musi sosac byt, aby doslo k odblokovani
 +
# pokud funkce nema byt vyuzita, zakomentovat
 +
LOWLIMIT=50
 +
 +
# maximalni doba na jakou lze prekrocit limit (minut)
 +
MAXOVERTIME=2
 +
 +
# doba, na jakou danou IP zabanujeme (minut)
 +
BANTIME=10
 +
 +
# interface ktery sledujeme
 +
WATCHIF=eth5
 +
 +
# podsite ktere sledujeme
 +
WATCHNET=10.107.3.32/27:10.107.3.96/27:10.107.3.128/25:10.107.103.0/28:10.107.103.32/27:85.132.161.218/32:85.132.160.163/32:85.132.160.172/32:85.132.160.170/32:85.132.160.168/32:85.132.160.169/32:85.132.161.219/32
 +
#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
 +
 +
IPTABLES=/usr/local/sbin/iptables
 +
IPBAND=/usr/local/bin/ipband
 +
 +
case "$1" in
 +
report)
 +
  # ziskame obsah reportu do tempfile
 +
  TMPF=`mktemp -t kladivo.XXXXXX`
 +
  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%%.*}"
 +
  # ziskame jaka byla prekrocena rychlost
 +
  SPEED=`awk '/threshold: / { print $3 }' $TMPF`
 +
  SPEED="${SPEED%%.*}"
 +
  # debug
 +
  ###echo $IP $OVERTIME
 +
 +
  BANME=no
 +
  MAKEBANFILE=no
 +
  if [ "$OVERTIME" -gt "$MAXOVERTIME" ]; then
 +
      # pokud byl limit prekrocen delsi dobu nez je limit
 +
      FILE="$LISTDIR/$IP"
 +
      if [ "$SPEED" == "$LIMIT" ]; then
 +
          # jde o vysokou rychlost, vytvorit take prvni report
 +
          MAKEBANFILE=yes
 +
          BANME=yes
 +
      fi
 +
      if [ "$SPEED" == "$LOWLIMIT" ]; then
 +
          # pokud byla prekrocena nizsi rychlost, banuj pouze pokud existuje prvni report
 +
          if [ -e "$FILE.ban" ]; then
 +
              BANME=yes
 +
  fi
 +
      fi
 +
      if [ "$BANME" == "yes" ]; then
 +
          # limit prekrocen, banovat
 +
          NOW="`date +%s`"
 +
          BANTOTIME="$(($BANTIME * 60 + $NOW))" 
 +
          # zapiseme timestamp do souboru
 +
          echo "$BANTOTIME" > "$FILE.current"
 +
          # zapiseme report na jehoz zaklade ban vznikl
 +
          echo "" >> "$FILE.current"
 +
          cat "$TMPF" >> "$FILE.current"
 +
      fi
 +
      if [ "$MAKEBANFILE" == "yes" ]; then
 +
          # vytvorit prvni banovaci report. existujici neprepisovat
 +
          [ ! -e "$FILE.ban" ] && cp "$FILE.current" "$FILE.ban"
 +
  # spustime cronjob, aby zabanovani bylo okamzite
 +
  $0 cronjob
 +
      fi
 +
  fi
 +
  rm "$TMPF"
 +
  exit 0
 +
  ;;
 +
 +
cronjob)
 +
  # vyprazdnit chain
 +
  $IPTABLES -t mangle -F SOSACI_pre  &> /dev/null
 +
  $IPTABLES -t mangle -F SOSACI_post &> /dev/null
 +
 +
  # co ma znacku 3 v unishaperu shaper obchazi
 +
  $IPTABLES -t mangle -A SOSACI_pre -i $WATCHIF -j MARK --set-mark 3
 +
  $IPTABLES -t mangle -A SOSACI_post -o $WATCHIF -j MARK --set-mark 3 
 +
 +
  #$IPTABLES -F SOSACI &> /dev/null
 +
 +
  NOW="`date +%s`"
 +
  NOWTIME="`date +%k%M`"
 +
  DAYTIME1="${DAYTIME%%-*}"
 +
  DAYTIME2="${DAYTIME##*-}"
 +
  # projit vsechny zabanovane
 +
  for FILE in $LISTDIR/*.current ; 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"
 +
    # smazat taky soubor s priponou .ban
 +
    rm "${FILE%.current}.ban"
 +
        else
 +
            # je-li stale zabanovan, obnovit banovani
 +
            BANME=no
 +
            if [ "$DAYTIME1" -gt "$DAYTIME2" ]; then
 +
              [ "$NOWTIME" -ge "$DAYTIME1" -o "$NOWTIME" -lt "$DAYTIME2" ] \
 +
                && BANME=yes
 +
            elif [ "$NOWTIME" -ge "$DAYTIME1" -a "$NOWTIME" -lt "$DAYTIME2" ]; then
 +
              BANME=yes
 +
            fi
 +
     
 +
            if [ "$BANME" = yes ]; then
 +
                IP="${FILE##*/}"
 +
IP="${IP%.current}"
 +
$IPTABLES -t mangle -p ! icmp -A SOSACI_pre  -i $WATCHIF -s $IP -j unishaper_pre
 +
$IPTABLES -t mangle -p ! icmp -A SOSACI_post -o $WATCHIF -d $IP -j unishaper_post
 +
 +
                #$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|start)
 +
  # spustit omezovaci shaper
 +
  unishaper.sh
 +
  # umravnit shaper
 +
  $IPTABLES -t mangle -D PREROUTING -j unishaper_pre
 +
  $IPTABLES -t mangle -D POSTROUTING -j unishaper_post
 +
  $IPTABLES -t mangle -D INPUT -j unishaper_in
 +
  $IPTABLES -t mangle -D OUTPUT -j unishaper_out
 +
  $IPTABLES -t mangle -D FORWARD -j unishaper_fw
 +
  # vytvorit chain kam strkame banovaci pravidla
 +
  $IPTABLES -t mangle -N SOSACI_pre  && $IPTABLES -t mangle -I PREROUTING  -j SOSACI_pre
 +
  $IPTABLES -t mangle -N SOSACI_post && $IPTABLES -t mangle -I POSTROUTING -j SOSACI_post
 +
  # co ma znacku 3 v unishaperu shaper obchazi
 +
  $IPTABLES -t mangle -A SOSACI_pre -i $WATCHIF -j MARK --set-mark 3
 +
  $IPTABLES -t mangle -A SOSACI_post -o $WATCHIF -j MARK --set-mark 3 
 +
 +
  #$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 180 -t 5 -M root@localhost -T "$KLADIVO report" $WATCHIF
 +
  if [ "$LOWLIMIT" != "" ]; then
 +
      $IPBAND -F -L $WATCHNET -m 32 -b $LOWLIMIT -a 60 -r 240 -t 5 -M root@localhost -T "$KLADIVO report" $WATCHIF 
 +
  fi
 +
  exit 0
 +
  ;;
 +
 +
stopwatch|stop)
 +
  killall $IPBAND
 +
  # smazat iptables pravidla (chyby ignorovat, pokud neexistuji)
 +
  $IPTABLES -t mangle -F SOSACI_pre  &> /dev/null
 +
  $IPTABLES -t mangle -F SOSACI_post &> /dev/null
 +
 +
  $IPTABLES -t mangle -D PREROUTING  -j SOSACI_pre  &> /dev/null
 +
  $IPTABLES -t mangle -D POSTROUTING -j SOSACI_post &> /dev/null
 +
 +
  $IPTABLES -t mangle -X SOSACI_pre  &> /dev/null
 +
  $IPTABLES -t mangle -X SOSACI_post &> /dev/null
 +
 +
  unishaper.sh -s
 +
 +
  #$IPTABLES -F SOSACI &> /dev/null
 +
  #$IPTABLES -D FORWARD -j SOSACI &> /dev/null
 +
  #$IPTABLES -X SOSACI &> /dev/null
 +
  exit 0
 +
  ;;
 +
 +
restart)
 +
  $0 stop
 +
  $0 start
 +
  exit 0
 +
  ;;
 +
 +
*)
 +
  echo "usage: $0 startwatch|stopwatch|start|stop|restart|report|cronjob"
 +
  exit 1
 +
  ;;
 +
esac
 +
</bash>
 +
 +
 +
vypis kladiva:
 +
<bash>#!/bin/sh
 +
#
 +
#Verze 1.02
 +
#Autor PavKriz
 +
#
 +
# modifikace Lada JNet
 +
 +
LISTDIR=/var/lib/kladivo
 +
 +
SEP="--------------------------------------------"
 +
echo "Content-type: text/plain"
 +
echo ""
 +
TODAY=`date`
 +
ping -c 1 -w 1 10.107.15.17 &> /dev/null && SHOWMAIL=yes
 +
echo "Report k datu: $TODAY"
 +
echo $SEP
 +
NOW=`date +%s`
 +
 +
  for FILE in $LISTDIR/*.current ; do
 +
      echo "$FILE" | grep archive &>/dev/null && continue
 +
      if [ -e "$FILE" ]; then
 +
  FILE="${FILE%.current}"
 +
          IP=`basename $FILE`
 +
  [ "$SHOWMAIL" == "yes"  ] && MAIL=`echo "$IP" | nc -w 2 10.107.15.17 10107`
 +
          HOST=`host $IP | awk "{ print \\$5 }"`
 +
          BANTO=`head -n 1 $FILE.current`
 +
          UNBAN=`expr $BANTO - $NOW`
 +
          UNBAN=`expr $UNBAN / 60`
 +
          # print report
 +
          echo "Adresa: $HOST ($IP)"
 +
  [ "$SHOWMAIL" == "yes"  ] && echo "Email: $MAIL"
 +
          echo "Bude smazano za: $UNBAN minut"
 +
          echo "Omezeni spusteno kvuli:"
 +
          tail +8 $FILE.ban
 +
  echo "Omezeni udrzovano kvuli:"
 +
  tail +8 $FILE.current
 +
          echo
 +
      fi
 +
  done
 +
</bash>
 +
 +
mensi pokus o prevod kladiva do html:
 +
<pre><nowiki>#!/bin/sh
 +
#
 +
#Verze 1.02
 +
#Autor PavKriz
 +
#
 +
# modifikace Lada JNet
 +
 +
LISTDIR=/var/lib/kladivo
 +
 +
#SEP="--------------------------------------------"
 +
echo "Content-type: text/html"
 +
echo ""
 +
cat << EoF
 +
<HTML>
 +
<TITLE>Kladivo</TITLE>
 +
<BODY>
 +
<img src="http://d-network.hkfree.org/logo.gif"><br>
 +
EoF
 +
TODAY=`date`
 +
ping -c 1 -w 1 10.107.15.17 &> /dev/null && SHOWMAIL=yes
 +
echo "<font size=+1><b> Report k datu: $TODAY </b></font><br><br>"
 +
NOW=`date +%s`
 +
 +
  for FILE in $LISTDIR/*.current ; do
 +
      echo "$FILE" | grep archive &>/dev/null && continue
 +
      if [ -e "$FILE" ]; then
 +
  FILE="${FILE%.current}"
 +
          IP=`basename $FILE`
 +
  [ "$SHOWMAIL" == "yes"  ] && MAIL=`echo "$IP" | nc -w 2 10.107.15.17 10107`
 +
          HOST=`host $IP | awk "{ print \\$5 }"`
 +
          BANTO=`head -n 1 $FILE.current`
 +
          UNBAN=`expr $BANTO - $NOW`
 +
          UNBAN=`expr $UNBAN / 60`
 +
          # print report
 +
          echo "Adresa: $HOST ($IP)<br>"
 +
  [ "$SHOWMAIL" == "yes"  ] && echo "Email: $MAIL <br>"
 +
          echo "Bude smazano za: $UNBAN minut<br>"
 +
          echo "<b>Omezeni spusteno kvuli:</b><br>"
 +
  echo "<pre>"
 +
          tail +8 $FILE.ban
 +
  echo "</pre>"
 +
  echo "<b>Omezeni udrzovano kvuli:</b>"
 +
  echo "<pre>"
 +
  tail +8 $FILE.current
 +
  echo "</pre>"
 +
  echo "<hr>"
 +
          echo
 +
      fi
 +
  done
 +
 +
cat << EoF
 +
</BODY>
 +
</HTML>
 +
EoF
 +
</nowiki></pre>
 +
 +
===Unishaper===
 +
[http://lide.hkfree.org/~martink Homepage] (v soucasne dobe zde unishaper ke stazeni neni... martina se pozeptam)
 +
 +
unishaper.conf na dnetw:
 +
<bash>#!/bin/sh  # jen kvuli zvyrazneni syntaxe ve vimu :)
 +
 +
tc=/sbin/tc
 +
iptables=/usr/local/sbin/iptables
 +
ip=/sbin/ip
 +
modprobe=/sbin/modprobe
 +
 +
 +
iface0() {
 +
iface="eth5"
 +
 +
# ve zkratce, co znamenaji parametry:
 +
# root_rate maximalni rychlost vsech dohromady - lze rict, kolik "kladivouni" smi urvat dohromady
 +
# rate - garance; musi byt nad 12, je potreba aby garance vsech nepresahla root_rate
 +
# ceil - maximalni rychlost v ramci jedne tridy (rychlost uzivatele)
 +
# dist - yes/no znamena, jestli je v routru iface vzdaleny od uzivatele, nebo je-li na nej napojen uzivatel primo
 +
#        pouziva se pouze, pokud nemame imq a vime, kudy potecou odchozi data uzivatele
 +
 +
# upload uzivatelu
 +
upload="yes"
 +
up_dist="no"
 +
up_unit="kbit"
 +
# kolik muzou udelat vsichni dohromady
 +
up_root_rate="15000"
 +
# default trida - tu nepouzivame; sem jde vse, co neni oznackovano
 +
up_ceil="300"
 +
up_rate="25"
 +
 +
# jak se pisou subnety je skvele vysvetleno v ukazkovem konfiguraku
 +
# ve zkratce:
 +
# 10.107.3.1-5 vytvori 5 samostatnych trid (pro 5 ruznych uzivatelu)
 +
# 10.107.3.1,10.107.3.2,10.107.3.3 vytvori 1 tridu pro 3 adresy (1 user vlastni vsechny adresy)
 +
# 10.107.3.0/27 vytvori 1 tridu pro cely rozsah (cely rozsah patri jednomu uzivateli)
 +
 +
#  wireless     rexornet   weetek,bloque  jenda   rexor
 +
A="10.107.3.130-222 10.107.3.34-46 10.107.3.97-102 85.132.161.218,10.107.3.112/29 10.107.3.14,10.107.3.34,10.107.3.35,85.132.160.163"
 +
#  yanda       radekN&tomask bazina     bazina_subnet  jaja&kamil     mirra&spol
 +
B="10.107.3.147,85.132.160.172 10.107.103.50-51 10.107.3.58,10.107.3.59,10.107.3.60 10.107.3.61-62 10.107.3.122-123 10.107.103.34,85.132.160.170 10.107.103.35,85.132.160.168 10.107.103.36,85.132.160.169"
 +
#  honya   honya_subnet sa dave
 +
C="10.107.3.50,10.107.3.51,85.132.161.219 10.107.3.52-54 10.107.3.104/29 10.107.103.42-43"
 +
# A B a C pouzivam jenom, aby se nejak dalo vyznat v tech komentarich
 +
 +
# koho shapujem
 +
up_1_range="$A $B $C"
 +
# garance
 +
up_1_rate="25"
 +
# strop
 +
up_1_ceil="300"
 +
 +
# pokud nejaky uzivatel hodne zlobi, lze mu tady vytvorit individualni rychlost, na kterou ho kladivo srazi, napr:
 +
# pri individualni hranici je ale treba dbat na to, aby uzivatel mohl prekrocit LOWLIMIT v kladivo.sh,
 +
#  jinak bude neustale odblokovavan a zablokovavan
 +
#up_2_range="10.107.3.1"
 +
#up_2_rate="25"
 +
#up_2_ceil="100"
 +
 +
# download uzivatelu
 +
download="yes"
 +
dl_dist="no"
 +
dl_unit="kbit"
 +
# celkova rychlost
 +
dl_root_rate="15000"
 +
# default trida - nepouzivame
 +
dl_ceil="1024"
 +
dl_rate="25"
 +
 +
# tridy uzivatelu
 +
dl_1_range="$up_1_range"
 +
dl_1_ceil="800"
 +
dl_1_rate="25"
 +
 +
#dl_2_range="$up_2_range"
 +
#dl_2_ceil="450"
 +
#dl_2_rate="25"
 +
 +
}
 +
 +
tests="yes"
 +
</bash>

Verze z 9. 6. 2006, 10:00

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

nebo skript přímo nalinkovat do startovacích adresářů (rcX.d). Na debianu to lze udělat takto:

cd /etc/init.d
ln -s /root/kladivo.sh
update-rc.d kladivo.sh defaults

Skript /root/kladivo.sh:

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

<bash>#!/bin/sh

  1. Verze 1.06 -> doplnujte aktualni verzi
  2. autor pavkriz@hkfree.org
  3. iptables rules kendy@hkfree.org
  4. detekce casoveho useku jezz@hkfree.org
  1. rychlostni limit v kB/s

LIMIT=70

  1. maximalni doba na jakou lze prekrocit limit (minut)

MAXOVERTIME=15

  1. doba, na jakou danou IP zabanujeme (minut)

BANTIME=180

  1. interface ktery sledujeme

WATCHIF=eth2

  1. podsite ktere sledujeme

WATCHNET=10.107.12.0/24:10.107.42.0/24

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

DAYTIME="700-2300"

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

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

case "$1" in

report)
  # ziskame obsah reportu do tempfile
  TMPF=`mktemp -t kladivo.XXXXXX`
  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 &> /dev/null
  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
              [ "$NOWTIME" -ge "$DAYTIME1" -o "$NOWTIME" -lt "$DAYTIME2" ] \
                && BANME='yes'
            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|start)
  # 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|stop)
  killall $IPBAND
  # smazat iptables pravidla (chyby ignorovat, pokud neexistuji)
  $IPTABLES -F SOSACI &> /dev/null
  $IPTABLES -D FORWARD -j SOSACI &> /dev/null
  $IPTABLES -X SOSACI &> /dev/null
  exit 0
  ;;
restart)
  $0 stop
  $0 start
  exit 0
  ;;
*)
  echo "usage: $0 startwatch|stopwatch|start|stop|restart|report|cronjob"
  exit 1
  ;;

esac </bash>

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

<bash>#!/bin/sh

  1. Verze 1.01
  2. 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
      echo "$FILE" | grep archive &>/dev/null && continue
      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 ($IP)"
          echo "Minutes to unban: $UNBAN"
          echo "Ban-causing report:"
          tail +8 $FILE
          echo
      fi
  done

</bash>

TCP/IP rozhrani na dotazy do userdb pro prevod IP adresy na e-mail HKfree clena bezi na brita (brita.lhota.hkfree.org, 10.107.15.17) na portu 10107.

Priklady:

uspesny dotaz:

23:13:30 Lhota3-JZD:~# echo 10.107.12.88 | nc 10.107.15.17 10107
caryInvalidaddresSfukhk@tiscInvaliddomaiNali.cz

neuspesny dotaz (ip adresa v userdb neni)

23:15:36 Lhota3-JZD:~# echo 10.107.12.888 | nc 10.107.15.17 10107
23:15:46 Lhota3-JZD:~#

chybova hlaska:

23:15:46 Lhota3-JZD:~# echo 10.107.12.8888 | nc 10.107.15.17 10107
ip2mail: [10.107.12.8888] does not look like IPv4 address.

Rozhrani je vhodne k pouziti v kladivu - poslu clenovi mail hned jak na nej kladivo "spadne"

Kladivo na node d-network

  • integrace se shaperem od martink, vyuziva se htb a imq
  • zavedeny 2 rychlostni urovne
  • drobna uprava - po vytvoreni banovaciho reportu se ihned spusti cronjob (zabanovani se projevi driv)

co je treba dodelat:

  • mozna ve vychozim stavu si skript vystaci s -m limit --limit XX; mel by tedy asi tak byt publikovany zde na wiki (staci zakomentovat moje iptables pravidla a odkomentovat ty puvodni)
  • pokud jde o htb, aby ve vychozim stavu vsichni shaper obchazeli (nebyli omezeni), je vyuzito znacky -j MARK --set-mark 3, ktera je vicemene interni funkci unishaperu; bylo by dobre, kdyby se default trida v unishaperu mohla nastavit jako neshapovana... neni to ale kriticke


kladivo.sh: <bash>#!/bin/sh

  1. Verze 1.07 -> doplnujte aktualni verzi
  2. autor pavkriz@hkfree.org
  3. iptables rules kendy@hkfree.org
  4. detekce casoveho useku jezz@hkfree.org
  5. vzorova integrace s unishaperem od martink@hkfree.org a lowlimit lada@hkfree.org
  1. rychlostni limit v kB/s

LIMIT=200

  1. limit pod kterym musi sosac byt, aby doslo k odblokovani
  2. pokud funkce nema byt vyuzita, zakomentovat

LOWLIMIT=50

  1. maximalni doba na jakou lze prekrocit limit (minut)

MAXOVERTIME=2

  1. doba, na jakou danou IP zabanujeme (minut)

BANTIME=10

  1. interface ktery sledujeme

WATCHIF=eth5

  1. podsite ktere sledujeme

WATCHNET=10.107.3.32/27:10.107.3.96/27:10.107.3.128/25:10.107.103.0/28:10.107.103.32/27:85.132.161.218/32:85.132.160.163/32:85.132.160.172/32:85.132.160.170/32:85.132.160.168/32:85.132.160.169/32:85.132.161.219/32

  1. 10.107.12.0/24:10.107.42.0/24
  1. jak je definovana denni doba (7:00-23:00)
  2. muze se prehoupnout pres pulnoc, pak je prvni cislo vetsi nez druhe (700-200)
  3. v noci se banovani vypina (bany bezi casove dal, ale nejsou "provadeny")

DAYTIME="700-2300"

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

IPTABLES=/usr/local/sbin/iptables IPBAND=/usr/local/bin/ipband

case "$1" in

report)
  # ziskame obsah reportu do tempfile
  TMPF=`mktemp -t kladivo.XXXXXX`
  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%%.*}"
  # ziskame jaka byla prekrocena rychlost
  SPEED=`awk '/threshold: / { print $3 }' $TMPF`
  SPEED="${SPEED%%.*}"
  # debug
  ###echo $IP $OVERTIME
  BANME=no
  MAKEBANFILE=no
  if [ "$OVERTIME" -gt "$MAXOVERTIME" ]; then
      # pokud byl limit prekrocen delsi dobu nez je limit
      FILE="$LISTDIR/$IP"
      if [ "$SPEED" == "$LIMIT" ]; then
         # jde o vysokou rychlost, vytvorit take prvni report
         MAKEBANFILE=yes
         BANME=yes
      fi
      if [ "$SPEED" == "$LOWLIMIT" ]; then
          # pokud byla prekrocena nizsi rychlost, banuj pouze pokud existuje prvni report
          if [ -e "$FILE.ban" ]; then
              BANME=yes

fi

      fi
      if [ "$BANME" == "yes" ]; then
          # limit prekrocen, banovat
          NOW="`date +%s`"
          BANTOTIME="$(($BANTIME * 60 + $NOW))"   
          # zapiseme timestamp do souboru
          echo "$BANTOTIME" > "$FILE.current"
          # zapiseme report na jehoz zaklade ban vznikl
          echo "" >> "$FILE.current"
          cat "$TMPF" >> "$FILE.current"
      fi
      if [ "$MAKEBANFILE" == "yes" ]; then
          # vytvorit prvni banovaci report. existujici neprepisovat
          [ ! -e "$FILE.ban" ] && cp "$FILE.current" "$FILE.ban"

# spustime cronjob, aby zabanovani bylo okamzite $0 cronjob

      fi
  fi
  rm "$TMPF"
  exit 0
  ;;

cronjob)
  # vyprazdnit chain
  $IPTABLES -t mangle -F SOSACI_pre  &> /dev/null
  $IPTABLES -t mangle -F SOSACI_post &> /dev/null
  # co ma znacku 3 v unishaperu shaper obchazi
  $IPTABLES -t mangle -A SOSACI_pre -i $WATCHIF -j MARK --set-mark 3
  $IPTABLES -t mangle -A SOSACI_post -o $WATCHIF -j MARK --set-mark 3   
  #$IPTABLES -F SOSACI &> /dev/null
  NOW="`date +%s`"
  NOWTIME="`date +%k%M`"
  DAYTIME1="${DAYTIME%%-*}"
  DAYTIME2="${DAYTIME##*-}"
  # projit vsechny zabanovane
  for FILE in $LISTDIR/*.current ; 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"

# smazat taky soubor s priponou .ban rm "${FILE%.current}.ban"

        else
            # je-li stale zabanovan, obnovit banovani
            BANME=no
            if [ "$DAYTIME1" -gt "$DAYTIME2" ]; then
              [ "$NOWTIME" -ge "$DAYTIME1" -o "$NOWTIME" -lt "$DAYTIME2" ] \
                && BANME=yes
            elif [ "$NOWTIME" -ge "$DAYTIME1" -a "$NOWTIME" -lt "$DAYTIME2" ]; then
              BANME=yes
            fi
      
            if [ "$BANME" = yes ]; then
                IP="${FILE##*/}"

IP="${IP%.current}" $IPTABLES -t mangle -p ! icmp -A SOSACI_pre -i $WATCHIF -s $IP -j unishaper_pre $IPTABLES -t mangle -p ! icmp -A SOSACI_post -o $WATCHIF -d $IP -j unishaper_post

                #$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|start)
  # spustit omezovaci shaper
  unishaper.sh
  # umravnit shaper
  $IPTABLES -t mangle -D PREROUTING -j unishaper_pre
  $IPTABLES -t mangle -D POSTROUTING -j unishaper_post
  $IPTABLES -t mangle -D INPUT -j unishaper_in
  $IPTABLES -t mangle -D OUTPUT -j unishaper_out
  $IPTABLES -t mangle -D FORWARD -j unishaper_fw
  # vytvorit chain kam strkame banovaci pravidla
  $IPTABLES -t mangle -N SOSACI_pre  && $IPTABLES -t mangle -I PREROUTING  -j SOSACI_pre
  $IPTABLES -t mangle -N SOSACI_post && $IPTABLES -t mangle -I POSTROUTING -j SOSACI_post
  # co ma znacku 3 v unishaperu shaper obchazi
  $IPTABLES -t mangle -A SOSACI_pre -i $WATCHIF -j MARK --set-mark 3
  $IPTABLES -t mangle -A SOSACI_post -o $WATCHIF -j MARK --set-mark 3   
  #$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 180 -t 5 -M root@localhost -T "$KLADIVO report" $WATCHIF
  if [ "$LOWLIMIT" != "" ]; then
      $IPBAND -F -L $WATCHNET -m 32 -b $LOWLIMIT -a 60 -r 240 -t 5 -M root@localhost -T "$KLADIVO report" $WATCHIF   
  fi
  exit 0
  ;;

stopwatch|stop)
  killall $IPBAND
  # smazat iptables pravidla (chyby ignorovat, pokud neexistuji)
  $IPTABLES -t mangle -F SOSACI_pre  &> /dev/null
  $IPTABLES -t mangle -F SOSACI_post &> /dev/null
  $IPTABLES -t mangle -D PREROUTING  -j SOSACI_pre  &> /dev/null
  $IPTABLES -t mangle -D POSTROUTING -j SOSACI_post &> /dev/null
  $IPTABLES -t mangle -X SOSACI_pre  &> /dev/null
  $IPTABLES -t mangle -X SOSACI_post &> /dev/null

  unishaper.sh -s

  #$IPTABLES -F SOSACI &> /dev/null
  #$IPTABLES -D FORWARD -j SOSACI &> /dev/null
  #$IPTABLES -X SOSACI &> /dev/null
  exit 0
  ;;

restart)
  $0 stop
  $0 start
  exit 0
  ;;

*)
  echo "usage: $0 startwatch|stopwatch|start|stop|restart|report|cronjob"
  exit 1
  ;;

esac </bash>


vypis kladiva: <bash>#!/bin/sh

  1. Verze 1.02
  2. Autor PavKriz
  3. modifikace Lada JNet

LISTDIR=/var/lib/kladivo

SEP="--------------------------------------------" echo "Content-type: text/plain" echo "" TODAY=`date` ping -c 1 -w 1 10.107.15.17 &> /dev/null && SHOWMAIL=yes echo "Report k datu: $TODAY" echo $SEP NOW=`date +%s`

  for FILE in $LISTDIR/*.current ; do
      echo "$FILE" | grep archive &>/dev/null && continue
      if [ -e "$FILE" ]; then

FILE="${FILE%.current}"

          IP=`basename $FILE`

[ "$SHOWMAIL" == "yes" ] && MAIL=`echo "$IP" | nc -w 2 10.107.15.17 10107`

          HOST=`host $IP | awk "{ print \\$5 }"`
          BANTO=`head -n 1 $FILE.current`
          UNBAN=`expr $BANTO - $NOW`
          UNBAN=`expr $UNBAN / 60`
          # print report
          echo "Adresa: $HOST ($IP)"

[ "$SHOWMAIL" == "yes" ] && echo "Email: $MAIL"

          echo "Bude smazano za: $UNBAN minut"
          echo "Omezeni spusteno kvuli:"
          tail +8 $FILE.ban

echo "Omezeni udrzovano kvuli:" tail +8 $FILE.current

          echo
      fi
  done

</bash>

mensi pokus o prevod kladiva do html:

<nowiki>#!/bin/sh
#
#Verze 1.02
#Autor PavKriz
# 
# modifikace Lada JNet

LISTDIR=/var/lib/kladivo
 
#SEP="--------------------------------------------"
echo "Content-type: text/html"
echo ""
cat << EoF
<HTML>
<TITLE>Kladivo</TITLE>
<BODY>
<img src="http://d-network.hkfree.org/logo.gif"><br>
EoF
TODAY=`date`
ping -c 1 -w 1 10.107.15.17 &> /dev/null && SHOWMAIL=yes
echo "<font size=+1><b> Report k datu: $TODAY </b></font><br><br>"
NOW=`date +%s`
 
   for FILE in $LISTDIR/*.current ; do
       echo "$FILE" | grep archive &>/dev/null && continue
       if [ -e "$FILE" ]; then
	   FILE="${FILE%.current}"
           IP=`basename $FILE`
	   [ "$SHOWMAIL" == "yes"  ] && MAIL=`echo "$IP" | nc -w 2 10.107.15.17 10107`
           HOST=`host $IP | awk "{ print \\$5 }"`
           BANTO=`head -n 1 $FILE.current`
           UNBAN=`expr $BANTO - $NOW`
           UNBAN=`expr $UNBAN / 60`
           # print report
           echo "Adresa: $HOST ($IP)<br>"
	   [ "$SHOWMAIL" == "yes"  ] && echo "Email: $MAIL <br>"
           echo "Bude smazano za: $UNBAN minut<br>"
           echo "<b>Omezeni spusteno kvuli:</b><br>"
	   echo "<pre>"
           tail +8 $FILE.ban
	   echo "

"

echo "Omezeni udrzovano kvuli:"

echo "

"
	   tail +8 $FILE.current
	   echo "

" echo "


"

          echo
      fi
  done

cat << EoF </BODY> </HTML> EoF

</nowiki>

Unishaper

Homepage (v soucasne dobe zde unishaper ke stazeni neni... martina se pozeptam)

unishaper.conf na dnetw: <bash>#!/bin/sh # jen kvuli zvyrazneni syntaxe ve vimu :)

tc=/sbin/tc iptables=/usr/local/sbin/iptables ip=/sbin/ip modprobe=/sbin/modprobe


iface0() { iface="eth5"

  1. ve zkratce, co znamenaji parametry:
  2. root_rate maximalni rychlost vsech dohromady - lze rict, kolik "kladivouni" smi urvat dohromady
  3. rate - garance; musi byt nad 12, je potreba aby garance vsech nepresahla root_rate
  4. ceil - maximalni rychlost v ramci jedne tridy (rychlost uzivatele)
  5. dist - yes/no znamena, jestli je v routru iface vzdaleny od uzivatele, nebo je-li na nej napojen uzivatel primo
  6. pouziva se pouze, pokud nemame imq a vime, kudy potecou odchozi data uzivatele
  1. upload uzivatelu

upload="yes" up_dist="no" up_unit="kbit"

  1. kolik muzou udelat vsichni dohromady

up_root_rate="15000"

  1. default trida - tu nepouzivame; sem jde vse, co neni oznackovano

up_ceil="300" up_rate="25"

  1. jak se pisou subnety je skvele vysvetleno v ukazkovem konfiguraku
  2. ve zkratce:
  3. 10.107.3.1-5 vytvori 5 samostatnych trid (pro 5 ruznych uzivatelu)
  4. 10.107.3.1,10.107.3.2,10.107.3.3 vytvori 1 tridu pro 3 adresy (1 user vlastni vsechny adresy)
  5. 10.107.3.0/27 vytvori 1 tridu pro cely rozsah (cely rozsah patri jednomu uzivateli)
  1. wireless rexornet weetek,bloque jenda rexor

A="10.107.3.130-222 10.107.3.34-46 10.107.3.97-102 85.132.161.218,10.107.3.112/29 10.107.3.14,10.107.3.34,10.107.3.35,85.132.160.163"

  1. yanda radekN&tomask bazina bazina_subnet jaja&kamil mirra&spol

B="10.107.3.147,85.132.160.172 10.107.103.50-51 10.107.3.58,10.107.3.59,10.107.3.60 10.107.3.61-62 10.107.3.122-123 10.107.103.34,85.132.160.170 10.107.103.35,85.132.160.168 10.107.103.36,85.132.160.169"

  1. honya honya_subnet sa dave

C="10.107.3.50,10.107.3.51,85.132.161.219 10.107.3.52-54 10.107.3.104/29 10.107.103.42-43"

  1. A B a C pouzivam jenom, aby se nejak dalo vyznat v tech komentarich
  1. koho shapujem

up_1_range="$A $B $C"

  1. garance

up_1_rate="25"

  1. strop

up_1_ceil="300"

  1. pokud nejaky uzivatel hodne zlobi, lze mu tady vytvorit individualni rychlost, na kterou ho kladivo srazi, napr:
  2. pri individualni hranici je ale treba dbat na to, aby uzivatel mohl prekrocit LOWLIMIT v kladivo.sh,
  3. jinak bude neustale odblokovavan a zablokovavan
  4. up_2_range="10.107.3.1"
  5. up_2_rate="25"
  6. up_2_ceil="100"
  1. download uzivatelu

download="yes" dl_dist="no" dl_unit="kbit"

  1. celkova rychlost

dl_root_rate="15000"

  1. default trida - nepouzivame

dl_ceil="1024" dl_rate="25"

  1. tridy uzivatelu

dl_1_range="$up_1_range" dl_1_ceil="800" dl_1_rate="25"

  1. dl_2_range="$up_2_range"
  2. dl_2_ceil="450"
  3. dl_2_rate="25"

}

tests="yes" </bash>