2012-10-12

Hogyan nem találtam hibát a TSharkban

Miután két napon keresztül bohóckodtam egy AWK szkripttel, ami TShark által lesniffelt, majd a TShark prokoll dekóderén áthajtott adatokat dolgoz fel, és capture file-ból már hibátlanul működött mind a TShark-os dekódolós rész, mint az AWK szkript, gondoltam ideje kipróbálni valódi környezetben is dolgot. Felkerült egy tesztrendszerre, pár módosítás a capture-t végző szkriptben, hogy valódi sniffelés legyen, ne capture fájlból olvasson, aztán mindenkit odacsődítettem, hogy na, ezt nézzétek, elkészült, és... kopp. Nem megy. Á... igen, rövid hegesztgetés a capture filteren, apróbb állítgatás a protokoll dekóderen, na, majd most... kopp. Még egy kis mókolgatás, és... kopp, kopp, kopp.

Egy jó másfél órás túrás után kiderült, hogy a szkript lelkének számító "tshark ... | magic.awk > /dev/tcp/1.1.1.1/1111" szerkezetű sorban (a /dev/tcp/IP/port Bash specifikus) már a legelején elkerülik a pipe-ot az adatok. Persze én a másik végéről visszafelé haladva ellenőriztem mindent, ez nem is kérdés. A probléma egyébként roppant egyszerű: capture filter használata esetén az STDOUT-ra nem ad semmit a TShark, ami nem valami szép dolog tőle. Az alábbi egyszerű példák megvilágítják, hogy mi is a gond. Tegyük fel, hogy folyamatos ICMP forgalmunk van a 192.168.0.1 és a 192.168.0.2 között.

Capture filter és pipe nélkül minden rendben:

betazed:~# tshark -i eth2
Running as user "root" and group "root". This could be dangerous.
Capturing on eth2
  0.000000 192.168.0.1 -> 192.168.0.2  ICMP Echo (ping) request
  0.000118  192.168.0.2 -> 192.168.0.1 ICMP Echo (ping) reply
  ...

Capture filterrel, de pipe nélkül is OK:

betazed:~# tshark -i eth2 icmp
Running as user "root" and group "root". This could be dangerous.
Capturing on eth2
  0.000000 192.168.0.1 -> 192.168.0.2  ICMP Echo (ping) request
  0.000103  192.168.0.2 -> 192.168.0.1 ICMP Echo (ping) reply
  ...

Capture filter nékül, pipe-pal:

betazed:~# tshark -i eth2 | grep .
Running as user "root" and group "root". This could be dangerous.
Capturing on eth2
  0.541318 192.168.0.1 -> 192.168.0.2  ICMP Echo (ping) request
  0.541418  192.168.0.2 -> 192.168.0.1 ICMP Echo (ping) reply
  ...

Capture filterrel és pipe-pal:

betazed:~# tshark -i eth2 icmp | grep .
Running as user "root" and group "root". This could be dangerous.
Capturing on eth2
^C26 packets captured

Az STDERR-re kikerül a CTRL+C megnyomása után, hogy 26 csomagot fogott a TShark. Szép, szép, de hová tette azt a 26 csomagot? A grep tutira nem nyeli le őket, hiszen ebben a formában mindent átenged, ergo meg sem kapja az STDIN-jén az adatokat. Akkor vajon mi lehet gond? Rövid töprengés után (vö. Gyalog galopp boszorkányégetős jelenet) megvan az itélet: biztosan a TShark vacak, máglyára vele. Nincs is szebb annál, mint amikor a hülyeség szorgalommal párosul, lejelentettem hibára a bugs.wireshark.org-on. Nem tudom, hogy a véletlenül kapott mágikus erejű bug ID (7777) hatására, vagy azért, mert egyébként is jól felépített szervezetet tolt a Riverbed a Wireshark alá, de húsz perc múlva volt megoldás: user error. Khm... nos, igen, körülbelül iyen "Operációs rendszerek" szeminárium első évfolyam, első félév, második alkalom szintű dologról van szó, nem tudtam, hogy az STDOUT pufferelt, és ha nincs elég sok adat a TShark kimeneten, akkor bizony sokáig a pufferben ragadnak a dolgok. Ezért abban az esetben, ha TShark van a pipe elején, "-l" kapcsolóval érdemes elindítani, akkor azonnal ürül a puffer minden egyes csomag feldolgozása után. Innen persze már működött a csoda szkriptem is, az más kérdés, hogy a végső változatban mégsem TShark-kal sniffeltem, hanem ngrep-pel, és a TShark parancssori protokoll dekódere helyett mindent AWK-val oldottam meg, nem is ez a fontos, hanem az, hogy a szakmában töltött évek száma semmilyen kapcsolatban nincs az ember valós vagy inkább vélt tévedhetetlenségével.

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?