Hlavní navigace

Monitorování přenesených dat v síti s 1000 IP adresami

22. 6. 2012
Doba čtení: 10 minut

Sdílet

Potřeboval jsem na jedné městské síti udělat statistiky přenosů. V síti se nachází přibližně 1000 IP adres a je potřeba udržovat statistiku pro každou z nich. Chtěl jsem mít data uložená v co nejuniverzálnější formě, aby se s nimi dalo dále pracovat, a rozhodl jsem se k tomu použít NoSQL databázi MongoDB.

Problém

O monitorovacích nástrojích už se na Rootu psalo v několika článcích, např:

V každém článku se nachází informace o jednom nástroji a každý z nich se soustředí na trochu jinou oblast. Collectd a jeho backend RRDTool je velmi dobrý na grafy, ale dostávat data z round robin databází není nic pohodlného. Cacti kombinuje RRDTool a MySQL a snaží se být univerzálním nástrojem k monitorování všeho. VnStat je zas velmi dobrý na udržování statistik k síťovým rozhraním. Já potřeboval udělat nástroj pro měření přenesených dat na jednotlivých IP adresách, což je problém řešitelný mnoha způsoby, a já dnes představím ten svůj.

Požadavky jsem měl následující:

  • Napojení na interní systém přes JSON-RPC
  • Rychlé odezvy na RPC
  • Denní/týdenní/měsíční/roční statistiky
  • Grafy
  • Využití dat pro optimalizaci firewallu a shaperu
  • Zpracování dat v různých jazycích a nástrojích

Jak získat data

Data o přenosech dle IP adresy se na Linuxu dají získat dvěma způsoby. Nejjednodušší je použití linuxového firewallu iptables, který má u každého pravidla čítač paketů, které jím prošly, a součet jejich velikostí. V mém případě nebylo proč váhat, protože stroj, pro který dělám statistiky, má přes iptables řešený whitelist, tedy jsou v něm uvedeny adresy, které mohou komunikovat směrem ven. Pokud se rozhodnete pro iptables, dejte si pozor na množství pravidel a zda nějaké pravidlo nezastavuje pakety, ještě než projdou vaším seznamem.

Můžete také narazit na limity vašeho stroje. Při rozhodování je potřeba zohlednit:

  • Výkon routeru
  • Počet IP adres
  • Množství paketů, které routerem projde

Mám-li být konkrétní, tak na mém routeru prochází ve špičce kolem 100 Mb ve 14 000 paketech za sekundu jedním směrem. V iptables se aktuálně nachází 1940 pravidel, z nichž většina slouží jako whitelist a je nastavena tak, aby každý paket musel přes tento seznam projít. Na routeru je procesor Intel® Xeon® CPU X3440 @ 2.53GHz, který si bez problémů poradí přibližně s 30 000 takovými pravidly za současných podmínek. Řešení vyžaduje určitou pozornost, a s rostoucím počtem pravidel je potřeba buď upravit jejich pořadí tak, aby většina paketů firewall co nejdříve opustila, nebo je rozdělit do více řetězců, aby firewall nemusel procházet tolik záznamů, než narazí na ten správný. Se statistikou přenosů by neměl být problém pravidla seřadit tak, aby nejaktivnější IP adresy byly výše než ty méně aktivní.

Data lze z iptables dostat různými způsoby, ale nejuniverzálnější je parsování jeho výstupu:

# iptables -L IPS -n -v -x
Chain IPS (2 references)
    pkts      bytes target     prot opt in     out     source               destination
    89     5035 ACCEPT     all  --  *      *       0.0.0.0/0            10.17.252.162
799625 202345998 ACCEPT     all  --  *      *       0.0.0.0/0            10.17.252.146
    0        0 ACCEPT     all  --  *      *       0.0.0.0/0            10.16.21.1
[...] 

Pro získání dat je důležitý první a poslední dvojice údajů. V prvním sloupci najdeme počet paketů, v druhém jejich celkovou velikost, v předposledním cílovou adresu a v předpředposledním zdrojovou.

Druhou možností jak získat data, je využití shaperu. Je to komplikovanější možnost, protože je potřeba přiřadit přenesená data k ip adrese na základě společného klíče classid, což už vyžaduje trochu více programování než hloupé přečtení výstupu z iptables a také vědět něco o tom, jak shaper v Linuxu funguje. S tím vám může pomoci třeba náš článek HTB – jemný úvod a jeho pokračování. Na druhou stranu se nemusí nezbytně zatěžovat router pravidly ve firewallu, ale stačí přečíst již vytvořený strom a jeho filtry. K informacím o přenosech se dá dostat pomocí programu tc:

# tc -s class show dev imq0
[...]
class hfsc 1:106 parent 1:1 leaf 106: sc m1 0bit d 0us m2 128000bit ul m1 0bit d 0us m2 8192Kbit
Sent 1370955213 bytes 1007514 pkt (dropped 94, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
period 35828 work 1370956909 bytes rtwork 30297611 bytes level 0

class hfsc 1:989 parent 1:1 leaf 989: sc m1 0bit d 0us m2 128000bit ul m1 0bit d 0us m2 102400Kbit
Sent 17821762 bytes 39774 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
period 39109 work 17821762 bytes rtwork 10909492 bytes level 0
[...] 

Důležité informace jsou rozprostřené přes 4 řádky, z nichž potřebujeme první dva. V prvním se nachází classid a v druhém samotné údaje o přenosech. Classid použijeme k získání IP adresy z filtru:

# tc filter show dev imq0
[...]
filter parent 1: protocol ip pref 200 u32 fh 800::808 order 2056 key ht 800 bkt 0 flowid 1:10
match c208fcc1/ffffffff at 16
filter parent 1: protocol ip pref 200 u32 fh 800::809 order 2057 key ht 800 bkt 0 flowid 1:11
match c208fc84/ffffffff at 16
[...] 

Informace jsou zase na více řádcích. Tentokrát potřebujeme údaj flowid, který koresponduje s našim classid a na dalším řádku je pak hexadecimálně zapsaná IP adresa s maskou.

Uložení dat v MongoDB

Máme-li data, je potřeba je někam uložit. Možností je víc než dost, ale záleží hlavně na tom, co od statistik očekáváte. Nemusíte ani ukládat jednotlivá měření, ale už agregovaná data tak, jak je budete zobrazovat ve svém systému. Nebo si můžete uchovávat všechno a krom testu schopností databáze poradit si s opravdu velkým množstvím dat, získáte i dostatečně granulovaná data pro denní grafy. Určitě data sbírejte často, třeba jednou za 5 až 10 minut, protože oba čítače se nulují, ať už při restartu stroje nebo při přetečení proměnné (na 32bit systémech).

Dnes už si snad každá běžně používaná databáze poradí s množstvím dat, které tímto způsobem získáte. Určitě neprohloupíte s PostgreSQL nebo MySQL. Obě databáze dokáží velmi rychle agregovat nasbíraná data (alespoň dokud stačí RAMka) a ani nepotřebují moc prostoru k jejich uložení. Navíc mocný jazyk SQL vám otevírá obrovské možnosti v další práci s daty. V případě, že potřebujete jen grafy, neváhejte použít RRDTool, o kterém si můžete přečíst v našem seriálu Prechádzame na RRDTOOL. Je to vynikající nástroj přesně navržený pro tento úkol a potřebná data udrží na několika megabytech prostoru. Data z RRD databází můžete exportovat do XML pro další zpracování. Naopak nevhodné je použití třeba databáze Redis, která všechna data drží v paměti kvůli rychlosti.

Jak jsem psal výše, vybral jsem si databázi MongoDB a to z následujících důvodů:

  • Jednoduché ne-SQL rozhraní
  • Wrapper pro mnoho jazyků
  • Škálovatelnost
  • JSON dokumenty
  • Výkon
  • 30MB deb balík bez závislostí

S MongoDB se komunikuje JavaScriptovým stylem. Je to univerzální rozhraní, které se neztratí ani v jenom ze třinácti podporovaných jazyků. Uvnitř MongoDB běží JavaScriptové jádro V8 a nad daty je možné spouštět JavaScriptové funkce, což pro jejich zpracování otevírá neomezené možnosti. Data jsou do databáze vkládána i z ní vybírána jako JSON dokumenty, s čímž si poradí většina programovacích jazyků. V případě Pythonu, který pro tento úkol používám, jsou data převáděna přímo do jeho slovníků. Stejně jako u mnoha jiných databázi, ani MongoDB nemá problémy s počtem záznamů a záleží jen na množství, se kterými chceme pracovat. To většinou nekopíruje celou databázi a dobře vytvořené indexy se postarají o rozumnou rychlost.

I tak se na některé operace MongoDB nehodí. JavaScriptové jádro V8 sice dává neomezenou moc nad daty, ale s výkonem to není tak dobré, a pokud si data vytáhnete mimo databázi a uděláte potřebné akce v Pythonu, C++ či jiném jazyku, můžete se snadno stát, že dostanete výsledek několikanásobně rychleji. Na druhou stranu se nejedná o žádnou kritickou aplikaci, kde by na rychlosti záleželo, a pokud už záleží, dá se vše dobře cachovat. Výše je zmíněná například agregace, kterou je lepší dělat průběžně a ukládat naměřené hodnoty tak, jak je budete později číst. V případě dopočítávání za chodu a navíc v MongoDB se získávání dat protáhne i na minuty za každý zaznamenaný týden.

Druhý problém může nastat s velikostí databáze, protože MongoDB není zrovna úsporné úložiště. V mém případě to nevadí, router má 320 GB veliké a rychlé disky, z nichž je 315 GB nezaplněno. Pokud takové možnosti nemáte, počítejte s tím, že data zaberou hodně prostoru a na routerech s malými disky či paměťmi je lepší je držet mimo nebo použít jiné úložiště. Pokud chcete použít MongoDB i tam, kde nemáte moc místa, zvažte, zda opravdu musíte uchovávat každé měření. V případě že ne, ušetříte si kolem 130 B v jednom měření na jednu IP adresu. Také si dejte pozor na limity MongoDB na 32bit platformě.

Do svých statistik ukládám následující informace:

  • Množství přenesených bytů ven
  • Množství přenesených bytů dovnitř
  • Počet přenesených paketů ven
  • Počet přenesených paketů dovnitř
  • Čas, za který byly hodnoty nasbírány
  • Adresa stroje

Kromě prvních čtyřech hodnot lze z páté vypočítat průměrnou rychlost za měřené období, a to jak pro pakety, tak pro data v obou směrech. Jeden záznam zabere v průměru 136 B, což při počtu 970 IP adres dělá něco málo přes 128 kB dat za jedno měření. V případě pětiminutových intervalů to je 36,2 MB denně, 253 MB týdně, něco přes 1 GB měsíčně a 12,9 GB ročně. MongoDB si kolem dat ještě vytvoří nějaká metadata, která se umí také nafukovat. Navíc se místo pro data předalokovává a celkově může být i několikrát větší, než je velikost skutečných dat. Kolik prostoru bude nakonec potřeba, ukáže až čas.

K čemu data použít

Máme-li data, můžeme je samozřejmě zobrazit, a to jak uživatelům, tak administrátorovi, který se o klienty na síti stará. V mých požadavcích bylo ještě JSON-RPC, které data zpřístupní interním aplikacím pro správu uživatelů.

Ale se získanými daty se dají dělat různé věci a ne je jen ukazovat. Pro samotný router není ani tak důležité, kolik přes něj proteklo dat, jako množství paketů. Paket je to, s čím router pracuje, většinou se nedívá dovnitř, ale stráví nějaký čas nad jeho hlavičkami. V mé síti za dobu monitorování přiteklo z internetu kolem 2,3 miliardy paketů a 1,9 miliardy šlo ven, což datově dělá kolem 2 TB dovnitř a 600 GB ven. Když si zobrazím statistiky:

    Address              Bytes In   Bytes Out  Pkts In    Pkts Out
    --------------------------------------------------------------
1.  10.17.253.16         30.38 GB   107.70 GB  423.99 M   401.04 M
2.  10.16.20.92          114.30 GB  49.31 GB   117.10 M   96.99 M
3.  10.17.252.156        96.64 GB   35.87 GB   94.10 M    72.82 M
4.  10.17.253.50         6.29 GB    32.87 GB   89.38 M    149.14 M
[...]
10. 10.16.20.101         28.07 GB   8.13 GB    27.72 M    19.85 M
[...]
20. 10.16.20.94          12.50 GB   7.38 GB    15.21 M    14.26 M
[...]
50. 10.17.211.83         10.88 GB   204.44 MB  7.61 M     3.83 M 

Zjistím, že pakety jdoucí dovnitř jsou:

  • z 50 % určeny pro 25 adres
  • z 60 % určeny pro 50 adres
  • z 70 % určeny pro 100 adres
  • z 80 % určeny pro 150 adres
  • z 90 % určeny pro 250 adres

Celkově 50 % provozu směrem dovnitř, který prochází shaperem a firewallem, jde pouze na 25 adres z 970, což už stojí za tu námahu srovnat pravidla a filtry tak, aby se tyto adresy objevovaly někde nahoře a jejich 1,15 miliard paketů nezdržovala procesor při hledání správné díry.

Statistiky mohou pomoci také při testování nastavených restrikcí, například vůči uživatelům, kteří za svoje připojení nezaplatili. Stejně tak mohou sloužit jako kontrola nastavení shaperu, i když na to jsou specializovanější nástroje, například tctop. Někdy mohou správná čísla pomoci zjistit, že se něco děje. Uživatelé někdy nehlásí problém, i když vědí, že ho mají a doufají, že se vyřeší sám. Pokud uživatel za určitý čas přenášel tolik a tolik dat a hodnota se držela konstantně, je minimálně podezřelé, když se za stejný čas v jiném období změní.

root_podpora

Dále statistiky pomohou v komplikovanějších situacích. Například pokud máte „placatý“ shaper, kde jsou si všechna pravidla rovna, pak se může snadno stát, že některá část sítě bude přetížená. Pomocí nasbíraných dat můžete pro svůj strom sítě spočítat, kolik na jakém spoji teklo maximálně dat a porovnat to s reálnou propustností tohoto stroje. Podaří se vám tak odhalit slabší místa vaší sítě a zlepšit kvalitu připojení vašich uživatelů. V případě že máte složitější shaper kopírující strukturu vaší sítě, platí to samé, jen uživatelé to tak nepociťují.

Shrnutí

V článku jsem popsal vlastní zkušenosti se sběrem dat pro vytváření statistik přenosů. Také jsem se snažil uvést, k čemu data hodlám použít, používám nebo se o to ještě pokusím. Mám připravený skript pro sběr dat a základní nástroje pro jejich zpracování. Pokud by byl z řad čtenářů zájem, určitě bych pokračoval u praktických ukázek a prezentoval bych výsledky, kterých se podařilo díky těmto datům dosáhnout. Pokud máte jiný názor na ukládání dat nebo případně máte jiný nápad, jak data využít, určitě se o to podělte v diskusi.

Byl pro vás článek přínosný?

Autor článku

Adam Štrauch je redaktorem serveru Root.cz a svobodný software nasazuje jak na desktopech tak i na routerech a serverech. Ve svém volném čase se stará o komunitní síť, ve které je již přes 100 členů.