2011-09-19

FQDN alapú tűzfalszabályok diagnosztikája FortiOS alatt

A legtöbb komolyabb tűzfalplatform biztosít lehetőséget FQDN alapú tűzfalszabályok létrehozására, nincs ez másként a FortiOS alatt sem. Az FQDN-es szabályok alkalmazása azonban nem feltétlenül jó ötlet, hiszen a forgalom átengedése vagy visszatartása a  tűzfal szempontjából egy másik, független rendszerre, a DNS-re épít, illetve megbízik annak a másik rendszernek az integritásában. Többek közt ezért is érdemes mindig a belső DNS szervereinket beállítani a tűzfalon (bár ettől még önmagában nem lesz biztonságosabb vagy megbízhatóbb a DNS rendszerünk). Mindenesetre ha alkalmazunk ilyen domain neves szabályokat is a tűzfalon, akkor további talányokhoz vezethet, ha az FQDN-es szabály mégsem működik, látszólag mégis minden tökéletesen rendben van.

A Fortigate tűzfalakon a webes felület nem ad sok lehetőséget arra, hogy leellenőrizzük, hogy egy FQDN-es szabály éppen milyen IP-kre helyettesíti a domain nevet, ugyanakkor van egy remek parancs a CLI-ben, amivel utánajárhatunk a tűzfalunk által a domian nevek helyett használt épp aktuális IP-knek:

FORTIGATE ~ $ diagnose firewall fqdn list
www.google.hu: ID(27) REF(1) ADDR(209.85.148.103) ADDR(209.85.148.104) ADDR(209.85.148.105) ADDR(209.85.148.106) ADDR(209.85.148.147) ADDR(209.85.148.99)
srp.eu.blackberry.net: ID(33) REF(2) ADDR(93.186.25.33) ADDR(193.109.81.33)
interwetten.com: ID(38) REF(1) ADDR(195.10.192.12)
energia.eon-hungaria.com: ID(52) REF(2) ADDR(217.67.35.141)
kkk.vam.gov.hu: ID(56) REF(2) ADDR(84.206.40.1)
microsoft.com: ID(67) REF(1) ADDR(207.46.197.32) ADDR(207.46.232.182)
login.live.com: ID(356) REF(1) ADDR(65.54.186.19) ADDR(65.54.186.47) ADDR(65.54.186.77) ADDR(65.54.165.136) ADDR(65.54.165.169) ADDR(65.54.165.175) ADDR(65.54.165.177) ADDR(65.54.186.17)
symantec.com: ID(209) REF(1) ADDR(206.204.52.31) ADDR(216.12.145.20)
update.microsoft.com: ID(244) REF(1) ADDR(65.55.25.59)


Ezeket a DNS cache információkat összevethetjük a DNS-ben elérhető információkkal, gyakran csak annyiról van ugyanis szó, hogy a tűzfal nincs szinkronban a DNS-sel, becache-elt valamilyen IP-t egy adott névhez, míg a valódi közben megváltozott. A parancs kimenetében minden egyes domain névhez tartozik ADDR mezőn vagy mezőkön kívül egy ID és egy REF mező is: fogalmam sincs mit jelenthetnek. Az ID-ról azt gondoltam, hogy a FortiOS tűzfal policyjeiben használt, és külön listában is (get firewall address) kezelt címek ID-jairól van szó, de semmi jele, hogy ezekhez tartozna ID, még a konfigurációs fájlban sem, szóval ezt a teóriát sem megerősíteni sem cáfolni nem tudom. A másik mezőről, a REF-ről elsőre úgy véltem, hogy arra utal, hány referencia van az adott névre a tűzfal policy-kben, de ez sem stimmelt, szóval passz, nem tudni mik ezek. A CLI Reference Guide-ot sem üthetjük fel ezekkel kapcsolatban, ott ugyanis nincs egy szó sem erről a parancsról.

A fenti diagnose firewall fqdn list parancsnak van egyébként még két testvére, az fqdn flush eldobja a cache-ben lévő IP-ket, míg az fqdn purge egyszerűen kipucolja a névlistából az összes olyan domain nevet, amit nem használ a tűzfal. Van továbbá arra is lehetőség, szintén csak a CLI alatt, hogy a DNS cache-be bekerülő nevekhez mi magunk definiáljuk, hogy milyen időközönként ellenőrizze a rendszer a DNS-ben az IP címeket (set ttl <másodperc> a config firewall address / edit domain_név alatt) -- felülvágva ezzel a rendes DNS-ből származó TTL információkat.

2011-09-06

Parancssori SNMP eszközök (3.) - CAM tábla kiolvasása

A korábbiakban már volt szó az alapvető rendszerinformációkról, illetve az interfész tábla és az ARP tábla adatainak "kézi" kiolvasásáról SNMP-n keresztül, a mai poszt a switchek CAM táblájának adaihoz való hozzáférésről szól. Ezt az információt általában valamilyen show (display) alparanccsal kaphatjuk meg a network OS-ek alatt, és alapvetően ugye azt az információt adja meg, hogy egy adott MAC című host fizikailag mely switchporton keresztül érhető el, a kapcsolási folyamat e táblázat alapján dolgozgat.

Mielőtt rátérnénk a lényegre, nem árt egy rövid kitérőt tennünk, ugyanis az eddig kiolvasott adatok mind az RFC1213-ben voltak definiálva, a mostani adatok viszont túl specifikusak, hiszen nem minden SNMP-s eszköz képes Ethernet kapcsolásra. Ennek megfelelően az erre vonatkozó objektumok külön MIB-et kaptak: a BRIDGE-MIB (RFC 1493) írja le őket. Félreértés ne essék, ha egy SNMP agent támogatja a BRIDGE-MIB-et, akkor abból az SNMP kliens eszközünkkel OID alapján nagyjából minden kiolvasható, ám az OID-k helyett egyszerűbb a nevek használata, ehhez pedig elengedhetetlen a megfelelő MIB megléte SNMP kliens oldalon is.

A net-snmp csomagnak nem része alapból a BRIDGE-MIB, így ezt érdemes importálnunk, mielőtt tovább haladnánk. Több helyen is részletes útmutatót olvashatunk arról, miképp okosíthatjuk fel a net-snmp-t extra MIB-ekkel, itt most talán a legegyszerűbb módszert érdemes követnünk, amihez elegendő felhasználói szintű hozzáférés:


user@NMS:~$ wget ftp://ftp.cisco.com/pub/mibs/v1/BRIDGE-MIB.my
--2011-09-06 19:28:58--  ftp://ftp.cisco.com/pub/mibs/v1/BRIDGE-MIB.my
           => `BRIDGE-MIB.my'
Resolving ftp.cisco.com... 72.163.7.54
Connecting to ftp.cisco.com|72.163.7.54|:21... connected.
Logging in as anonymous ... Logged in!
==> SYST ... done.    ==> PWD ... done.
==> TYPE I ... done.  ==> CWD (1) /pub/mibs/v1 ... done.
==> SIZE BRIDGE-MIB.my ... 47013
==> PASV ... done.    ==> RETR BRIDGE-MIB.my ... done.

    [   <=>                                    ] 47,013      59.6K/s   in 0.8s  

2011-09-06 19:29:02 (59.6 KB/s) - `BRIDGE-MIB.my' saved [47013]

user@NMS:~$ mkdir .snmp .snmp/mibs
user@NMS:~$ echo "BRIDGE-MIB BRIDGE-MIB.my" > .snmp/mibs/.index
user@NMS:~$ mv BRIDGE-MIB.my .snmp/mibs/

A CAM tábla információi nem állnak közvetlenül, egységesen SNMP táblázat formájában a rendelkezésünkre, az információkat az SNMP fa külön ágaiból, táblázataiból kell összeszedegetni, nagyobb részük persze a BRIDGE-MIB-en belüli adat, de a végső választ például a "Melyik switchporton keresztül érhető el az AA-AA-AA-AA-00-04 MAC című host?" kérdésre az IF-MIB-ből (ifName) nyerjük majd ki.

Az első lépés a dot1dTpFdbTable (.1.3.6.1.2.1.17.4.3) táblázat   dot1dTpFdbAddress (.1.3.6.1.2.1.17.4.3.1.1) mezőjének snmpwalkkal való bejárása. A parancs kimeneteként megkapjuk azokat a MAC címeket, amelyekről a switch forwarding adatbázisa (Fdb) információt tartalmaz, ezt a kimenetet nagyobb hálózatok esetén célszerű leszűrni a keresett MAC címre egy grep-pel:

user@NMS:~$ snmpwalk -m +BRIDGE-MIB -v1 -cpublic -On -Cc 10.10.10.1 \
dot1dTpFdbAddress | grep "AA AA AA AA 00 04"
.1.3.6.1.2.1.17.4.3.1.1.170.170.170.170.0.4 = Hex-STRING: AA AA AA AA 00 04 

Apróságok az snmpwalk kapcsolói közt: a -m segítségével beolvassuk a BRIDGE-MIB-et is, így használható a dot1dTpFdbAddress név az OID helyett, a -Cc pedig biztos, ami biztos alapon került a parancsba, a tapasztalataim alapján ugyanis nem minden SNMP agent kezeli rendesen ezt a táblázatot, van hogy az OID-k nem szigorúan monoton növekvő rendben követik egymást a fában, ami zavarba hozhatja az snmpwalk-ot, a -Cc kapcsolóval viszont az ilyen rendetlen fákban is eligazodik a program. A parancs kimeneteként kapott OID-ből az .1.3.6.1.2.1.17.4.3.1.1 (dot1dTpFdbAddress) utáni részt (esetünkben a 170.170.170.170.0.4-et [figyelem: 170 = hex AA, akinek megy a hex->dec, az akár az első lépést át is ugorhatta volna :)]) másoljuk ki vágólapra, szükségünk lesz rá a következő parancs grep-es szűrésénél:

user@NMS:~$ snmpwalk -m +BRIDGE-MIB -v1 -cpublic -On -Cc 10.10.10.1 \
dot1dTpFdbPort | grep "170.170.170.170.0.4"
.1.3.6.1.2.1.17.4.3.1.2.170.170.170.170.0.4 = INTEGER: 138

A fenti parancs szintén dot1dTpFdbTable (.1.3.6.1.2.1.17.4.3) táblázatban turkál, ezúttal a dot1dTpFdbPort (.1.3.6.1.2.1.17.4.3.1.2) mezőben. A grep segítségével a táblázat ezen oszlopából kiválasztjuk az első parancsban már megtalált sort. Vagyis a parancs az AA-AA-AA-AA-00-04 MAC címet betanuló port számát adja vissza. Sajnos ez a szám még nem olyan szám, amit a felhasználó közvetlenül értelmezhet, a legtöbb implementációban csupán egy közbülső azonosító. Kivétel persze mindig akad, a nálam járt Nortel 5500-as switcheken például a dot1dTpFdbPort már a valódi portszámot tartalmazta, de kivétel ide vagy oda, ezt a számot a legtöbb esetben valahogy át kell váltanunk emberi fogyasztásra alkalmas adatra. A következő parancsot már e nagy cél elérésének reményében adhatjuk ki, a dot1dBasePortIfIndex (.1.3.6.1.2.1.17.1.4.1.2) egy másik táblázatnak, a dot1dBasePortTable-nek (.1.3.6.1.2.1.17.1.4) a mezője. Ez a táblázat (szintén a BRIDGE-MIB része) felsorolja az összes olyan portot az SNMP agentet futtató eszközön, amely részt vesz a kapcsolási folyamatban. Ezek közül kell kiválasztanunk a példánkban az előző parancs kimenete alapján a 138-as azonosítójú sort a greppel. A második parancs a dot1dBasePortIfIndex oszlopból kinyert ifIndex számot fordítja stringre:

user@NMS:~$ snmpwalk -m +BRIDGE-MIB -v1 -cpublic -On -Cc 10.10.10.1 \
dot1dBasePortIfIndex  | grep ".138"
.1.3.6.1.2.1.17.1.4.1.2.138 = INTEGER: 146800833

user@NMS:~$ snmpwalk -v 1 -c eqnetwork -On -Cc 10.10.10.1 \
ifName | grep "146800833"
.1.3.6.1.2.1.31.1.1.1.1.146800833 = STRING: GigabitEthernet3/0/22

A végeredmény tehát: az AA AA AA AA 00 04 MAC című eszköz az adott switch GE3/0/22-es portján keresztül érhető el. Ez nem feltétlenül jelenti azt, hogy az AA AA AA AA 04 eszköz közvetlenül a GE3/0/22-es porton lóg, lehetséges, hogy az adott porton csak egy újabb switch csatlakozik, amelyből természetesen hasonló módon kinyerhetők a CAM információk. A módszer nem igényel CLI bejelentkezést a switchekre, viszonylag jól szkriptelhető, elvileg sok-sok munkával egész érdekes adatbázis építhető belőle, ha periodikusan mentjük minden switchünkről a CAM adatokat, így ugyanis nyomon követhetjük a hostjaink mozgását a hálózaton belül.

A bemutatott módszer jól működik a legtöbb gyártó esetében, 3Com és Nortel eszközökön biztosan, Cisco switchek esetén még egy csavar van a dologban: a Cisco-féle SNMP implementációban a BRIDGE-MIB adatai VLAN specifikusak, ha a bemutatott parancsokat adjuk ki, akkor csak a natív VLAN-ra vonatkozó adatokat kapjuk vissza. Magyarul míg egy Nortel switch esetén az "snmpwalk -v1 -cpublic -On -Cc 10.10.10.1 dot1dTpFdbAddress" az összes VLAN-on betanult MAC címet listázza, addig egy Cisco switchen ez alapesetben kizárólag a VLAN1-ben forgó MAC-eket adja vissza, ezért ezeken az eszközökön a VLAN ID alapján indexelt SNMP community stringes lekérdezéseket kell összeállítanunk. A részletes magyarázat a bekezdésben lévő linkeken elérhető, a végére már csak egy ilyen Cisco eszközös példa maradt:

user@NMS:~$ snmpwalk -v1 -cpublic@2 -Cc 10.10.10.7 \
.1.3.6.1.2.1.17.4.3.1.1 | grep "AA AA AA 00 12"
SNMPv2-SMI::mib-2.17.4.3.1.1.170.170.170.170.0.18 = Hex-STRING: AA AA AA AA 00 12
 

user@NMS:~$ snmpwalk -v1 -cpublic@2 -Cc 10.10.10.7 \
.1.3.6.1.2.1.17.4.3.1.2 | grep "170.170.170.0.18"
SNMPv2-SMI::mib-2.17.4.3.1.2.170.170.170.170.0.18 = INTEGER: 3
 

user@NMS~$ snmpwalk -v1 -cpublic@2 -Cc 10.10.10.7 \
.1.3.6.1.2.1.17.1.4.1.2 | grep ".3"
SNMPv2-SMI::mib-2.17.1.4.1.2.3 = INTEGER: 10003
 

user@NMS:~$ snmpwalk -v1 -cpublic -Cc 10.10.10.7 ifName | grep 10003
IF-MIB::ifName.10003 = STRING: Fa0/3


Ugyanez IOS-ben:

Switch#show mac-address-table dynamic vlan 2
          Mac Address Table
-------------------------------------------

Vlan    Mac Address       Type        Ports
----    -----------       --------    -----
...
   2    aaaa.aaaa.0012    DYNAMIC     Fa0/3
...
Total Mac Addresses for this criterion: 24