@D:
Tekst pokazuje prosty sposób na monitorowanie obciążenia łącza
do interentu, z podziałem na sieci docelowe lub usługi za pomocą rrd i
iptables.
@T:
Monitorowanie ruchu za pomocą rrd i iptables.
@V:
Ostatnio przez Internet przetoczyła się dyskusja spowodowana problemami
z transmisją na styku sieci akademickich - Pol-34 a siecią TP S.A.
Oczywiście, jak zwykle poszło o pieniądze i dodatkowo, żeby sprawę
utrudnić, można było odnieść wrażenie, że poza pieniędzmi chodziło o
ambicje dwóch, bardzo dużych jak na nasze polskie warunki, sieci.
@V
W trakcie tej dyskusji przerzucano się statystykami błędów,
obciążeń, wielkością styków z danym operatorem, itp. Dodatkowo
pojawiło się wiele głosów omawiających kierunki ruchu, w
którym idzie większość ruchu internetowego od większych i
mniejszych operatorów, pomiędzy jakimi sieciami wymiana ruchu
jest zbliżona, gdzie jest asymetryczna itd. Ponieważ sam byłem ciekaw
jak to jest naprawdę i kto tak naprawdę korzysta z danych zgromadzonych
na moim serwerze, postanowiłem się temu przyjrzeć.
@V
Sytuacja była o tyle skomplikowana, że chodzi o jeden serwer z Linuksem
na pokładzie, a nie o router z oprogramowaniem gotowym do generowania
takich statystyk za pomocą NetFlow. Ostatecznie okazało się to prostsze
niż się spodziewałem i już wiem od kogo mogę żądać peeringu;)
@V
Celem było potwierdzenie lub zaprzeczenie tezie, jakoby gros ruchu z
większości sieci szło w kierunku TP S.A., przy okazji dodatkowym
zadaniem było ograniczenie ruchu ftp do określonego poziomu. Całość
musiała się rozstrzygnąć przy pomocy narzędzi ogólnie dostępnych
w oparciu o dane zgromadzone z niedużego serwera z Linuksem, z serwerem
ftp z popularną zawartością i kilkoma mniejszymi rzeczami (www, smtp,
pop3).
@ZT:
Zabawa w kopciuszka czyli zliczanie pakietów.
@L:
Żeby móc zacząć robić statystyki musiałem zacząć od posortowania
ruchu wg kategorii, które chciałem później analizować.
Interesowały mnie tak naprawdę cztery kategorie ruchu:
- całość ruchu wychodzącego z serwera
- ruch wychodzący w kierunku TP S.A.
- ruch wychodzący w kierunku GTS, w tym wypadku głównego dostawcy łącza
- ruch wychodzący ftp generowany przez użytkownika, z którego prawami działał serwer ftp z dostępem anonimowym
@L:
Po przeczesaniu freshmeat.net i googlowaniu za odpowiednimi narzędziami
ostatecznie okazało się, że poczciwe iptables jest doskonałym
narzędziem do zabawy w Kopciuszka.
@L:
Wykorzystałem łańcuch mangle, który pozwalał na znakowanie
pakietów wg kategorii określonych powyżej. Mangle poza
możliwością znakowania ruchu jest celem nieterminującym, czyli pakiety,
które zostaną wysłane do tego właśnie celu, są dalej
przetwarzane przez iptables. Do samego ograniczania ruchu ftp z serwera
skorzystałem z pomocy tc.
@L:
Poniżej krok po kroku przedstawiam konfigurację iptables, która
pozwoliła na pogrupowanie ruchu, oznakowanie ruchu i okresowe zbieranie
statystyk.
@L:
Na początek dla porządku czyszczę cały łańcuch mangle:
@LI:
iptables -t mangle -F
@L:
Żeby móc coś powiedzieć o ilości danych przesyłanych w
określonym kierunku potrzebowałem informacji o sumie ruchu wychodzącego
z serwera. Aby oznakować cały ruch utworzyłem własny łańcuch i tam
skierowałem wszystkie pakiety wychodzące. W łańcuchu tym pakiety
wpadające do niego otrzymują znacznik 0x11.
@KT:Znakowanie wszystkich pakietów
@LI:
iptables -t mangle -X all_data
iptables -t mangle -N all_data
iptables -t mangle -A OUTPUT -o $ETH -j all_data
iptables -t mangle -A all_data -j MARK --set-mark 0x11
@L:
Oczywiście można to zrobić w jednym łańcuchu, ale ponieważ zliczane
będą jeszcze inne grupy pakietów, zależało mi na jednakowym
sposobie sumowania ruchu wychodzącego.
@L:
Podobnie znakowany będzie ruch wychodzący w kierunku operatora. Warto
zwrócić uwagę, że znaczniki nadane we wcześniejszych liniach
będą nadpisywane przez kolejne, jeśli pakiety trafią do różnych
łańcuchów. W tym przypadku będzie tak zawsze, bo każdy pakiet
wychodzący w kierunku GTS jest także pakietem wychodzącym w
ogóle.
@KT:Znakowanie pakietów wychodzących w kierunku GTS
@LI:
iptables -t mangle -X gts
iptables -t mangle -N gts
iptables -t mangle -A OUTPUT -o $ETH -d 195.94.192.0/19 -j gts
iptables -t mangle -A OUTPUT -o $ETH -d 217.8.160.0/19 -j gts
iptables -t mangle -A OUTPUT -o $ETH -d 217.153.0.0/16 -j gts
iptables -t mangle -A gts -j MARK --set-mark 0x21
@L:
Pojawia się przy okazji pytanie skąd brać aktualne zakresy
adresów IP przypisane do danego operatora. Te dane udostępniają
serwery whois. Jeśli chcę uzyskać spis sieci przyznanych TP S.A.
wystarczy użyć polecenia:
@KT:Wyszukiwanie prefiksów rozgłaszanych przez operatora
@LI:
vix:~# whois -h filtergen.level3.net RIPE::AS5617
vix:~# whois -h filtergen.level3.net RIPE::AS5617
Prefix list for policy RIPE::AS5617 = RIPE::AS5617
80.48.0.0/13
83.0.0.0/11
194.204.128.0/18
...
@L:
Podobnie jak powyżej oznaczałem pakiety skierowane do sieci GTS,
oznaczam pakiety wychodzące do sieci TP S.A. Należy tylko zmienić
zakresy sieci docelowych (opcja -d) oraz znacznik, którego
użyję (opcja -set-mark).
@KT:Znakowanie pakietów wychodzących w kierunku TP S.A.
@LI:
iptables -t mangle -X tpnet
iptables -t mangle -N tpnet
iptables -t mangle -A OUTPUT -o $ETH -d 80.48.0.0/13 -j tpnet
iptables -t mangle -A OUTPUT -o $ETH -d 83.0.0.0/11 -j tpnet
iptables -t mangle -A OUTPUT -o $ETH -d 194.204.128.0/18 -j tpnet
...
...
iptables -t mangle -A tpnet -j MARK --set-mark 0x31
@L:
Pozostaje mi policzyć pakiety wysyłane do użytkowników mojego
serwera ftp. Tę regułkę zostawiam na koniec po to, aby żadne inne nie
nadpisały znacznika w przypadku ściągania danych z serwera ftp przez
użytkowników GTS. Gdyby znakowanie według adresów GTS
następowało po znakowaniu ruchu ftp, nie mógłbym później
ograniczać ruchu z serwera ftp, bo część znaczników zostałaby
nadpisana.
@KT:Znakowanie wychodzących pakietów ftp
@LI:
iptables -t mangle -X ftp
iptables -t mangle -N ftp
iptables -t mangle -A OUTPUT -o $ETH \
-m owner --uid-owner anonftp -j ftp
iptables -t mangle -A ftp -j MARK --set-mark 0x41
@L:
Następnie sprawdzam czy ruch jest rzeczywiście zliczany:
@KT:Pokazywanie informacji o wychodzących danych ftp
@LI:
vix:~# iptables -t mangle -L ftp -n -v -x
Chain ftp (1 references)
pkts bytes
target prot opt in
out
source
destination
1002842 1356515158 MARK
all -- *
*
0.0.0.0/0
0.0.0.0/0
MARK set 0x41
@L:
Połowa zadania jest wykonana: pakiety zostały poznakowane i są już
zliczane. Ruch ftp mogę następnie w dogodny dla siebie sposób
ograniczyć za pomocą tc.
@KT:Ograniczenie ruchu wychodzącego ftp
@LI:
tc qdisc del dev $ETH root
tc qdisc add dev $ETH root handle 1: htb default 10
tc class add dev $ETH parent 1: classid 1:1 htb rate 2mbit ceil 2mbit
tc class add dev $ETH parent 1:1 classid 1:10 htb rate 2mbit prio 1
tc class add dev $ETH parent 1:1 classid 1:20 htb rate 1024kbit prio 2
tc qdisc add dev $ETH parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev $ETH parent 1:20 handle 20: sfq perturb 10
tc filter add dev $ETH protocol ip parent 1: prio 2 handle 0x41 \
fw flowid 1:20
@ZT:
Wykresy.
@L:
Teraz przydałoby się pokazać zebrane dane w jakiejś rozsądnej postaci.
Zdecydowałem się na rrd, które jest następcą zasłużonego i
wysłużonego mrtg. rrd daje znacznie większe możliwości jeśli chodzi o
manipulację danymi gromadzonymi w bazach .rrd jak i o prezentację
wyników w formie wykresów.
@L:
Na początku trzeba stworzyć plik .rrd, w którym będą zbierane informacje:
@KT:Tworzenie pliku w którym będa zbierane statystyki RRD
@LI:
rrdtool create stats.rrd -s 60 \
DS:all_data:COUNTER:600:0:U \
DS:gts:COUNTER:600:0:U \
DS:tpnet:COUNTER:600:0:U \
DS:ftp:COUNTER:600:0:U \
RRA:AVERAGE:0.5:1:10080 \
RRA:AVERAGE:0.5:2:5040 \
RRA:AVERAGE:0.5:4:2520 \
RRA:AVERAGE:0.5:6:1680 \
RRA:AVERAGE:0.5:180:56 \
RRA:AVERAGE:0.5:360:28
@L:
Polecenie to tworzy plik stats.rrd inicjując kolejno cztery
źródła danych - DS. Każde ze źródeł będzie przechowywać
informacje o określonym typie ruchu. Minimalna wartość została ustalona
na 0, maksymalna jest niezdefiniowana U. Dane będą pobierane co 60
sekund, a przechowywane próbki określane są przez rekordy
RRA.
@LI:
RRA:AVERAGE:0.5:1:10080
@L:
Średnia z jednej próbki, czyli z 60 sekund; przechowywanych będzie 10080 próbek, co daje ostatecznie:
10080 min / 60 minut / 24 godziny = 7 dni.
@LI:
RRA:AVERAGE:0.5:180:56
@L:
Średnia ze 180 próbek, czyli z trzech godzin; przechowywanych będzie 56 próbek. Ostatecznie daje to:
3 godziny * 56 próbek = 174 godziny = 7 dni.
@L:
Po szczegółowy opis parametrów rrd odsyłam do stron rrd,
może warto tylko dodać, że jako typ danych został wybrany COUNTER,
ponieważ pozwala on zliczać stale rosnące dane i dobrze radzi sobie z
przewijającymi się licznikami.
@L:
Następnie będę wypełniać plik stats.rrd danymi sczytywanywanymi w
odstępach jednominutowych. Do tego wykorzystam prosty skrypcik
uruchamiany poprzez cron w następujący sposób:
@LI:
* * * * * /home/mazek/bin/update.sh
@L:
Sam skrypt ma za zadanie odczytać stan liczników dla podanych łańcuchów oraz wprowadzić te dane do bazy rrd.
@KT:Skrypt do aktualizowania danych w pliku rrd
@LI:
#!/bin/bash
ITM="/sbin/iptables -t mangle"
# Pobieramy liczbę bajtów z podanego łańcucha.
ALL_DATA=`$ITM -L all_data -n -x -v | tail -n 1 | awk -F " " {'print $2;'}`
GTS=`$ITM -L gts -n -x -v | tail -n 1 | awk -F " " {'print $2; '}`
TPNET=`$ITM -L tpnet -n -x -v | tail -n 1 | awk -F " " {'print $2; '}`
FTP=`$ITM -L ftp -n -x -v | tail -n 1 | awk -F " " {'print $2; '}`
# Wprowadzamy dane pobrane do pliku .rrd
rrdtool update stats.rrd N:$ALL_DATA:$GTS:$TPNET:$FTP
@L:
I tu zaczyna się najlepsze, czyli narysowanie tego co zgromadziłem. rrd
daje pod tym względem ogromne możliwości w porównaniu do swojego
porzednika - mrtg. Możliwości prezentacji danych przez rrd w
różnoraki sposób są naprawdę imponujące i dla kogoś, kto
wcześniej korzystał z mrtg - wręcz przytłaczające;)
@L:
Na początek zgromadzę wszystkie dane na jednym wykresie:
@KT:Generowanie wykresu
@LI:
COMMENT="Ostatnia aktualizacja: "` date +"%d/%m/%Y %T"`
rrdtool graph stats1.gif --title="Ruch wychodzący z vix" \
-w 700 --start -129600 \
DEF:all_data=stats.rrd:all_data:AVERAGE \
DEF:gts= stats.rrd:gts:AVERAGE \
DEF:tpnet= stats.rrd:tpnet:AVERAGE \
DEF:ftp= stats.rrd:ftp:AVERAGE \
DEF:www= stats.rrd:www:AVERAGE \
HRULE:100000#000000:"MAX limit" \
LINE3:all_data#0000ff:"Cały ruch z vix"\
LINE2:gts#ff0000:"Ruch do GTS"\
LINE2:tpnet#fff000:"Ruch do TPNET"\
LINE2:ftp#00ffff:"Ruch ftp z serwera"\
LINE2:www#888282:"Ruch www z serwera"\
COMMENT:"
"\
COMMENT:"$COMMENT" \
--vertical-label "bits/sek"
@L:
To polecenie wykonuję za każdym razem, kiedy chcę obejrzeć najnowsze
dane z pliku stats.rrd. Można je także wrzucić do crona i wykonywać w
wybranych okresach czasu. Wykres wygenerowany za pomocą tego polecenia
będzie prezentował dane z ostatnich trzydziesty sześciu godzin (129600
sekund). Parametr DEF określa źródło danych i sposób ich
interpretowania. Mnie interesuje wartość średnia z przedziału
czasowego, czyli AVERAGE. Ponieważ chcę pokazać całość na jednym
wykresie, definiuję cztery źródła danych. Linię wykreślającą
całość ruchu z serwera rysuję najgrubszą linią - LINE3, kolorem
czerwonym - wartość rgb: ff0000, pozostałe będą kreślone linią średniej
grubości - LINE2 w różnych kolorach. Na dole wygenerowanego
obrazka dodana zostanie legenda łącząca kolory z określonym typem ruchu
pokazywanego, oraz komentarz.
@Bi:mark41.gif
@B:Rysunek 1: Wykres pokazujący wszystkie typy zliczanego ruchu.
@L:
Rysunek 1 pokazuje wszystkie typy ruchu monitorowanego na jednym
wykresie. Każdy z rodzaj ruchu pokazywany jest za pomocą linii.
Uzyteczność tego typu wykresów jest więc ograniczona.
@L:
Żeby nie mieszać rzeczy niepowiązanych ze sobą, czyli statystyk typu
ruchu (ftp, www) i celu danych (TP S.A., GTS), rozbijam poprzedni
wykres na dwa oraz próbuję sprawić żeby stał się bardziej
czytelny.
@KT:Generowanie wykresu
@LI:
rrdtool graph stats2.gif --title="Ruch z eth vix, z podzialem na sieci" \
-w 700 --start -129600 \
DEF:all_data= stats.rrd:all_data:AVERAGE \
DEF:gts= stats.rrd:gts:AVERAGE \
DEF:tpnet= stats.rrd:tpnet:AVERAGE \
AREA:all_data#0000ff:"Cały ruch z vix"\
AREA:tpnet#fff000:"Ruch do TPNET"\
STACK:gts#ff0000:"Ruch do GTS"\
--vertical-label "bits/sek"
@Bi:mark42.gif
@B:Rysunek 2: Ruch pogrupowany wg celu danych.
@L:
Rysunek 2 pokazuje zestakowane dane o ruchu wychodzącym wg. celu pakietów wychodzących.
@KT:Generowanie wykresu
@LI:
rrdtool graph stats3.gif --title="Ruch z eth vix, z podzialem na usługi" \
-w 700 --start -129600 \
DEF:all_data= stats.rrd:all_data:AVERAGE \
DEF:ftp= stats.rrd:ftp:AVERAGE \
DEF:www= stats.rrd:www:AVERAGE \
AREA:all_data#0000ff:"Cały ruch z vix"\
AREA:ftp#00ffff:"Ruch FTP"\
STACK:www#888282:"Ruch WWW"\
--vertical-label "bits/sek"
@Bi:mark43.gif
@B:Rysunek 3: Ruch pogrupowany wg typu danych.
@L:
Rysunek 3 pokazuje zestakowane dane o ruchu wychodzącym wg. usług. W tym przypadku badamy jedynie ftp i www.
@L:
W obydwu przypadkach utworzone zostały wykresy pokazujące dane z
ostatnich sześciu godzin. Źródła danych (DEF) zostały
ograniczone tylko do tych, które mnie interesują. Co
najważniejsze, zmienił się także sposób prezentacji. Zamiast
linii wykreślających poziom ruchu danego typu, pokazuję wypełnione
obszary. W obydwu przypadkach całość ruchu jest pokazywana kolorem
granatowym. Na Rys. 2. na obszarze granatowym pokazywane są dane o
ruchu do sieci GTS i TP S.A. Ruch do sieci TP S.A. pokazany jest za
pomocą koloru żółtego, do sieci GTS za pomocą koloru czerwonego.
Jak widać, można spokojnie rozpoczynać negocjacje z TP S.A. w kwestii
darmowej wymiany ruchu;)
@L:
Co ważne, ruch do różnych sieci pokazywany jest w formie
zestakowanych a nie nakładających się obrazów dzięki użyciu
słowa kluczowego STACK. Podobnie jest na rysunku 3., który
pokazuje różne typy ruchu. Granatowy kolor oznacza całość ruchu
wychodzącego, jasnoniebieski obszar to wychodzący ruch ftp a szary
obszar to ruch www.
@L:
Jak widać, za pomocą prostych i powszechnie dostępnych narzędzi można
uzyskać bardzo ciekawe informacje. Oczywiście rozwiązania te nie
zastąpią zintegrowanych narzędzi do analizy ruchu, ale w dużym stopniu
mogą ułatwić zarządzanie siecią i dostępnym pasmem.
@IT:Info
@IL:
[1] Strona domowa projektu RRD
<U>http://www.rrdtool.com/<U>
@IL:
[2] Strona domowa projektu NetFilter
<U>http://www.netfilter.org/<U>
@IT:Autor
@IL: Marcin Mazurek ...