2012-09-14

Multicast light: statikus multicast routing Linuxon (2.)

Az előző részben elkészült egyszerű multicast rendszert valahogy le kell tesztelni. Sokan a VLC média playert használják ehhez, ami teljesen rendjén is van, de azért sosem árt, ha van valami igazán igénytelen, CLI-s eszközünk, amivel valódi multicast forgalmat generálhatunk. Pontosan ilyen program az "mcsender", ami az "smcroute" csomaggal együtt érkezik (legalábbis Ubuntu/Debian alatt). Ennek segítségével kipróbálhatóak az előző részben beállított statikus multicast route-ok. A topológiánk most is a következő:



A "bajor" hostról legalább 3-as IP TTL értékkel (hiszen három hálózaton kell átjutnia a multicast üzenetnek ebben a topológiában), 192.168.1.100-as forrás IP-vel, a 225.1.2.3-as csoportnak címezve, 3000-es UDP porton a következő paranccsal küldetünk teszt UDP streamet:

robert@bajor:~$ mcsender -t3 -ieth0 225.1.2.3:3000

Igen ám, de mi fogja ezt fogadni? Az "andoria" hoston szükségünk lesz egy másik multicastos teszteszközre, az "emcast"-ra. Az "emcast" multicast streamet képes fogadni, és a stream tartalmát kiteszi az STDOUT-ra, valahogy így:

robert@andoria:~$ emcast 225.1.2.3:3000
this is the test message from mclab/mcsender
this is the test message from mclab/mcsender
this is the test message from mclab/mcsender
this is the test message from mclab/mcsender
this is the test message from mclab/mcsender
this is the test message from mclab/mcsender
this is the test message from mclab/mcsender
this is the test message from mclab/mcsender
...

Annyi csavar van a dologban, hogy az "emcast" csomagot az Ubuntu 11.04-es verzió után kidobták a hivatalos repókból, így vagy fordítunk magunknak, vagy feltesszük a 11.04-esben lévő deb-et (12.04-en csont nélkül megy). Ha mégsem működne a multicast rendszerünk, ellenőrizzük, hogy fut-e egyáltalán az smcroute démon (pgrep smcroute), nézzük végig minden multicast routeren a multicast route-okat az "ip mroute show" paranccsal, illetve bizonyosodjunk meg arról, hogy a bejövő és kimenő multicast interfészek benne vannak-e a kernel multicast interfész táblázatában (cat /proc/net/ip_mr_vif).

További hibalehetőség lehet az, ha az smcroute démon indításakor még nem él valamelyik, a multicast route-ok által hivatkozott interfész. Tipikusan ilyen lehet a VPN tunnel interfész, ha le-föl kapcsolgatjuk. Ilyenkor hiába él már a tun1 utólag, az smcroute démon indítása után:

root@trill:~# ifconfig tun1
tun1      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:172.31.255.1  P-t-P:172.31.255.2  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Nem lehet hozzáadni a statikus multicast route-ot:

root@trill:~# smcroute -a eth0 192.168.1.100 225.1.2.3 tun1
Daemon error: Warn: invalid output interface

...és a multicast interfészek közt sincs benne a kernel szerint:

root@trill:~# cat /proc/net/ip_mr_vif
Interface      BytesIn  PktsIn  BytesOut PktsOut Flags Local    Remote
 0 eth0              0       0         0       0 00000 0101A8C0 00000000
 1 eth1              0       0         0       0 00000 010A0A0A 00000000

Újra kell az smcroute-ot indítani, és megint megpróbálni a route hozzáadást:

root@trill:~# service smcroute stop
Stopping static multicast router daemon: smcroute.
root@trill:~# service smcroute start
Starting static multicast router daemon: smcroute.

root@trill:~# cat /proc/net/ip_mr_vif
Interface      BytesIn  PktsIn  BytesOut PktsOut Flags Local    Remote
 0 eth0              0       0         0       0 00000 0101A8C0 00000000
 1 eth1              0       0         0       0 00000 010A0A0A 00000000
 2 tun1              0       0         0       0 00000 01FF1FAC 00000000
root@trill:~# smcroute -a eth0 192.168.1.100 225.1.2.3 tun1
root@trill:~# ip mroute show
(192.168.1.100, 225.1.2.3)       Iif: eth0       Oifs: tun1

2012-09-05

Multicast light: statikus multicast routing Linuxon (1.)

Mostanában szinte kizárólag Linuxokkal foglalkozom, és egyre többször találkozom sajátos megoldásokkal. Az egyik ilyen sajátosan linuxos megoldás a minden nélküli multicast, avagy "multicast light" lehetőség, ami valószínűleg eléggé unortodox, viszont cserébe egyszerű mint az ék, kevésbé összetett multicast környezetekben kiválóan alkalmazható.

A korrekt IPv4 multicast rendszerek működéséhez LAN oldalon IGMP-s hostok, IGMP querier a router(ek)en, illetve a switcheken IGMP snooping szükségeltetik, a routerek pedig egymás közt valamilyen multicast routing protokollal (pl. PIM vagy DVMRP) lerendezik, hogy melyik multicast csoportnak címzett forgalmat hová kell továbbítani. Az „smcroute” multicast routing megoldással tulajdonképpen ebből a listából mindent el lehet hagyni, ha elfogadhatóak számunkra az ezekkel járó kompromisszumok.

LAN oldalon a legfájóbb pont IGMP snooping hiánya lehet. Layer 2-ben a multicast forgalom alapesetben, extra konfiguráció nélkül, minden hosthoz eljut (flood), max. azok nem törődnek vele, ha nem tagjai az adott multicast csoportnak. Attól függően, hogy mekkora ez a multicast forgalom, hogy csak egy vékonyka, mondjuk 20Kbit/s-os tőzsdei árfolyam-streamről beszélünk, vagy durva, sok Mbit/s-os video streamről, ez az elárasztásos forgalom lehet szinte észrevehetetlen, megtűrt vagy éppen nagyon is zavaró. Az IGMP snoopinggal felvértezett switchek megértik a multicast hostok és az IGMP querier közötti IGMP üzenetváltásokat, és pontosan tudják, hogy egy adott pillanatban melyik portjuk mely multicast streamekre van feliratkozva, így nem árasztják el a teljes LAN-t, célzottan jutnak el a multicast csomagok a végállomásokra.

WAN oldalon a dinamikus multicast routing hiánya okozhat kényelmetlenséget, az smcroute-ot, és a vele járó statikus multicast útvonalakat ennek megfelelően olyan helyeken érdemes alkalmazni, ahol viszonylag kevés hostra kell eljuttatni a multicast streamünket. Az smcroute teszteléséhez a létező legegyszerűbb, a valódi környezetketől nem túlságosan távoli multicast tesztkörnyezet a következőképp nézne ki linuxos multicast routerekkel:



IP konfiguráció a hostokon (a teszt alatt használt OS egységesen Ubuntu 12.04.1, i386):

root@bajor:~# cat /etc/network/interfaces 
auto lo eth0

iface lo inet loopback

iface eth0 inet static
address 192.168.1.100
netmask 255.255.255.0
gateway 192.168.1.1
---
root@trill:~# cat /etc/network/interfaces 
auto lo eth0 eth1

iface lo inet loopback

iface eth0 inet static
address 192.168.1.1
netmask 255.255.255.0

iface eth1 inet static
address 10.10.10.1
netmask 255.255.255.0
---
root@vulcan:~# cat /etc/network/interfaces 
auto lo eth0 eth1

iface lo inet loopback

iface eth0 inet static
address 192.168.2.1
netmask 255.255.255.0

iface eth1 inet static
address 10.10.10.2
netmask 255.255.255.0
---
root@andoria:~# cat /etc/network/interfaces 
auto lo eth0

iface lo inet loopback

iface eth0 inet static
address 192.168.2.100
netmask 255.255.255.0
gateway 192.168.2.1

A Layer3-as VPN interfészek, azaz WAN VPN kapcsolat esetünkben OpenVPN „tun” tunnelt jelent a „trill” és a „vulcan” hoston, PSK-val. Először generáljuk le a PSK-t:

root@trill:~# cd /etc/openvpn/
root@trill:/etc/openvpn# openvpn --genkey --secret s2stunnel.psk
root@trill:/etc/openvpn# cat s2stunnel.psk
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
06d0ae16e16150f850462271490e1055
e0c516af702ccf95986660889f4f02ee
0abe658cebb12b326e32214a659ba70f
ee79a55158526101ed6c6477d05a03e7
40293591d110af3c45801f537c41d71b
59304d171084e6f174e44aba2c32766b
6a88b617a6ca8e0e371f040858c289ed
b83a5c943030ec4758065ee556a458f3
ce266b42e956a5c867586fde20f4d51a
396ebdade3f55d27fe12aa184b134298
aeaa91fdaf40f2d80bcb001969608c94
9daae5a2bbf03149b93cf076b80532cd
eb68c84c314bfc0eae8ba008c19a00f9
425b80005fb26e7bc2140442794813ec
e2718ce0df00f17473ac23561c4fd088
987f8ffb9864e448fb0f6a18d170bf2c
-----END OpenVPN Static key V1-----

Ezt a fájlt másoljuk át a „vulcan” ugyanezen a könyvtárba, úgy, hogy közben lehetőleg ne publikáljuk az interneten a PSK-t, majd folytathatjuk a „trill” konfigurációját a tunnel beállításával:

root@trill:/etc/openvpn# cat s2stunnel.conf 
daemon
verb            3
#ubuntu openvpn init script handles this:
#writepid       /var/run/openvpn-s2stunnel.pid
#ubuntu openvpn init script handles this:
#status         /var/run/openvpn-s2stunnel.status 30
log             /var/log/openvpn-s2stunnel.log
log-append      /var/log/openvpn-s2stunnel.log
dev-type        tun
dev             tun1
ping            10
ping-restart    60
ifconfig        172.31.255.1 172.31.255.2
local           10.10.10.1
lport           1194
remote          10.10.10.2
rport           1194
route           192.168.2.0 255.255.255.0
cipher          bf-cbc
keysize         128
auth            sha1
secret          /etc/openvpn/s2stunnel.psk

A „vulcan”-on egy nagyon hasonló konfigurációs fájlt kell összeállítanunk, figyelve arra, hogy a helyi és a távoli IP-k, subnetek értelemszerűen változzanak. Ha készen vagyunk, indítsuk újra mindkét VPN gateway-en az OpenVPN szolgáltatást a „service openvpn restart” paranccsal. Ne feledjük az IP forwarding engedélyezését a procfs-en keresztül; amennyiben mindent jól csináltunk, kapunk egy új, „tun1” nevű, multicastra képes virtuális interfészt mindkét gépen, és a két „tun1” IP tudja pingelni egymást:

root@trill:/# ifconfig tun1
tun1      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet addr:172.31.255.1  P-t-P:172.31.255.2  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:7 errors:0 dropped:0 overruns:0 frame:0
          TX packets:7 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100 
          RX bytes:588 (588.0 B)  TX bytes:588 (588.0 B)

Ezzel eljutottunk a tulajdonképpeni témához, a multicast routeolás beállításához. Linux alatt ehhez a funkcióhoz egy multicast routing démont kell telepíteni, amennyire tudom, összesen három ilyen szoftver létezik Linuxra, az „mrouted” (DVMRP), a „pimd” (PIM) és az „smcroute”. Egyszerre csak egy multicast routing démon futhat, teljesen felesleges mindegyiket felpakolni. Az „smcroute” sajátossága, hogy egyáltalán nem dinamikus, nem valósít meg semmilyen multicast routing protokollt, így a démon elindulása után nekünk magunknak kell kézzel felvennünk a multicast útvonalakat.

Ubuntuban az smcroute az „apt-get install smcroute” paranccsal telepíthető. Sajnálatos hiányosságnak érzem az aktuális LTS-ben, hogy az alapértelmezett repóból feltett csomag SEGFAULT-tal elszáll, amint egynél több multicast képes interfészt talál a rendszeren -- ez némiképp megnehezíti a rendeltetésszerű használatát. Remélhetőleg a problémát hamarosan javítani fogják, a teszt alatt egyszerűen lecseréltem az "/usr/sbin/smcroute" binárist egy saját fordítású, friss, 1.99-es verziójú binárisra, de minden mást meghagytam a repóból feltett csomagból.

Amennyiben fut a multicast démon (service smcroute start), azonnal életre kelnek a procfs-en a multicastos virtuális fájlok, a /proc/net/ip_mr_vif például tartalmazza a multicastra fogható interfészek jellemzőit:

root@trill:/# cat /proc/net/ip_mr_vif 
Interface  BytesIn  PktsIn  BytesOut PktsOut Flags Local    Remote
 0 eth0          0       0         0       0 00000 0101A8C0 00000000
 1 eth1          0       0         0       0 00000 010A0A0A 00000000
 2 tun1          0       0         0       0 00000 01FF1FAC 00000000

Mindössze annyi dolgunk marad még, hogy felvegyük a megfelelő helyre mutató multicast route-okat a „trill”-en és persze a „vulcan”-on, a következő paranccsal: „smcroute -a <in-ifname> <source-ip> <multicast-group>  <out-ifname> [<out-ifname> ...]”.

root@trill:/# smcroute -a eth0 192.168.1.100 225.1.2.3 tun1
---
root@vulcan:/# smcroute -a tun1 192.168.1.100 225.1.2.3 eth0 

A -r kapocsolóval törölhetők a korábban felvett multicast útvonalak, az éppen érvényben lévő listát pedig az ip mroute show paranccsal kérdezhetjük le. Ezzel a két statikus bejegyzéssel biztosítottuk, hogy a 192.168.1.100-as forrásról a 225.1.2.3-as csoportnak küldött adatok átjussanak a WAN-on. A következő részben a parancssorból teszteljük a megoldást.

2012-08-31

RIverbed offtopic érdekességek

Egy kis érdekesség egy Riverbed Steelhead 550-es WAN optimizer CLI-jéből. A legmenőbb networkös cégeknél mindig vannak magyarok:

amnesiac > show ver
Product name:      rbt_sh
Product release:   7.0.1
Build ID:          #202_11
Build date:        2012-02-09 17:16:08
Build arch:        i386
Built by:          root@miskolc

Uptime:            2m 29s

Product model:     550
System memory:     1549 MB used / 475 MB free / 2024 MB total
Number of CPUs:    2
CPU load averages: 1.85 / 0.76 / 0.28
amnesiac >

Ha már Riverbed, akkor még egy dolog, amiről érdemes tudni: kb. két éve megvették kilóra a Wireshark mögött álló céget, persze maga a kód GPL-es, de a tudás, a kulcsemberek, mind-mind Riverbed alkalmazottak. A legszebb az egészben, hogy itt nem történtek olyan baklövések, mint amelyek például az OpenOffice és az Oracle esetében a LibreOffice forkhoz vezettek -- szintén ugye két éve. Nem tépték szét a fejlesztői közösséget, nem akarták kisajátítani a Wiresharknak a protokoll analizátorok közötti páratlan népszerűségét, építettek rá egy üzleti modellt, tök jó termékek kaphatók, egy Cascade Shark appliance-t például egyszer szívesen meghajtanék.

Szóval riszpekt, köszi, hogy nem kúrtátok el, és persze üdv a magyar kollégá(k)nak.

Mekkora egy switch késleltetése?

A napokban egy összetett alkalmazáskésleltetés-mérési projekt kapcsán felmerült a kérdés, hogy hol legyen az első mérési pont a rendszerben. Maga a rendszer egy több hostos elosztott alkalmazás, amiben mindenfelé létre lettek hozva mérési pontok. Nyilvánvaló, hogy az első mérési pont ott kell, hogy legyen, ahol bejutnak az adatok a rendszerbe, ezt történetesen egy Linux. A teljes elosztott alkalmazás késleltetési ideje sok milliszekundumos nagyságrendben mozog, nekem meg sem fordult a fejemben, hogy az említett első mérési pontot nem ezen a gateway Linux rendszeren kellene létrehozni, de egy kolléga felvetette, hogy van ám az előtt a Linux előtt egy switch is, és hogy gyakorlatilag az az első eszköz a teljes rendszerben, azon kellene egy monitor portot konfigurálni, hogy valóban a legkorábbi ponton kapjuk el a bejövő adatokat.

Ekkor kibújt belőlem a networkös, hiszen a switching, akár a gyorsabb cut-through de még a lassabb store-and-forward esetében is a milliszekundumos nagyságrend alatt, mikroszekundumos berkekben mozog. Arról nem is szólva, hogy az elosztott rendszer hostjai közötti NTP szinkronizációnak is vannak korlátai, sosem törtem ilyenen a fejem, de állítólag LAN-on az NTP szinkronizáció precizitása jó, ha megüti a 20 mikroszekundumos tartományt. Ergo felesleges vesződni a monitor porttal, ha nem is tudjuk olyan precízen jegyzetelni az adatokat, amennyit az egyetlen switcheléssel korábbi sniffing jelentene.

Ennek apropóján utánanéztem, hogy tulajdonképpen mennyi az annyi: mekkora manapság a switchek késleltetése? Átpörgettem pár adatlapot különböző gyártóktól, és arra jutottam, hogy az enterprise termékek esetében a mezei 100Mb/s-es eszközöktől a 10Gb/s-es Ethernet eszközökig nagyjából néhány tíz mikroszekundumos késleltetéssel lehet számolni. Persze nehéz ezeket az adatokat összehasonlítani, hiszen nem ugyanazokkal a módszerekkel dolgoznak a különböző műhelyek a mérések során, van ahol a beérkező keret első bitjétől megy a stopper a kimenő keret első bitjéig, máshol (store-and-forward méréseknél) a beérkező keret utolsó bitjétől a kimenő első bitjéig. Gyakran nincs feltüntetve, hogy mekkora Ethernet keretméret mellett végezték a mérést, máshol egész adatsorok vannak egészen jumbo frame méretig. De úgy körülbelül a néhány tíz mikroszekundum jó közelítést ad, és ez nagyjából a kilencvenes évek közepe, az ASIC áramkörök switchekben való megjelenése óta így van. Az alapok a cisco.com-on elolvashatók a "Cut-Through and Store-and-Forward Ethernet Switching for Low-Latency Environments" doksiban.

Persze vannak extrém igényeket kielégítő termékek is. Úgy tűnik, hogy mostanában a low latency switching piacot leginkább a tőzsdei rendszerek, illetve azoknak is egy speciális szegmense, a High-Frequency Trading rendszerek fűtik. Az egyik, erre a piacra szakosodott gyártó, az Arista például 600 nanoszekundumos késleltetésű cut-through switchekkel hergeli a vevőit már a tervezési dokumentumaiban is, így rackek között is már 2,4 mikroszekundomot képesek elérni.

No, ettől messze vannak azok az eszközök, amikhez én hozzáférek, de épp volt kéznél egy 3Com 5500-EI, gondoltam kipróbálom, hogy mekkora a késleltetése, nem éppen mai darab, de legalább enterprise cucc. Az adatlap pusztán annyit közöl, hogy "Store-and-forward switching; latency <10 μs". Lássuk. Elővettem a Systimax patchkábeleket, két egyforma laptopot, egyforma OS-szel (Ubuntu 12.04.1), és céleszköz híján ment a ping, először 1000 bájtos mérettel:


50 packets transmitted, 50 received, 0% packet loss, time 48998ms
rtt min/avg/max/mdev = 0.462/0.495/0.528/0.036 ms

Hm... 495μs átlagos RTT-re, annak a fele 247,5μs, igaz ebben benne van az is, hogy a switchtől független két OS-en át kell verekednie magát, valószínűleg maga a kapcsolás sokkal rövidebb ideig tart, mint amennyi idő alatt a két végen lévő TCP/IP stacken átjut az ICMP, de valahogy akkor is kevesebbre számítottam. Aztán kipróbáltam 32 bájtos mérettel is:


50 packets transmitted, 50 received, 0% packet loss, time 48998ms
rtt min/avg/max/mdev = 0.167/0.184/0.218/0.021 ms

Így már csak 184μs az átlagos RTT, azaz egy átlagos odaút már csak 92μs, úgy, hogy ebben a két Linux TCP/IP stackje is benne van, nem csak a kapcsolás. Ez valóban sokkal közelebb van az adatlap alapján megcélzott <10μs-hez, gyakorlatilag én ezt a a <10μs adatot már simán el is hiszem.

2012-08-23

Interaktív SSH wrapper parancssorból

Egy volt kollégám többször bizonygatta, hogy SecureCRT nélkül ebben a szakmában manapság már nem lehet meglenni, hogy enélkül nem veszik komolyan az embert. Valóban, az említett program legalább akkora változást hozott a remote shell hozzáférések egyszerű kezelésében Windows alatt, mint annak idején a PuTTY. A két programot igazából nem is érdemes hasonlítgatni, annyival okosabb, szebb, modernebb a SecureCRT, hogy a PuTTY csak egyetlen területen veheti fel a versenyt vele: az árában, merthogy ez utóbbi ingyenes. Minden másban, pl. hostok csoportosítása, jelszavak megjegyzése, alapból megnyíló sessionök stb. a SecureCRT viszi a prímet.

Arról azonban sosem sikerült meggyőznöm a kollégát, hogy Linuxon azért van élet a SecureCRT-n kívül is. Persze olyan szintű dolog nincs, mint amilyen a SecureCRT, illetve azt úgy hívják, hogy SecureCRT for Linux, de azért csak fel lehet a bash-t okosítani, hogy menjen az a Tab-os kiegészítés gyakran használt hostnevekre vagy ilyesmi. Nyilván az ember elsősorban már csak SSH-t használ, meg általában parancssort, még ha Linux desktop is fut a gépen, legtöbbször a terminálablak takar ki minden mást. A GNOME 2-es környezetben volt egy klassz kis app, az "SSH Menu", az egész élhető volt, közvetlenül a panelből lehetett kiválasztani a hostokat, de a mostani új desktopokból (GNOME 3, Unity) fájóan hiányzik egy igazán ütős alkalmazás erre. A Remmina lehet, hogy egyszer jó lesz, egyáltalán nem ördögtől való ötlet egyetlen kliensben integrálni az összes hasonló célú funkciót (SSH, VNC, RDP...), de jelen állapotában a Remmina CLI-s felületek használatához meglehetősen kényelmetlen. Szóval mostanában egyre inkább kezd igaza lenni a volt kollégának.

Egészen eddig a percig. Közzéteszem ugyanis a pótolhatatlan, teljesen CLI-s, interaktív SSH indító felületet, amit csak feldobunk egy jump szerverre, és okostelefonról, Windowsról, Linuxról egyaránt használhatjuk, itt van kérem a csodálatos, hasznos, mc-kék SSH menü szkript:


Még akár felhasználónevet is választhatunk (az alapértelmezett a $USER) egy előre megadott listából, vagy beírhatunk tetszés szerinti nevet:


Khm... nos, itt nagyjából véget is ér a szkript tudása, én jelenleg egy kb. 80 hosztos listával használom, és már annyira a szívemhez nőtt, hogy el sem tudnám képzelni a napi munkát nélküle. Különösebb függősége nincs, szükség van a "dialog" csomagra, "ncurses"-re. Kód:

#!/bin/sh

if ! $(which dialog); then
   echo "Can't find \"dialog\" binary on PATH."
   exit 1
fi

SSHHOST=$(dialog --stdout --title " SSH Menu " --menu "       IP............Hostname...............Function/Description" 22 74 100 \
192.168.0.1      "domain-name-host1      Comment for host1" \
192.168.0.2      "domain-name-host2      Comment for host2" \
192.168.0.3      "domain-name-host3      Comment for host3" \
192.168.0.4      "domain-name-host4      Comment for host4" \
192.168.0.5      "domain-name-host5      Comment for host5" \
192.168.0.6      "domain-name-host6      Comment for host6" \
192.168.0.7      "domain-name-host7      Comment for host7" \
192.168.0.8      "domain-name-host8      Comment for host8" \
192.168.0.9      "domain-name-host9      Comment for host9" \
192.168.0.10     "domain-name-host10     Comment for host10" \
192.168.0.11     "domain-name-host11     Comment for host11" \
192.168.0.12     "domain-name-host12     Comment for host12" \
192.168.0.13     "domain-name-host13     Comment for host13" \
192.168.0.14     "domain-name-host14     Comment for host14" \
192.168.0.15     "domain-name-host15     Comment for host15" \
192.168.0.16     "domain-name-host16     Comment for host16" \
)

if test -z $SSHHOST; then
   exit 1
fi

REMOTEUSR=$(dialog --stdout --title " Select remote user name " --menu "If you would like to type in a username select \"Cancel\"" 15 40 10 \
$USER "" \
root "" \
admin "" \
cisco "" \
vyatta "" \
)

if test -z $REMOTEUSR; then
   REMOTEUSR=$(dialog --stdout --title " Enter remote user name " --inputbox "" 7 40 )
fi

if test -z $REMOTEUSR; then
   exit 1
fi

clear
exec ssh -l $REMOTEUSR $SSHHOST

2012-03-21

Egymásba ágyazott ismétlődések kezelése TShark field print opciókkal

Tegyük fel, hogy szkriptet kell írnunk, ami valamiféle statisztikát készít mondjuk IPIP vagy GRE tunnelezett forgalomról. Mintának egyből használhatjuk a packetlife.net-ről a GRE.cap-ot. A tunnel ebben az esetben a 10.0.0.1 és a 10.0.0.2 közt van kihúzva, a tunnelen belül pedig az 1.1.1.1 és a 2.2.2.2 kommunikál egymással:


Ha mindezt CLI-ben szeretnénk feldolgozni, akkor persze TSharkra lesz szükség, és egy kicsit állítgatni kell az alapértelmezett outputon. Egyszerűsítsük le a végletekig a dolgot, csak a forrás, illetve a cél IP-ket jelenítsük meg:
karsair@betazed:~$ tshark -r GRE.cap -T fields -e ip.src -e ip.dst -E separator=\;
1.1.1.1;2.2.2.2
2.2.2.2;1.1.1.1
1.1.1.1;2.2.2.2
2.2.2.2;1.1.1.1
1.1.1.1;2.2.2.2
2.2.2.2;1.1.1.1
1.1.1.1;2.2.2.2
2.2.2.2;1.1.1.1
1.1.1.1;2.2.2.2
2.2.2.2;1.1.1.1
Nos, ez nem egészen az, amire szükség van, hiszen itt csak a GRE payload IP-k látszanak, azaz az ip.src és az ip.dst mezők utolsó előfordulásai minden egyes keretben. Ettől többet sajnos nem is várhatunk egészen a Wireshark 1.6-os verziójáig. Az új stabil Wireshark ágban azonban már gondoltak a rekurzivitás barátaira, új opciók vannak ugyanis a hasonló esetek kezelésére. Egyrészt megváltozott az alapértelmezett viselkedés a TShark-ban, -e után megadott mező összes előfordulását kilistázza a program vesszővel elválasztva:
karsair@betazed:~$ /opt/wireshark-1.6.5/bin/tshark -r GRE.cap -T fields -e ip.src \
-e ip.dst -E separator=\;
10.0.0.1,1.1.1.1;10.0.0.2,2.2.2.2
10.0.0.2,2.2.2.2;10.0.0.1,1.1.1.1
10.0.0.1,1.1.1.1;10.0.0.2,2.2.2.2
10.0.0.2,2.2.2.2;10.0.0.1,1.1.1.1
10.0.0.1,1.1.1.1;10.0.0.2,2.2.2.2
10.0.0.2,2.2.2.2;10.0.0.1,1.1.1.1
10.0.0.1,1.1.1.1;10.0.0.2,2.2.2.2
10.0.0.2,2.2.2.2;10.0.0.1,1.1.1.1
10.0.0.1,1.1.1.1;10.0.0.2,2.2.2.2
10.0.0.2,2.2.2.2;10.0.0.1,1.1.1.1
Másrészt vadonatúj field print opcióként itt az "occurrence". Az eddigi field print opciókkal be lehetett állítani, hogy legyen-e az outputban fejléc (-E header=y), a fenti példákban már bemutatott separator opcióval megadhattunk mezőelválasztó karaktert (-E separator=\;), illetve kérhettünk idézőjeleket a mező tartalma köré (pl. -E quote=d). Most viszont azt is megadhatjuk az occurrence opcióval, hogy az adott nevű mező első (f), utolsó (l) vagy összes (a) előfordulását szeretnénk látni, így akár imitálhatjuk az 1.6-os verziók előtti viselkedést (-E occurrence=l):
karsair@betazed:~$ /opt/wireshark-1.6.5/bin/tshark -r GRE.cap -T fields -e ip.src \
-e ip.dst -E separator=\; -E header=y -E quote=d -E occurrence=l
ip.src;ip.dst
"1.1.1.1";"2.2.2.2"
"2.2.2.2";"1.1.1.1"
"1.1.1.1";"2.2.2.2"
"2.2.2.2";"1.1.1.1"
"1.1.1.1";"2.2.2.2"
"2.2.2.2";"1.1.1.1"
"1.1.1.1";"2.2.2.2"
"2.2.2.2";"1.1.1.1"
"1.1.1.1";"2.2.2.2"
"2.2.2.2";"1.1.1.1"
Ami még ide tartozik, mégis kimaradt az eddigi példákból, az az aggregator field print opció, ami az -e után megadott nevű mező(k)nek az adott keretben való előfordulásait elválasztó karaktert definiálja, az alábbi példában ez a kettőspont:
karsair@betazed:~$ /opt/wireshark-1.6.5/bin/tshark -r GRE.cap -T fields -e ip.src \
-e ip.dst -E separator=\; -E quote=d -E occurrence=a -E aggregator=:
"10.0.0.1:1.1.1.1";"10.0.0.2:2.2.2.2"
"10.0.0.2:2.2.2.2";"10.0.0.1:1.1.1.1"
"10.0.0.1:1.1.1.1";"10.0.0.2:2.2.2.2"
"10.0.0.2:2.2.2.2";"10.0.0.1:1.1.1.1"
"10.0.0.1:1.1.1.1";"10.0.0.2:2.2.2.2"
"10.0.0.2:2.2.2.2";"10.0.0.1:1.1.1.1"
"10.0.0.1:1.1.1.1";"10.0.0.2:2.2.2.2"
"10.0.0.2:2.2.2.2";"10.0.0.1:1.1.1.1"
"10.0.0.1:1.1.1.1";"10.0.0.2:2.2.2.2"
"10.0.0.2:2.2.2.2";"10.0.0.1:1.1.1.1"
Eljutottunk tehát odáig, hogy a TShark egy jól konfigurálható kimentet ad a poszt elején vázolt szkript számára, az IP-ket pakolgathatjuk tömbökbe, ide-oda, számolgathatjuk, hogy melyik hányszor fordult elő ilyen külső IP, amolyan belső IP mellett, de az már egy másik történet.

2012-03-14

NAT connection tracking naplózás Linuxon

Gyakran felmerülő probléma, hogy miképp lehet azonosítani linuxos SRC NAT mögötti gépeket megbízhatóan. Az ugye viszonylag egyértelmű, hogy címfordítást végző rendszeren valamit kezdenünk kell a kernel által vezetett conntrack táblával, amihez van egy sztenderd interfész minden Linuxon: a /proc/net/ip_conntrack-ből mindig ki lehet olvasni az éppen aktuális bejegyzéseket. Ez azonban igencsak behatárolt lehetőség. Tegyük fel, hogy percenként mentjük a táblázatot! Még így is igen könnyen lehetnek olyan NAT-olt kapcsolatok, amelyek az előző lekérdezés óta épültek ki, de azóta már kikerültek a conntrack táblázatból, ezért a percenkénti logjainkban semmilyen nyomuk nem marad, arról nem is beszélve, hogy rengeteg felesleges információt is eltárolunk, mert a conntrack bejegyzések jelentős része - a megnyitott, kiépített TCP sessionök - tipikusan több percen át élnek, és ezeket mindig újra és újra tárolgatjuk a percenkénti logokban.

Jobb lenne az eseményalapú megközelítés, csak akkor naplózni a conntrack bejegyzéseket, ha új kapcsolat épül ki, vagy ha az adott conntrack bejegyzés kikerül a conntrack táblázatból. Szerencsére ilyesmi létezik Linuxra, a szoftvercsomag neve conntrack-tools, a benne lévő eszközök pedig kiváló, dinamikus, userspace interfészt biztosítanak a kernel conntrack táblájához. A csomag két fontos eleme a conntrack és a conntrackd nevű program. Az előbbivel listázni, naplózni, létrehozni, módosítani, törölni lehet conntrack bejegyzéseket, az utóbbi (a démon) pedig redundáns NAT rendszerek közt képes a conntrack információk szinkronizálására. A conntrack naplózás tesztjéhez az alábbi topológiát használtam:



A "denobula" beállításait nem vittem túlzásba, egy teljesen alap Ubuntu 10.04 LTS telepítést kell elképzelni, ahol két paranccsal beállítható a 10.1.1.0/24 subnetből érkező csomagok forráscímeinek NAT-olása az eth0-ra aggatott külső IP-re, feltételezve, hogy az alapértelmezett ACCEPT iptables policy-ket senki és semmi nem állította át:
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o eth0 -s 10.1.1.0/24 -j MASQUERADE
Az interfészeket kell még beállítani, az /etc/network/interfaces fájlba kerüljenek a következők:
auto lo eth0 eth1

iface lo inet loopback

iface eth0 inet static
address 10.0.2.15
netmask 255.255.255.0
gateway 10.0.2.2

iface eth1 inet static
address 10.1.1.1
netmask 255.255.255.0
Majd állítsuk be a DNS-t, végül húzzuk fel az interfészeket (újraindítás után ez már az init alatt megtörténik az előbbi auto bejegyzés miatt):
echo "nameserver 8.8.8.8" > /etc/resolv.conf
ifup eth0
ifup eth1
Következik a lényeg, a conntrack-tools telepítése (valójában csak a conntrack csomag szükséges ahhoz, amiről ebben a posztban szó lesz):
apt-get update
apt-get install conntrack conntrackd
A "denobula" beállítása ezzel meg is van, a tesztkörnyezetből még hiányzik a NAT mögötti kliens, az "andoria", ez bármi lehet, Live CD-s Linux, akármi, a lényeg, hogy konfiguráljunk rajta egy 10.1.1.2/24-es IP-t, majd a 10.1.1.1-et gatewaynek, valamint egy DNS szervert (pl. 8.8.8.8). Ezek után nincs más hátra, mint beröffenteni a NAT-os gépen a connttrack programot, a sok opció közül most a -E lesz az, amire szükségünk lesz, további opcióként megadtam a -o id,timestamp-et, így az egyes bejegyzések pontos időbélyege és az adott NAT-olt kacsolat belső ID-je is látszani fog a kimenetben:
root@denobula:~# conntrack -E -o id,timestamp,extended
[1331710267.511683]        [NEW] ipv4     2 tcp      6 120 SYN_SENT src=10.1.1.2 dst=74.125.232.247 sport=39059 dport=80 [UNREPLIED] src=74.125.232.247 dst=10.0.2.15 sport=80 dport=39059 id=3607679456
[1331710267.513939]        [NEW] ipv4     2 tcp      6 120 SYN_SENT src=10.1.1.2 dst=74.125.232.247 sport=39060 dport=80 [UNREPLIED] src=74.125.232.247 dst=10.0.2.15 sport=80 dport=39060 id=3607679216
[1331710267.513992]     [UPDATE] ipv4     2 tcp      6 60 SYN_RECV src=10.1.1.2 dst=74.125.232.247 sport=39059 dport=80 src=74.125.232.247 dst=10.0.2.15 sport=80 dport=39059 id=3607679456
[1331710267.514021]     [UPDATE] ipv4     2 tcp      6 60 SYN_RECV src=10.1.1.2 dst=74.125.232.247 sport=39060 dport=80 src=74.125.232.247 dst=10.0.2.15 sport=80 dport=39060 id=3607679216
[1331710267.514047]     [UPDATE] ipv4     2 tcp      6 432000 ESTABLISHED src=10.1.1.2 dst=74.125.232.247 sport=39059 dport=80 src=74.125.232.247 dst=10.0.2.15 sport=80 dport=39059 [ASSURED] id=3607679456
[1331710267.514076]     [UPDATE] ipv4     2 tcp      6 432000 ESTABLISHED src=10.1.1.2 dst=74.125.232.247 sport=39060 dport=80 src=74.125.232.247 dst=10.0.2.15 sport=80 dport=39060 [ASSURED] id=3607679216
[1331710272.506759]     [UPDATE] ipv4     2 tcp      6 120 FIN_WAIT src=10.1.1.2 dst=74.125.232.247 sport=39060 dport=80 src=74.125.232.247 dst=10.0.2.15 sport=80 dport=39060 [ASSURED] id=3607679216
[1331710272.507065]     [UPDATE] ipv4     2 tcp      6 60 CLOSE_WAIT src=10.1.1.2 dst=74.125.232.247 sport=39060 dport=80 src=74.125.232.247 dst=10.0.2.15 sport=80 dport=39060 [ASSURED] id=3607679216
[1331710272.507135]     [UPDATE] ipv4     2 tcp      6 30 LAST_ACK src=10.1.1.2 dst=74.125.232.247 sport=39060 dport=80 src=74.125.232.247 dst=10.0.2.15 sport=80 dport=39060 [ASSURED] id=3607679216
[1331710272.507208]     [UPDATE] ipv4     2 tcp      6 120 TIME_WAIT src=10.1.1.2 dst=74.125.232.247 sport=39060 dport=80 src=74.125.232.247 dst=10.0.2.15 sport=80 dport=39060 [ASSURED] id=3607679216
A kimenetben megtalálhatók a kért paraméterek, az első mező a timestamp, az utolsó mező a conntrack ID, a sorok egyébként elég beszédesek, minden sorban a második mező a conntrack esemény, amiből összesen három létezik, a NEW értelemszerűen egy új conntrack bejegyzés létrejöttekor generálódik, az UPDATE egy már létező bejegyzésben valamiféle változást jelez, például az UPDATE bejegyzésekben a TCP állapotátmenet-változások kiválóan követhetők. A harmadik, DESTROY nevű esemény pedig azt jelzi (a fenti példában épp nincs ilyen), hogy egy bejegyzés kikerül a conntrack táblából.

Ez a fajta eseményvezérelt kimenet már egészen közel van ahhoz, hogy használható legyen, két apróságra térnék még ki. Az első, hogy az STDOUT-ra küldött log nem tekinthető valódi log-nak, valahova át kell irányítanunk, a következő példában a tee-t használom, amivel így, ahogy van, ott lehet hagyni egy ötös vagy hatos szöveges terminálon, úgysem nyúl hozzá soha senki ;). A másik dolog, hogy általában az UPDATE eseményekre nincs szükség, hiszen az ilyesfajta logoknak az a lényege, hogy ki lehessen hámozni belőlük, hogy egy SRC NAT mögötti gép mettől meddig, milyen külső IP-vel, hová kommunikált, ehhez pedig elég a bejegyzés létrejöttét (NEW) és a bejegyzés végét (DESTROY) naplózni, ami közben történt a bejegyzéssel, nem érdekes. A "végső" NAT naplózó parancs tehát, amit természetesen ezer módon tovább lehet még fejlesztgetni, így néz ki:
conntrack -E -o id,timestamp,extended -e NEW,DESTROY | tee /var/log/ctrack.log

2012-02-29

Alapvető biztonsági beállítások MikroTiken

Néhány poszttal ezelőtt volt szó a Mikrotik eszközök ISR routerként történő használatáról, akkor egy-két teljesen szokványos lehetőséget (SNAT, DNAT, DHCP kliens WAN oldalon, DHCP szerver LAN oldalon, NTP kliens, WPA2 PSK wifi) vettünk elő CLI-ben, viszont tárva-nyitva hagytuk a rendszert, így valószínűleg nem élne túl a konfigurációnk pár napnál hosszabb időt érintetlenül publikus interneten. A biztonságosabb működés érdekében a legelső lépés az alapértelmezett admin jelszó megváltoztatása:
[admin@Tik] > /password
old password: password
new password: *************
retype new password: *************
Ez már önmagában sokat jelent, itt azonban semmiképp se pihenjünk még le, következhet a nem használt szolgáltatások kikapcsolása. Amire ténylegesen is szükség lehet, az az SSH, a többit bátran le lehet tiltani:
/ip service
set telnet disabled=yes
set ftp disabled=yes
set www disabled=yes
set www-ssl disabled=yes
set api disabled=yes
set winbox disabled=yes
Akár le is ellenőrizhetjük, hogy mindent sikerült-e kikapcsolni:
[admin@Tik] > /ip service print Flags: X - disabled, I - invalid 
#   NAME        PORT ADDRESS            CERTIFICATE                                     
0 X telnet                23
1 X ftp                   21
2 X www                   80
3   ssh                   22
4 X www-ssl              443                   none
5 X api                 8728
6 X winbox              8291
A RouterOS-en alapértelmezésben figyel UDP-n a bandwidth-server. Ez az IPerf-hez hasonló eszköz, amivel sávszélesség teszteket végezhetünk, érdemes ezt is addig pihentetni, amíg nincs rá ténylegesen szükség. A bandwidth-server szolgáltatás beállítása nem az IP service-ek közt található:
/tool bandwidth-server
set enabled=no
Végül tanácsos legalább a WAN és a WLAN interfészen letiltani a MikroTik Neighbor Discovery protocolt (MNDP) és a CDP-t, hogy ne szivárogtassunk feleslegesen információkat a rendszerről:
/ip neighbor discovery
set wlan1 disabled=yes
set ether1 disabled=yes
Ezzel az alapvető biztonsági beállításokon túl is vagyunk, a környezettől függően természetesen sok egyéb lehetőségünk van még a RouterOS alatt: tűzfalszabályok beállítása, központi RADIUS authentikáció, SNMPv3, BGP MD5 authentikáció, stb. ebben a posztban csupán a legáltalánosabb lehetőségeket vettük sorra.

2012-02-26

VLAN-ok kezelése MikroTiken

Vannak bizonyos megoldások a MikroTik RouterOS-en, amelyek, hát... legalábbis furcsának tűnnek egyéb network OS-ekhez képest, az egyik ilyen a VLAN-ok kezelése. Nem létezik olyasmi RouterOS alatt, hogy access port vagy trunk port, az van, amit összedrótozgatunk. Az alábbi parancsok például VLAN 1-3-ig, tagged VLAN kezelést biztosítanak az ether1 interfészen:
/interface vlan
add name="VLAN1" vlan-id=1 interface=ether1 disabled=no
add name="VLAN2" vlan-id=2 interface=ether1 disabled=no
add name="VLAN3" vlan-id=3 interface=ether1 disabled=no
Persze ezzel önmagában sokra nem megyünk, hiszen valahová tovább is kell kapcsolni ezeket a VLAN-okat, mondjuk access portokra. A következő döbbenet akkor éri a kezdő mikrotikest (például engem is), amikor kiderül, hogy amit mindenhol máshol access portnak hívnak, az itt tulajdonképpen nincs, de amit tehetünk, hogy mégis legyen, az sem az, hogy VLAN-okba tesszük a portokat, hanem:
/interface bridge
add name="BR1" disabled=no
add name="BR2" disabled=no
add name="BR3" disabled=no
/interface bridge port
add bridge=BR1 interface=ether2 disabled=no
add bridge=BR1 interface=ether3 disabled=no
add bridge=BR2 interface=ether4 disabled=no
add bridge=BR2 interface=ether5 disabled=no
add bridge=BR3 interface=ether6 disabled=no
add bridge=BR3 interface=ether7 disabled=no
Amint az a példából látható, a BR1 nevű bridge-hez az ether2-3, illetve a wlan1 port tartozik, a BR2-höz a ether4-5, a BR3-hoz pedig az ether6-7. Az itt definiált portcsoportok különálló VLAN-okként viselkednek, de természetesen az égvilágon semmi közük nincs az ether1 interfészen létrehozott trönkhöz, és az azon élő három tagged VLAN-hoz (némiképp emlékeztet egyébként mindez az autonóm Cisco AP-ken használatos BVI bridge group interfészekre). Az uplinken bejövő tagged VLAN-ok és a BR1, BR2, BR3 bridge-ek között úgy hozhatunk létre kapcsolatot, hogy a VLAN neveinkhez tartozó virtuális interfészeket szintén bepakoljuk a bridge-ekbe:
/interface bridge port
add bridge=BR1 interface=VLAN1  disabled=no
add bridge=BR2 interface=VLAN2  disabled=no
add bridge=BR3 interface=VLAN3  disabled=no
Ezzel eljutottunk oda, hogy az ether1-en bejövő tagged adatok megtalálják az útjukat az adott VLAN-on belül a MikroTik eszközre kapcsolt hostokig. De itt még nincs vége, ez csak az a módszer, ami minden MikroTik-en működik, egyes RouterBOARD-oknál ettől eltérő megoldást is lehet használni, attól függően, hogy milyen switch chip található a NYÁK-on. A RouterOS ugyanis nem fedi el a hardveres lehetőségeket, vannak hardverspecifikus parancsok a VLAN-ok kezelésére. A wiki.mikrotik.com-on található egy táblázat, ebből ki kell keresni, hogy a MikroTik eszközünkben milyen switch chip található, hogy támogatja-e a chip a port tükrözést, mekkora CAM táblát tud kezelni (MikroTik esetén ezt host table-nek hívják), vagy éppen azt, hogy hány VLAN-nal képes megbirkózni, és utána készíthetünk az adott switch chipre szabott VLAN konfigurációt, ami más RouterBOARD-on működésképtelen lehet. Beteges, nem igaz?

2012-02-03

Link Layer Discovery protokollok használata (5.) - CDP MikroTiken és Vyattán

Tulajdonképpen egész könnyen meg lehet szokni a MikroTik szoftverplatformját, a RouterOS-t, valójában igazi MikroTik eszköz sem kell ahhoz, hogy kipróbálhassuk, ugyanis van belőle x86-osra fordított változat, így akár virtuális gépre is telepíthető. A legfrissebb, 5.12-es kiadás IPSec-kel, MPLS-sel, NetFlow v9 exporttal, SNMP v3-mal és még számtalan lehetőséggel együtt sem több ~20MB-nál, ami bizony igen kevés, bármilyen mércével mérve, így aztán ideális választásnak tűnik nagyobb virtuális infrastruktúrák hálózati igényeinek kielégítésére.

De nem is erről szólna ez a poszt, hanem a MikroTik és a Vyatta CDP-kompatibilitásáról. A jó hír az, hogy mindkettőn működik, valódi Cisco eszközökkel tesztelve is, szerintem a Mikrotik megoldása a jobb, ugyanis a RouterOS alatt nagyon egyértelműen lehet kezelni a CDP-be bevont interfészeket, míg a Vyattán csak globálisan lehet ki- és bekapcsolni a CDP támogatást, bár állítólag dolgoznak az interfészenkénti ki- és bekapcsoláson. Ugyanakkor a Vyatta ismeri a CDP v2-t is, míg a RouterOS kizárólag CDP v1-et tud. A parancsok részletes leírogatása helyett ezúttal néhány beszédes képernyőképet készítettem, a képekre kattintva nagyobb felbontású változat is elérhető.

A Cisco eszköz látja mindkét CDP-s versenyzőt, a platform információk, a szoftververzió, a kapcsolódó fizikai portok teljesen korrekt módon jelennek meg az IOS-ben:


A MikroTik-es virtuális gép szintén hibátlanul teszi a dolgát, a gyártónál alapértelmezésben minden interfészen aktív a CDP, kivéve a vezeték-nélküli interfészeket, és mintha tunnel interfészeken sem kapcsolná be alapból a CDP-t a RouterOS; a lényeg, hogy vegyük a CDP-t is számításba (elsősorban biztonsági szempontból), amikor MikroTiket teszünk be a hálózatba. A képernyőképen a szomszédok listázása után példa látható arra is, hogyan kapcsolható ki egy adott interfészen a CDP, illetve arra, hogyan listázható az interfészek aktuális CDP-s állapota.


A CDP alapból nem fut a Vyattán, külön be kell kapcsolni (configure > set service lldp legacy-protocols cdp > commit > save). Az IOS CDP kereteitől a rendszer egy kissé megilletődött, kétszer is betette a neighbor táblázatba a Cisco AP-t, egyszer CDP v1-es, egyszer pedig CDP v2-es eszközként, ezt a kis botlást, valamint a többihez képest rendkívüli szószátyárságot leszámítva azonban nagyjából itt is minden rendben van:


Ugyanebben a témában a korábbi írásaim a Nortel, a 3Com (új HP) majd a HP (ProCurve, régi HP) Layer 2-es discovery protokolljainak alapvető használatát mutatták be, illetve az IOS-es LLDP-t.