Robot pro omezení zahlcujícího provozu: Porovnání verzí
| Řá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
- Verze 1.06 -> 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
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
- 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
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
- 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:
<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"
- 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>