"Egy kis rendszerfelügyelet" jeligére gondoltam, közzéteszem ezt az apró egysoros szkriptet, amely sorokból oszlopokat gyárt.
Probléma: IPSec VPN kapcsolatokat monitorozó rendszer nagy kieséseket mutat, közben a VPN-t termináló tűzfal szerint csak ezred- vagy tizedmásodperces "megállások" vannak, amíg a Phase2-es kulcsokat újragenerálja. Az első monitorozó rendszer hibájának kizárására egy újabb, független monitorozó rendszert állítottak be, de az egy harmadik értéket mutatott. Arra kértek, hogy zárjam ki a zavaró tényezőket és határozzam meg, mi lehet a hiba.
A megoldáshoz csak SNMP lekérdezés használható, mivel szigorú szabályozás miatt más nem engedélyezett. A tűzfal logjaiban nincs ok kételkednem, de arra gyanakodtam, hogy (bár a teljesítmény-mérések erről nem tanúskodtak) valamivel el van foglalva, ezért csak késve frissíti be az SNMP regisztereit, így a lekérdezés pontatlan.
Feladat: SNMP lekérdezéssel egy tűzfalról lekérni perces intervallummal a VPN kapcsolatok állapotait, ezt egy fájlban rögzíteni, majd utólag a fájlból könnyen értelmezhető táblázatot kell készíteni.
Megoldás
A lekérdezés természetesen nem nehéz:
while true; do
date +"%Y-%m-%d %H:%M:%S" >> snmp.out
snmpwalk -v 2c -c <community_string> <OID> >> snmp.out
sleep 60
done
A community azonosító és az OID, amely végülis a konkrét állapotokat tartalmazza, esetünkben lényegtelen. Még némi átalakítást is végeztem, és csak utána tettem be a fájlba az eredményt. A lényeg, hogy a fájlban ez látható:
2012-12-13 17:46:02
0 active(1)
1 active(1)
2 active(1)
3 active(1)
4 active(1)
5 active(1)
6 active(1)
7 active(1)
8 active(1)
9 active(1)
10 active(1)
11 active(1)
12 active(1)
13 active(1)
14 active(1)
15 active(1)
16 active(1)
17 active(1)
18 active(1)
19 active(1)
20 inactive(0)
21 inactive(0)
22 active(1)
23 active(1)
2012-12-13 17:47:03
0 active(1)
1 active(1)
2 active(1)
3 active(1)
4 active(1)
...
A problémánk tehát az, hogy egymás alatti sorokba vannak rendezve az egyes VPN csatornák állapotai, nekünk pedig úgy lenne jó, ha egy-egy időponthoz tartozó összes VPN állapot egy sorban lenne - magyarul oszlopokat kell gyártanunk sorokból. Szedjük elő hát kedvenc awk-nkat:
awk 'BEGIN{ORS=""} {for ( x = 0; x < 24; x++ ) { sub(/.+active\(/,"");sub(/\)/,""); print $0" "; getline; } print "\n";}' snmp.out > eredmeny.txt
Természetesen a fentiek értelmezése nem okozhat gondot senkinek, aki a bevező írásomon túljutott. :-P Mégis értelmezném a fenti egysorost :-):
A BEGIN részben az output record separator-t, azaz a sorokat elválasztó karaktert (ami nem meglepően alapértelmezetten \n, azaz soremelés) kinullázzuk. Ezzel azt érjük el, hogy a feldolgozott sorok többé nem sorok, hanem egyetlen hosszú adatfolyam.
A for ciklus természetesen arra kell, hogy a formázatlanná tett sorok ismét formázottak legyenek, ezúttal viszont úgy, hogy a dátum és mögötte a VPN státuszok egy egységet kell képezzenek.
A két sub() függvény egyszerű cserét végez el annak érdekében, hogy csak a zárójelek közötti 1-est vagy 0-t tegyük az adott oszlopba. Ezután a print $0 kiírja a maradékot (itt szerintem elég lenne egy sima print is, de nem próbáltam, így jött ki a kezemen, most már így marad). A getline; új sort olvas be, hiszen különben minden sornál kiírnánk ugyanazt az értéket 24x, magyarul nem a kívánt eredményt kapnánk. Ha a dátum és a státuszok megvannak, akkor vége a ciklusnak, ezért kézzel hozzáadunk egy soremelést, tehát mi vezéreljük azt, hogy mi számítson egy rekordnak.
A végeredmény egy szöveges fájl, ami Excelbe beolvasható szóközzel elválasztott fájlként, és olyan színes kimutatást gyárthatunk belőle, hogy a vezetőink csak pislognak.
2012-12-13 17:46:02 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
2012-12-13 17:47:03 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
...
Ha valakit érdekel a megoldás: mint kiderült, az SNMP lekérdezés tényleg csak ennyire megbízható. A riasztások elkerülésére a monitoring alkalmazást állították át úgy, hogy 2 vagy több kiesésre jelezzen csak.