Libro "Router e Internet" edizione Feb2012: capitolo di esempio su EEM e TCL
-
Upload
gianrico-fichera -
Category
Documents
-
view
642 -
download
0
description
Transcript of Libro "Router e Internet" edizione Feb2012: capitolo di esempio su EEM e TCL
169
Capitolo di esempio tratto dal libro “Router e Internet” di Gianrico Fichera e
Maurizio Intravaia
Capitolo VIII Monitoraggio, IP SLA e EEM
Il materiale in questo libro non e’ sponsorizzato o sottoscritto da
Cisco Systems, Inc. Cisco e’ un trademark di Cisco Systems, Inc.
negli Stati Uniti e in altri stati. L’autore di questo libro non si assume
nessuna responsabilita’ e non da nessuna garanzia riguardante
l’accuratezza e la completezza delle informazioni presenti nonche’ da conseguenze sull’uso delle informazioni presenti in questo libro.
Copyright 2011 Gianrico Fichera
Nessuna parte di questa pubblicazione puo' essere riprodotta o
trasmessa, in qualsiasi forma o con qualsiasi mezzo, elettronico, meccanico, fotocopie, registrazione, senza il consenso dell'autore.
This material is not sponsored by, endorsed by, or affiliated
with Cisco Systems, Inc., Cisco, Cisco Systems, and the Cisco
Systems logo are trademarks or registered trade marks of
Cisco Systems, Inc. or its affiliates. All other trademarks are
trademarks of their respective owners.
170
Cisco IP Service Level Agreements (IP SLA) Per Service Level Agreement (SLA) si intende un
contratto siglato tra un fornitore di servizi di
connettivita' (network provider o ISP) ed un cliente dove ci si impegna a fornire un servizio con delle
specifiche ben definite. Ad esempio una continuita' di servizio del 99% con una latenza massima ben
precisa, con un servizio di assistenza con risposta garantita entro un certo tempo dalla chiamata.
L'ISP per poter garantire questi servizi deve
configurare i circuiti dati opportunamente. In caso
di reti provviste di un buon supporto alla qualita' del servizio, come le reti ATM o Frame-Relay o le piu'
moderne MPLS, e' possibile far cio' utilizzando le funzionalita' dei protocolli. In caso di reti sprovviste
di tali protocolli ma basate solo sul TCP/IP (Internet) non e' altrettanto semplice. Se ci fossero
a disposizione una serie di comandi con cui il router potesse automaticamente verificare la rispondenza
di un circuito TCP/IP ai valori contrattualizzati, intervenendo di conseguenza quanto piu' automa-
ticamente possibile, il network provider potrebbe utilizzare in modo piu' efficiente la propria rete e
aumentarne la produttivita'. Questo e' di fatto possibile con la funzionalita' Cisco IP SLA,
disponibile su tutte le piattaforme hardware IOS
all'incirca della versione 12.2T (Catalyst 65XX a partire dalla 12.2(33)SXI1 per il comando "ip sla").
Abbiamo pertanto a disposizione una nuova
famiglia di comandi pensata principalmente per consentire misure sulle performance della rete in
171
tempo reale ed intervenire automaticamente con
delle azioni in conseguenza al verificarsi di determi-nati eventi. Quindi si ha la possibilita' di monitorare
un servizio Internet, come la raggiungibilita' di un indirizzo IP, oppure la raggiungibilita' di un servizio
web, o lo stato di una interfaccia, o la latenza e anche di eseguire delle azioni in conseguenza
all'attivita' monitorata. Il numero di attivita' monitorabili dipende dalla versione di IOS. E'
interessante notare che le performance vengono monitorate attivamente, ovvero con la generazione
di traffico. E' anche possibile configurare dei threshold per cui al superare di determinate soglie il
router invia una trap SNMP. In alternativa da CLI si possono verificare gli SLA.
La quantita' di servizi e funzionalita' monitorabili
e' davvero ampia. Con qualche esempio si potra'
capirne il principio di funzionamento.
Per alcune funzionalita' di monitoraggio e' neces-sario configurare un router mittente e uno
ricevente, quest'ultimo in modalita' "IP SLA
responder" che replica ai pacchetti di monitoraggio inviati dal primo, in modo da verificare alcuni
parametri di circuito. Con il comando "ip sla responder" (oppure "ip sla monitor responder") e'
possibile attivare in un secondo router Cisco un risponditore automatico per alcuni tipi di richieste
inviate da una configurazione "ip sla" di un primo router. Ad esempio se si utilizza il monitoraggio
dell'UDP Jitter (udp-jitter), che poi monitorizza anche il packet-loss e altri parametri, e' necessario
un risponditore all'altro capo della tratta da
172
monitorare. Questo e' estremamente utile per la
VoIP perche' la qualita' del link e' fondamentale per la qualita' della voce.
Configurazione IP SLA
In questi esempi ci limiteremo a delle
configurazioni di base. Una volta capito il principio di funzionamento sara' possibile preparare delle
configurazioni piu' specifiche. Supponiamo di voler monitorare la raggiungibilita' di un indirizzo IP.
La configurazione di uno SLA viene effettuata con il comando "ip sla {NUM}". Dopo aver preparato il
proprio SLA lo si attiva utilizzando il comando "ip sla schedule". Una volta attivo non e' piu'
modificabile. Se necessario dovremo cancellarlo dalla configurazione e ricrearlo.
giarout(config)#ip sla 12 giarout(config-ip-sla)#? IP SLAs entry configuration commands: dhcp DHCP Operation dns DNS Query Operation ethernet Ethernet Operations exit Exit Operation Configuration frame-relay Frame-relay Operation ftp FTP Operation http HTTP Operation icmp-echo ICMP Echo Operation icmp-jitter ICMP Jitter Operation mpls MPLS Operation path-echo Path Discovered ICMP Echo Operation path-jitter Path Discovered ICMP Jitter Operation tcp-connect TCP Connect Operation udp-echo UDP Echo Operation udp-jitter UDP Jitter Operation voip Voice Over IP Operation
Figura 105 - Comando "ip sla"
173
Per verificare le possibilita' di monitoraggio
offerte dall'IOS del nostro router possiamo aiutarci con l'help di linea del CLI, mostrato in figura 105.
Supponiamo di voler creare uno SLA che
monitorizzi un circuito utilizzando il protocollo ICMP in modo da accertarsi che non si superi un tempo di
latenza pari a 20ms. Il test viene effettuato ogni 70 secondi. Nel caso in cui per 5 volte consecutive il
test fallisce si genera una trap e si genera un trigger. Quest'ultimo ha la funzione di fare partire
un secondo sla, il numero "11" che non e' riportato
nell'esempio e che effettuera' dei test aggiuntivi.
ip sla 10 icmp-echo 192.168.30.1 source-interface GigabitEt hernet0/1 timeout 20 frequency 70 ip sla schedule 10 life forever start-time now ip sla reaction-configuration 10 react connectionLo ss threshold-type consecutive 5 action-type trapAndTrigger ip sla reaction-trigger 10 11
Figura 106 - Configurazione di base 'ip sla'
Con il comando "show ip sla configuration
{NUM}" possiamo verificare che la configurazione dello sla 10 sia stata recepita correttamente. In
figura 107 e’ mostrata la corretta sintassi e l’output.
Verifiche SLA
Relativamente all'esempio del paragrafo preceden-
174
te vediamo come verificare che lo SLA sia corret-
tamente funzionante e come vederne le statistiche. Come si vede dalla figura 108 dal momento
dell'avvio ci sono stati 4 successi e 1 fallimento, non sufficiente per l’invio di una trap e all'avvio
dello sla "11".
giatisc# show ip sla configuration 10 IP SLAs, Infrastructure Engine-II. Entry number: 10 Owner: Tag: Type of operation to perform: icmp-echo Target address/Source interface: 192.168.30.1/GigabitEthernet0/1 Type Of Service parameter: 0x0 Request size (ARR data portion): 28 Operation timeout (milliseconds): 20 Verify data: No Vrf Name: Schedule: Operation frequency (seconds): 70 (not considered i f randomly scheduled) Next Scheduled Start Time: Start Time already passe d Group Scheduled : FALSE Randomly Scheduled : FALSE Life (seconds): Forever Entry Ageout (seconds): never Recurring (Starting Everyday): FALSE Status of entry (SNMP RowStatus): Active Threshold (milliseconds): 5000 (not considered if r eact RTT is configured) Distribution Statistics: Number of statistic hours kept: 2 Number of statistic distribution buckets kept: 1 Statistic distribution interval (milliseconds): 20 History Statistics: Number of history Lives kept: 0 Number of history Buckets kept: 15 History Filter Type: None Enhanced History:
Figura 107 - Comando 'show IP sla configuration'
175
giarout# show ip sla statistics 10 IPSLAs Latest Operation Statistics IPSLA operation id: 10 Type of operation: icmp-echo Latest RTT: 1 milliseconds Latest operation start time: *14:18:43.961 UTC Fri Sep 11 2009 Latest operation return code: OK Number of successes: 4 Number of failures: 1 Operation time to live: Forever
Figura 108 - Comando 'show ip sla statistics'
giarout# show ip sla reaction-configuration 10 Entry number: 10 Index: 1 Reaction: connectionLoss Threshold Type: Consecutive Threshold CountX: 5 Threshold CountY: 5 Action Type: Trap and trigger
Figura 109 - Comando 'show ip sla reaction-
configuration'
giarout# show ip sla reactiontrigger 10 Entry number: 10 Target Entry Number: 11 Status of Entry (SNMP RowStatus): active Operational State: pending
Figura 110 - Comando 'show ip sla reactiontrigger'
Esempio di monitoraggio "ftp"
Modifichiamo l'esempio precedente con i seguenti
176
comandi monitoriamo la raggiungibilita' di un
servizio ftp:
ip sla 10 ftp get ftp://anonymous:test@@ftp.gianrico.com/ mode active ip sla schedule 10 life forever start-time now
Figura 111 - Monitoraggio ftp con 'ip sla'
Il comando "track"
Il comando "track" ha lo scopo di monitorare un
evento e di permettere delle azioni in conseguenza al suo verificarsi. Il comando track viene utilizzato
per molti scopi, ad esempio per monitorare lo stato delle interfacce di un router. Questo comando viene
utilizzato anche con il comando "ip sla". Questo
permette delle azioni diverse rispetto la genera-zione di trap oppure trigger in conseguenza al
superamento di un threshold. Il comando e' "track ip sla". In alcune versioni di IOS potrebbe essere
assente e in tal caso va utilizzata la variante "track rtr". Questo comando e' stato introdotto con IOS
12.3(4)T.
Comando "track" senza "ip sla"
Vediamo come utilizzare il comando track con
degli esempi concreti. Questo comando e'
storicamente gia' presente in IOS prima dell' introduzione degli "ip sla". Un campo di applicazione
e' nel monitoraggio delle interfacce. Ad esempio
177
possiamo monitorare lo stato di una interfaccia ATM
e cancellare una riga di routing nel caso in cui la linea vada nello stato di protocollo down.
track 10 interface ATM0/3/0 line-protocol delay down 5 up 30 ip route 18.181.0.0 255.255.255.0 dialer0 track 10 (1)
Figura 112 - Comando 'track' –
Allora se il protocollo dell'interfaccia ATM0/3/0
permane nello stato di down per oltre 5 secondi la
riga di routing (1) viene tolta dalla tabella di routing.
Con i comandi "show track" e "show track brief" si puo' verificare lo stato del monitoring:
gia-gw# show track 10 Track 10 Interface ATM0/3/0 line-protocol Line protocol is Up 1 change, last change 00:06:27 Delay up 30 secs, down 5 secs Tracked by: STATIC-IP-ROUTING 0 gia-gw# show track brief Track Object Parameter Value Last Change 10 interface ATM0/3/0 line-protocol Up 00:07:07
Figura 113 - Comando 'show track'
Con il comando "debug track" e' possibile fare
il debugging degli eventi. Ecco cosa succede quando il protocollo dell'interfaccia Atm0/3/0 passa nello
stato di down:
178
000917: Jan 20 16:09:43.646: Track: 10 Down change delayed for 5 secs 000923: Jan 20 16:09:48.646: Track: 10 Down change delay expired 000924: Jan 20 16:09:48.646: Track: 10 Change #4 in terface ATM0/3/0, line-protocol Up->Down
Figura 114 - Debug: track transizione down su
interfaccia
Ed ecco cosa accade quando il protocollo torna
nello stato di up:
000934: Jan 20 16:12:29.079: Track: 10 Up change de lay expired 000935: Jan 20 16:12:29.079: Track: 10 Change #5 in terface ATM0/3/0, line-protocol Down->Up
Figura 115 - Debug: track transizione up su interfaccia
Con il comando "show ip route track-table" si
possono vedere quali sono le righe di routing monitorate:
gia-gw# show ip route track-table ip route 18.181.0.0 255.255.255.0 Dialer1 track 10 state is [up]
Figura 116 - Comando 'show ip route track-table'
179
Esempio "track" con "ip sla"
Presentiamo adesso un esempio sulle nuove
funzionalita' del comando track. Si osservi la configurazione in figura.
ip name-server 192.168.30.30 ip domain-lookup ip sla 10 http get http://www.itesys.it frequency 100 ip sla schedule 10 life forever start-time now track 50 ip sla 10 !oppure "track 50 rtr 10" in ve cchie versioni ip route 18.181.0.31 255.255.255.255 Serial0/0/0.1 track 50 (2)
Figura 117 - Configurazione 'ip sla' con 'track'
Anche se dal punto di vista pratico la
configurazione puo' non avere molta utilita', dal punto di vista didattico e' molto interessante. Se il
sito web http://www.itesys.it diventa irraggiungibile la riga di routing (2) viene tolta dalla tabella di
routing. Con il comando "debug ip sla trace" si
puo' vedere lo stato del tracking come si vede in figura 118.
Nel caso in cui la risoluzione del nome fallisca,
oppure l'indirizzo IP del sito web diventa irraggiun-gibile, oppure il server web non risponde alla porta
80 per il sito web indicato, la riga di routing (2) viene tolta dalla tabella di routing.
180
*Jan 20 16:26:16.532: IP SLAs(10) Scheduler: saaSchedulerEventWakeup *Jan 20 16:26:16.532: IP SLAs(10) Scheduler: Starti ng an operation *Jan 20 16:26:16.532: IP SLAs(10) http operation: S tarting http operation *Jan 20 16:26:16.532: IP SLAs(10) dns operation: St arting dns operation *Jan 20 16:26:16.532: IP SLAs(10) dns operation: Qu ery name - www.itesys.it *Jan 20 16:26:16.532: IP SLAs(10) dns operation: Qu ery name server - 151.99.125.2 *Jan 20 16:26:16.532: IP SLAs(10) dns operation: ac tual target queried = www.itesys.it *Jan 20 16:26:16.616: IP SLAs(10) dns operation: Qu ery return code - no error *Jan 20 16:26:16.616: IP SLAs(10) dns operation: re ceived IP Address 82.85.14.71 *Jan 20 16:26:16.616: IP SLAs(10) dns operation: RT T=87 *Jan 20 16:26:16.760: IP SLAs(10) http operation: S ent 18 of 18 bytes *Jan 20 16:26:16.760: IP SLAs(10) http operation: W ait connection - connected *Jan 20 16:26:16.948: IP SLAs(10) http operation: T ime to first byte: 328 ms *Jan 20 16:26:16.948: IP SLAs(10) http operation: R TT=417 *Jan 20 16:26:16.948: IP SLAs(10) Scheduler: Updati ng result
Figura 118 - Comando 'debug IP sla trace'
E' possibile creare delle condizioni complesse con
l'uso di 'and' oppure 'or'. Vediamone un esempio.
track 111 list boolean and object 10 object 20
Figura 119 - Comando 'object' con 'track'
Nota 1: spesso i server web rispondono comunque
nel caso in cui un singolo sito web non sia funzio-nante, magari con messaggi del tipo "service
181
unavailable". In questo caso per il router il sito web
e' funzionante. Quindi il comando "http get" dell'esempio e' valido per verificare la raggiun-
gibilita' TCP/IP di un server ma non per monitorare lo stato di un singolo sito web che va oltre lo scopo
dei servizi di IOS;
Nota 2: nelle prime versioni di IOS si puo' trovare il comando "rtr" invece di "ip sla". Nelle versioni
dalla 12.4(20)T si ha "track ... sla..." invece di "track ... rtr..."
Nota 3: Nel caso si utilizzi il 'track' con 'rtr'
osservate che non si puo' utilizzare la parola chiave "consecutive" in "ip sla react configuration". Per
fare in modo tale da scatenare un evento dopo un
certo numero di ping falliti bisogna utilizzare un "delay" sufficientemente lungo in 'track' e dei valori
di 'frequency' e 'timeout' sufficientemente corti in 'ip sla' in modo da farci cadere il numero di
pacchetti icmp voluti.
Comando “track” e floating static route
Per "floating static route" intendiamo delle
righe di routing statico che hanno una distanza
amministrativa superiore al normale. Possono essere utilizzate come righe di backup o "backdoor"
da utilizzare nel caso in cui una route statica a priorita' maggiore venga cancellata dalla RIB. Se
un'interfaccia fisica va nello stato di down le righe statiche che la referenziano come next-hop
vengono tolte dalla RIB dando spazio ad eventuali altri righe provenienti da algoritmi di routing
182
dinamico oppure, appunto, righe statiche con AD
maggiore. Il limite nell'utilizzo di questo sistema sta nel fatto che in molte tipologie di guasto le
interfacce rimangono nello stato di UP senza pero' consentire il transito di dati, ma vedremo nei
paragrafi successivi come si puo' trovare rimedio a casi del genere. In tali casi le righe di route
rimangono in RIB. In tutti questi casi questa forma di backup non funziona. Segue in figura un esempio
di floating static route.
ip route 0.0.0.0 0.0.0.0 192.168.10.1 ip route 0.0.0.0 0.0.0.0 192.168.20.2 200
Figura 120 - 'ip route' con 'track'
In circostanze normali la route di default utiliz-
zata e' la prima e il gateway della rete e' l'indirizzo IP 192.168.10.1. Se questa riga di routing viene
cancellata dalla RIB, cosa che avviene solo nei casi sopra indicati, il gateway della rete diventera'
l'indirizzo IP 192.168.10.2. Se affianchiamo le floating route con il track e l'ip sla possiamo
realizzare interessanti configurazioni di backup dove piuttosto che monitorare lo stato di una interfaccia
monitoriamo l'effettiva sua capacita' di trasmettere
dati. E' possibile utilizzare il comando track insieme alle floating static route per potenziarne il
funzionamento, come in figura.
ip route 0.0.0.0 0.0.0.0 192.168.10.1 track 223 ip route 0.0.0.0 0.0.0.0 192.168.20.2 200
Figura 121 - 'ip route' con 'track'
183
Il bilanciamento di carico con interfacce di tipo dialer e backup
Nel caso di collegamenti WAN, come ad esempio
ADSL, le interfacce coinvolte sono spesso di tipo
dialer. In questo caso si potrebbe bilanciare il traffico in uscita tra i due circuiti, ad esempio se le
due ADSL sono con lo stesso operatore, adottando la semplice configurazione in figura.
ip route 0.0.0.0 0.0.0.0 dialer0 ip route 0.0.0.0 0.0.0.0 dialer1
Figura 122 - Statiche e bilanciamento di carico in
interfacce Dialer
Anche in tale caso vale quanto detto in
precedenza tuttavia le interfacce di tipo dialer hanno una particolarita' che e' bene conoscere. Puo'
accadere che entrambe le righe di routing restino in tabella di routing anche se una delle due interfacce
non e' funzionante. Questo perche' le interfacce dialer sono sempre nello stato di "up". Semmai
l'interfaccia "virtual-access" associata puo' essere presente o meno a seconda dello stato del circuito
associato.
Se una riga di routing relativa ad un
collegamento non funzionante rimane nella tabella di routing questo determina una perdita di
pacchetti. Nel caso di un bilanciamento di carico per destinazione circa il 50% delle connessioni fallira'.
184
La soluzione e' abbastanza articolata e implica
l'utilizzo del comando "track" che crea un processo di monitoraggio automatico in grado di determinare
se una interfaccia dialer e' funzionante o meno. Se e' vero che una interfaccia dialer puo' restare
sempre nello stato di UP e' anche vero che, se un collamento ADSL non funziona l'interfaccia sara'
sprovvista di indirizzo IP in quando il provider ISP non e' stato in grado di assegnarlo. Questo e' vero
quando l'IP viene assegnato dal provider tramite negoziazione del PPP.
track 10 interface Dialer0 ip routing delay down 5 up 30 track 11 interface Dialer1 ip routing delay down 5 up 30 ip route 0.0.0.0 0.0.0.0 Dialer0 track 10 ip route 0.0.0.0 0.0.0.0 Dialer1 track 11 ! 1841-gia# sh track 10 Track 10 Interface Dialer0 IP routing IP routing is Down (no IP addr) 1 change, last change 00:43:32 Delay up 30 secs, down 5 secs Tracked by: STATIC-IP-ROUTING 0 1841-gia# 1841-gia# sh track 11 Track 11 Interface Dialer1 IP routing IP routing is Up 1 change, last change 00:43:33 Delay up 30 secs, down 5 secs Tracked by: STATIC-IP-ROUTING 0
Figura 123 - Dialer, load-balancing e comando track -
185
Il comando "track", come abbiamo gia’ visto, e'
in grado di monitorare alcuni stati di un router. Interessa nel nostro caso perche' e' in grado di
verificare la capacita' di una interfaccia di fare "routing", il che e' possibile solo se questo ha un
indirizzo IP. Questo tracciamento si aggancia alle righe di routing statico che verranno eliminate
temporaneamente in caso di mancanza dei prerequisiti imposti. Nell'esempio in figura 123, nel
caso in cui l'interfaccia dialer non sia in grado di fare routing per piu' di 5 secondi, viene eliminata la
statica in corrispondenza del track. Se l'interfaccia torna attiva dopo un disservizio si attenderanno 30
secondi per essere sicuri che non si tratti di un flap. Con il comando "show track" si puo' verificare il
processo di monitoraggio.
In questo esempio monitoriamo non lo stato del
protocollo in una interfaccia (up o down), ma il fatto che questa abbia o meno un indirizzo IP. Nel caso
delle interfacce di tipo dialer, con negoziazione PPP dell'indirizzo IP, l'assenza di indirizzo IP implica
assenza di collegamento.
Cisco ASA, "track" & "ip sla"
In questo libro non trattiamo i firewall cisco della serie ASA tuttavia molte delle funzionalita' dei
paragrafi precedenti, seppur con alcune differenze, sono anche disponibili sui firewall Cisco ASA e PIX
7.X. Nell'esempio in figura si ha un Cisco ASA in
grado di verificare lo stato di efficenza di un
186
gateway e di smistare il traffico su un secondo
gateway in caso di fault.
sla monitor 123 type echo protocol ipIcmpEcho 18.87.179.129 interf ace outside num-packets 5 frequency 5 sla monitor schedule 123 life forever start-time no w track 1 rtr 123 reachability route outside 0.0.0.0 0.0.0.0 18.87.157.93 1 track 1 route outside 0.0.0.0 0.0.0.0 18.87.157.90 100
Figura 124 - Cisco ASA: comandi 'sla monitor' e 'track'
Nell'esempio si verifica la raggiungibilita' ICMP
dell'indirizzo IP 18.87.179.129, attraverso
l'interfaccia outside. Il monitoraggio e' continuo "life forever" ed e' attivo sempre. Nel caso di mancanza
di raggiungibilita' il comando track elimina la prima riga di default che attiva, secondo le regole del
floating static route, la seconda. Con i comandi "show ip sla statistics", "show ip sla
configuration", "show track" e' possibile
monitorare lo stato.
Cisco EEM - Embedded Event Manager -
Cisco IOS Embedded Event Manager (EEM) e' un
potente modulo software di Cisco IOS che permette di automatizzare azioni in un router IOS scrivendo
delle policy. Per policy si intendono degli applet
187
oppure degli script realizzati utilizzando il linguaggio
di programmazione TCL. Puo' essere immaginato come un'evoluzione di "IP SLA" ma in realta' lo
affianca e le due funzionalita' si possono integrare. Infatti gli eventi generati dagli IP SLA possono
integrarsi con EEM. EEM e' disponibile nella versione 1.0 a partire dalla versione di IOS 12.0(26)S ma e'
consigliabile utilizzarlo a partire da IOS 12.3(4)T.
Event Manager permette di generare script di monitoraggio utilizzando gli stessi comandi di IOS
oppure utilizzando il linguaggio TCL. L'introduzione
di un linguaggio di programmazione come il TCL consente una grande flessibilita'.
EEM evolve di continuo e nel momento della
stesura di questo libro e' alla versione 3.2 presente a partire da IOS 12.4(22)T. EEM 3.1 e' stato
introdotto con IOS 15.0 con TCL 8.3.4. A seconda della release presente in IOS, che partono dalla 1.0,
le funzionalita' a disposizione possono variare. Con il "Cisco Feature Navigator", strumento disponibile
nel sito web Cisco, e' possibile consultare le
funzionalita' a disposizione in ogni release di IOS.
Per conoscere quale versione di EEM e' attiva in
IOS potete utilizzare il comando "show event
manager version" come in figura 125. Osservate la presenza di una lista di processi chiamati event
detectors. La lista, riportata parzialmente in figura, rappresenta l'elenco di processi che
monitorizzano lo stato di IOS.
188
giahouse#show event manager version Embedded Event Manager Version 3.20 Component Versions: eem: (v320_rel1)1.0.1 eem-gold: (v320_rel1)1.0.0 eem-call-home: (v320_rel1)1.0.0 Event Detectors: Name Version Node Type application 01.00 node0/0 RP neighbor-discovery 01.00 node0/0 RP ... routing 02.00 node0/0 RP syslog 01.00 node0/0 RP cli 01.00 node0/0 RP track 01.00 node0/0 RP ...
Figura 125 - Cisco EEM: comando "show event
manager"
Con le nuove release di EEM vengono introdotti spesso nuovi event detectors che permettono un
monitoraggio sempre piu' completo. Per fare un esempio il 'syslog' event detector, mostrato in
figura, intercetta tutti i messaggi syslog di sistema.
Per interderci quelli che vengono mostrati in console. E' allora possibile da uno script EEM agire
in corrispondenza di determinati messaggi di syslog. Lo stesso discorso si puo' ripetere per gli
altri event detector. Ad esempio l'event detector "cli" permette di pubblicare un evento che esegue
dei comandi CLI, permettendo di modificare la configurazione del router.
Notiamo anche la presenza dell'event detector
"track". Questo e' molto interessante perche' e'
legato al monitoraggio del processo associato ai comandi "track". Poter intercettare gli eventi
189
generati dal comando track ci permette di
estenderne le potenzialita' come vedremo in un esempio nei paragrafi successivi.
Configurazione di EEM utilizzando gli applet
Non e' sempre necessario creare policy in TCL per
la gestione degli eventi. Se non dovete gestire degli eventi complessi si possono creare degli applet
senza TCL. Con il comando "event manager applet" (Dalla versione 12.4 nella serie 1800, dalla
versione 12.2 nei catalyst, dalla serie 800 da IOS 15.0) usato insieme al comando "ip sla reaction-
configuration" e' possibile in conseguenza a degli
eventi, definire delle azioni, utilizzando i comandi IOS come linguaggio di script. Piuttosto che
elencare una serie di comandi e relativa sintassi guardiamo subito un esempio in figura che e'
autoesplicativo.
event manager applet mioapplet event syslog pattern "Interface Ethernet 0/0, chang ed status to down" action 1.0 cli command "enable" action 2.0 cli command "conf t" action 3.0 cli command "ip route 10.10.10.0 255.25 5.255.0 1.1.1.1" action 4.0 mail server "192.85.14.73" to "[email protected]" from "ciscorouter26" subje ct "interfaccia down" body "attivato routing secondari o"
Figura 126 - Cisco EEM: invio email in caso di evento
190
Nel sorprendente script in figura il sistema
monitorizza i messaggi di log della console di un router. Se compare esattamente il messaggio
indicato tra doppi apici si attiva un trigger da cui conseguono delle azioni (action). Questo determina
l'esecuzione in sequenza di tre comandi IOS con lo scopo di attivare un collegamento di backup e
quindi di inviare una email per segnalare all'amministratore di sistema l'evento (EEM V.2.1
per l'invio di email da applet). L'esempio e' veramente illuminante. Infatti potete osservare
come il router si riconfiguri in autonomia in conseguenza ad un evento. E' una possibilita'
considerevole. Le righe sono numerate. Questo ci consente in un secondo tempo di aggiungere righe,
ma fate molta attenzione che le righe sono
interpretate alfabeticamente ovvero 10.0 viene prima di 2.0!!!
Con il comando "event manager run" si
possono testare gli applet. Tuttavia prima bisogna accertarsi che vi sia la riga "event none" nell'applet
altrimenti si ottiene il messaggio di errore in figura.
giahouse#event manager run mioapplet EEM policy mioapplet not registered with event none Event Detector
Figura 127 - Cisco EEM: invio email in caso di evento
Nel caso il cui l'applet utilizzi l'event syslog si
puo' inviare manualmente un messaggio al syslog in modo da forzare l'avvio dello script in modo da
testarlo. Per fare questo da console utilizzare il
191
comando "send log {messaggio}". In questo modo
possiamo testare rapidamente gli applet. Per stabilire se un applet e' stato eseguito si puo'
utilizzare il comando "show event manager history events" che mostra lo storico dell' ese-
cuzione degli applet. Affinche' una policy sia utilizzabile questa dev'essere registrata. Per gli
applet la registrazione e' automatica a differenza di quanto avviene per gli script TCL. Per vedere quali
policy sono registrate si utilizza il comando "show event manager policy registered". Nel caso
dell'applet dell'esempio precedente si avra' l'output mostrato in figura.
giahouse#show event manager policy registered No. Class Type Event Trap Time Registered Se cu Name 1 applet user syslog Off Thu Dec 30 15:01:09 no ne mioapplet pattern {Interface Ethernet 0/0, changed status t o down} maxrun 20.000 action 1.0 cli command "enable" action 1.1 cli command "conf t" action 1.2 cli command "ip route 10.10.10.0 255.2 55.255.0 1.1.1.1" action 1.3 mail server "192.85.14.73" to "[email protected]" from "cisco" subject "inter faccia down" body "attivato routing secondario"
Figura 128 - Cisco EEM: invio email in caso di evento
Presentiamo un nuovo esempio in cui mostriamo
come gestire un evento relativo alla irrag-giungibilita' di un indirizzo IP tramite ICMP. Questo
esempio e' molto utile perche' ci mostra come integrare le funzionalita' di "IP SLA" con "EEM".
Nell'evento rileviamo l'irraggiungibilita' di un host utilizzando le funzionalita' offerta da "IP SLA". In
caso di irraggiungibilita' EEM intercetta l'evento e
con un applet cambia la route di default. Questo puo' essere estremamente utile per rilevare
192
correttamente un disservizio in un collegamento
Internet quindi questo applet e' di larga appli-cabilita'.
catalyst_backup# sh run | section sla ip sla 10 icmp-echo 10.11.12.13 source-ip 10.11.12.14 timeout 100 ip sla schedule 10 life forever start-time now track 1 ip sla 10 reachability catalyst_backup# sh run | section event event manager applet pingfailed event track 1 state down <-- 12.4 (2)T in IOS almeno action 1.0 syslog msg " ping failed " action 1.1 cli command "enable" action 1.2 cli command "conf term" action 2.0 cli command "ip route 0.0.0.0 0.0.0. 0 192.168.30.145" action 3.0 cli command "exit"
Figura 129 - Cisco EEM: riconfigurazione automatica in
caso di ICMP timeout
Combinando le funzionalita' di EEM, SLA e TRACK possiamo anche creare eventi combinati
tramite funzioni booleane. Nell'esempio in figura
130 monitoriamo due collegamenti e solo nel caso in cui entrambi siano DOWN si genera un evento.
Si noti che "AND" e "OR" del comando track
sono booleani. Ovvero ci vuole un OR per generare un evento nel caso di contemporaneita' di due
FAIL. Una conseguenza di quanto spiegato e' che possiamo anche riavviare il router in caso di eventi
straordinari. La sintassi e' nell'esempio che segue.
193
catalyst_backup# show run | section sla ip sla 10 icmp-echo 10.11.12.13 source-ip 10.11.12.14 timeout 100 frequency 20 ip sla schedule 10 life forever start-time now ip sla 11 icmp-echo 10.11.12.17 source-ip 10.11.12.18 timeout 100 frequency 20 ip sla schedule 11 life forever start-time now track 111 ip sla 10 reachability track 112 ip sla 11 reachability catalyst_backup# show run | section track track 1 list boolean or object 111 object 112 track 111 ip sla 10 reachability track 112 ip sla 11 reachability catalyst_backup# show run | section event event manager applet pingfailed event track 1 state down <-- 12.4(2)T IOS alm eno action 1.0 syslog msg " ping failed " action 1.1 cli command "enable" action 1.2 cli command "conf term" action 2.0 cli command "ip route 0.0.0.0 0.0.0.0 19.16.4.1" action 4.0 cli command "exit" action 5.0 mail server "112.112.12.12" to "[email protected]" from " [email protected] " subject "corpo del messaggio" body "messaggio di test" catalyst_backup# show track 1 Track 1 List boolean and Boolean OR is Up 6 changes, last change 00:10:14 object 111 Up object 112 Up Tracked by: EEM applet pingfailed catalyst_backup#
Figura 130 - Cisco EEM: auto-riconfigurazione e email in
caso di DOWN
194
event manager applet ErroreGrave event track 100 state down action 1.0 syslog msg "Errore grave, riavvio il ro uter" action 2.0 reload
Figura 131 - Cisco EEM: invio messaggi al syslog e riavvio sistema
Esempio sull'uso di EEM per gestire la ridondanza
Nei piccoli uffici o comunque nelle strutture di
rete piu' semplici gestire la ridondanza degli accessi
ad Internet e' spesso problematico. Infatti non possiamo fare affidamento agli algoritmi di routing
dinamico e per i collegamenti di fascia bassa difficilmente gli ISP mettono a disposizione delle
offerte per il load-balancing o per il backup
automatico dei circuiti. Magari abbiamo due circuiti ADSL con due operatori differenti e con
indirizzamento IP differente e questo spesso impedisce anche un semplice load-balancing in
uscita in quanto non si possono usare gli indirizzi IP di un ADSL con uno differente. Prima dell'avvento di
"IP SLA" e "EEM" il massimo che si poteva fare era di rilevare con il "track" una interfaccia nello stato
di down e cambiare il routing di conseguenza, come abbiamo visto nei paragrafi precedenti. In caso di
utilizzo del NAT la situazione si complicava ulteriormente.
Nell'esempio che segue consideriamo una
configurazione piu' complessa e quindi piu' istrut-
tiva con la presenza di due circuiti HDSL che
195
vogliamo in load-balancing con NAT e un terzo
circuito ADSL. L'ADSL viene utilizzato per traffico di tipo VoIP, riconosciuta in base all'ip mittente. Se
l'ADSL non funziona vogliamo che la VoIP passi automaticamente sull'HDSL. Viceversa se le HDSL
vanno entrambe giu' i dati devono transitare sull'ADSL. Possiamo supporre che i collegamenti
siano anche con operatori differenti.
... ip sla 3 icmp-echo AA.AA.AA.AA source-interface Serial0/0/0.1 timeout 1500 frequency 8 ip sla schedule 3 life forever start-time now ! ip sla 4 icmp-echo BB.BB.BB.BB source-interface Serial0/0/ 1.1 timeout 1500 frequency 8 ip sla schedule 4 life forever start-time now ! track 10 rtr 3 reachability delay down 40 up 40 ! track 11 rtr 4 reachability delay down 40 up 40 ! track 12 interface Dialer1 IP routing delay down 5 up 30 ! track 13 list boolean or object 10 object 11 ! ! ! interface FastEthernet0/0 description --- interfaccia clienti con load-shar ing --- ip address FF.FF.FF.FF 255.255.255.0 ip policy route-map private ip nat inside ! interface FastEthernet0/1 description --- interfaccia server e clienti con nat statico --- IP address EE.EE.EE.EE 255.255.255.0 IP policy route-map private
196
! interface Serial0/0/0 no IP address encapsulation frame-relay IETF load-interval 30 frame-relay lmi-type cisco ! interface Serial0/0/0.1 point-to-point bandwidth 2048 IP address CC.CC.CC.CC 255.255.255.252 IP nat outside frame-relay interface-dlci 50 IETF ! interface Serial0/0/1 no IP address encapsulation frame-relay IETF load-interval 30 frame-relay lmi-type cisco ! interface Serial0/0/1.1 point-to-point bandwidth 2048 IP address DD.DD.DD.DD 255.255.255.252 IP nat outside frame-relay interface-dlci 50 IETF ! interface ATM0/1/0 no IP address IP nat outside no atm ilmi-keepalive dsl operating-mode auto pvc 8/35 encapsulation aal5mux ppp dialer dialer pool-member 1 ! ! interface Dialer1 ip address negotiated ip nat outside ... configurazione ADSL... ! ip route 0.0.0.0 0.0.0.0 Serial0/0/0.1 track 10 ip route 0.0.0.0 0.0.0.0 Serial0/0/1.1 track 11 ip route 0.0.0.0 0.0.0.0 Dialer1 200 ! ip nat inside source route-map adslvoip interface D ialer1 overload ip nat inside source route-map uscitaload1 interfac e Serial0/0/0.1 overload ip nat inside source route-map uscitaload2 interfac e Serial0/0/1.1 overload ! access-list 10 remark -- classi di IP sorgenti per HDSL --
197
access-list 10 permit ... access-list 20 remark -- classi di IP sorgenti per ADSL -- access-list 20 permit ... access-list 30 remark -- classi di IP sorgenti per secondo HDSL-- access-list 30 permit ... !!! Con queste route map il NAT utilizza i tre collegamenti in base al mittente !route-map adslvoip permit 15 match IP address 20 set interface Dialer1 ! route-map uscitaload2 permit 20 match IP address 102 match interface Serial0/0/1.1 ! route-map uscitaload1 permit 10 match IP address 102 match interface Serial0/0/0.1 !!! Con queste route map i mittenti con IP pubblico escono dalla connettivita' associata route-map private permit 10 description --- HDSL --- match IP address 10 set IP next-hop ... ! route-map private permit 20 description --- ADSL --- match IP address 20 set interface Dialer1 ! route-map private permit 30 description --- HDSL --- match IP address 30 set IP next-hop ... ! ! ... ! ! EEM riconfigura il router in base al disservizio sul circuito segnalato dagli eventi ! generati dal comando track ! event manager applet ADSLDOWN event track 12 state down action 1.0 cli command "enable" action 1.1 cli command "conf t" action 1.5 cli command "no access-list 40" action 1.6 cli command "access-list 102 permit IP ..." action 1.8 cli command "exit" event manager applet ADSLUP event track 12 state up
198
action 1.0 cli command "enable" action 1.1 cli command "conf t" action 1.5 cli command "access-list 40 permit ..." action 1.6 cli command "no access-list 102" action 1.7 cli command "access-list 102 permit IP ..." action 1.8 cli command "access-list 102 permit IP ..." action 1.9 cli command "exit" event manager applet DUEHDSLDOWN event track 13 state down action 1.0 cli command "enable" action 1.1 cli command "conf t" action 1.2 cli command "access-list 40 permit ..." action 1.3 cli command "exit" event manager applet DUEHDSLUP event track 13 state up action 1.0 cli command "enable" action 1.1 cli command "conf t" action 1.5 cli command "no access-list 40" action 1.6 cli command "access-list 40 permit ..." action 1.8 cli command "exit" ! end gianricotest# sh track Track 10 Response Time Reporter 3 reachability Reachability is Up 1 change, last change 04:15:47 Delay up 40 secs, down 40 secs Latest operation return code: OK Latest RTT (millisecs) 19 Tracked by: STATIC-IP-ROUTING 0 Track 11 Response Time Reporter 4 reachability Reachability is Up 7 changes, last change 03:37:58 Delay up 40 secs, down 40 secs Latest operation return code: OK Latest RTT (millisecs) 76 Tracked by: STATIC-IP-ROUTING 0 Track 12 Interface Dialer1 IP routing IP routing is Up 10 changes, last change 06:31:19 Delay up 30 secs, down 5 secs Tracked by: EEM applet ADSLUP EEM applet ADSLDOWN Track 13 List boolean and
199
Boolean OR is Up 8 changes, last change 03:37:58 object 10 Up object 11 Up Tracked by: EEM applet DUEHDSLUP EEM applet DUEHDSLDOWN gianricotest# show IP sla statistics Round Trip Time (RTT) for Index 3 Latest RTT: 15 milliseconds Latest operation start time: *20:25:48.344 UTC Fri Jan 8 2010 Latest operation return code: OK Number of successes: 288 Number of failures: 0 Operation time to live: Forever Round Trip Time (RTT) for Index 4 Latest RTT: 648 milliseconds Latest operation start time: *20:25:45.400 UTC Fri Jan 8 2010 Latest operation return code: OK Number of successes: 290 Number of failures: 0 Operation time to live: Forever gianricotest# show event manager history events No. Time of Event Event Type Name 1 Fri Jan 8 08:45:57 2010 track applet: ADSL DOWN 2 Fri Jan 8 08:47:25 2010 track applet: ADSL UP 3 Fri Jan 8 13:53:37 2010 track applet: ADSL DOWN 4 Fri Jan 8 13:54:28 2010 track applet: ADSL UP 5 Fri Jan 8 16:18:33 2010 track applet: DUEH DSLDOWN 6 Fri Jan 8 16:22:43 2010 track applet: DUEH DSLUP 7 Fri Jan 8 16:24:08 2010 track applet: DUEH DSLDOWN 8 Fri Jan 8 16:28:43 2010 track applet: DUEH DSLUP 9 Fri Jan 8 16:40:03 2010 track applet: DUEH DSLDOWN 10 Fri Jan 8 16:47:48 2010 track applet: DUEH DSLUP gianricotest# show ip route track-table ip route 0.0.0.0 0.0.0.0 Serial0/0/0.1 track 10 sta te is [up] ip route 0.0.0.0 0.0.0.0 Serial0/0/1.1 track 11 sta te is [up]
Figura 132 - Esempio di configurazione EEM + SLA
200
EEM e gli script TCL preinstallati
L'utilizzo di script in TCL e' un'alternativa
all'utilizzo degli applet. E' ovvio che le potenzialita' sono di molto superiori rispetto gli applet. Tuttavia
bisogna apprendere il TCL e questo richiede del tempo. Fortunatamente ci sono molti script TCL gia'
pronti e utilizzabili. Cisco fornisce degli script TCL di esempio gia' preinstallati nel router. Gli script TCL
forniti da Cisco operano in 'full TCL mode' mentre quelli scritti da un utente in 'safe TCL mode', una
versione di TCL priva di alcuni comandi che, se utilizzati, potrebbero compromettere il buon
funzionamento del sistema.
Gli script TCL vengono chiamati da Cisco policy.
Router diversi con diverse versioni di IOS hanno file di esempio differenti. Quindi cio' che vedrete nelle
figure a seguire potrebbe non combaciare con quanto presente nel vostro router. Con il comando
"show event manager policy available" pos-siamo vedere quali policy sono installate nel nostro
router.
giahouse#show event manager policy available No. Type Time Created Name 1 system Mon Feb 7 07:28:15 2036 ap_perf_test_base_ cpu.tcl 2 system Mon Feb 7 07:28:15 2036 cl_show_eem_tech.t cl 3 system Mon Feb 7 07:28:15 2036 no_perf_test_init. tcl 4 system Mon Feb 7 07:28:15 2036 sl_intf_down.tcl 5 system Mon Feb 7 07:28:15 2036 tm_cli_cmd.tcl 6 system Mon Feb 7 07:28:15 2036 tm_crash_reporter. tcl 7 system Mon Feb 7 07:28:15 2036 tm_fsys_usage.tcl
Figura 133 - Cisco EEM: script TCL preinstallati
201
Senza scendere nel dettaglio, che uscirebbe dagli
scopi di questo libro, osserviamo le policy di nome "sl_intf_down.tcl" e "tm_cli_cmd.tcl".
Con il comando "show event manager policy
available detailed {nomepolicy}" e' possibile vedere il sorgente TCL di una policy. Cio' che ci puo'
interessare sono le righe iniziali che spiegano le funzionalita' dello script e le variabili che utilizza.
Come esempio vediamo una parte dello script "tm_cli_cmd.tcl" fornito da Cisco in ogni IOS con
EEM. Questo script lo trovate in ogni router con
EEM ed e’ copyright Cisco System.
ite-7204# show event manager policy available detailed tm_cli_cmd.tcl ::cisco::eem::event_register_timer cron name crontimer2 cron_entry $_cron_entry maxrun 240 #---------------------------------- # EEM policy that will periodically execute a cli com mand # and email the results to a user. # # July 2005, Cisco EEM team # # Copyright (c) 2005-2006 by cisco Systems, Inc. # All rights reserved. #---------------------------------- ### The following EEM environment variables are used: ### ### _cron_entry (mandatory) ### -A CRON specification that determines ### when the policy will run. See the ### IOS Embedded Event Manager ### documentation for more information ### on how to specify a cron entry. ### Example: _cron_entry 0-59/1 0-23/1 * * 0- 7 ### ### _log_file (mandatory without _email_....) ### - A filename to append the output t o. ### If this variable is defined, the ### output is appended to the specifi ed ### file with a timestamp added. ### Example: _log_file disk0:/my_file.log ### ### _email_server (mandatory without _log_file)
202
### - A Simple Mail Transfer Protocol ( SMTP) ### mail server used to send e-mail. ### Example: _email_server mailserver.customer.c om ### ### _email_from (mandatory without _log_file) ### - The address from which e-mail is sent. ### Example: _email_from [email protected] ### ### _email_to (mandatory without _log_file) ### - The address to which e-mail is sent. ### Example: _email_to [email protected] ### ### _email_cc (optional) - The address to which the e-mail ### must be copied. ### Example: _email_cc [email protected] ### ### _show_cmd (mandatory) - The CLI command to be executed ### when the policy is run. ### Example: _show_cmd show versi on ### # check if all the env variables we need exist # If any of them doesn't exist, print out an error msg and quit if {![info exists _log_file]} { if {![info exists _email_server]} { set result \ "Policy cannot be run: variable _lo g_file or _email_server has not been set" error $result $errorInfo } if {![info exists _email_from]} { set result \ "Policy cannot be run: variable _lo g_file or _email_from has not been set" error $result $errorInfo } if {![info exists _email_to]} { set result \ "Policy cannot be run: variabl _log _file ore _email_to has not been set" error $result $errorInfo } if {![info exists _email_cc]} { #_email_cc is an option, must set to empty string if not set. set _email_cc "" } }if {![info exists _show_cmd]} { set result \ "Policy cannot be run: variable _show_cmd has no t been set" error $result $errorInfo
203
} namespace import ::cisco::eem::* namespace import ::cisco::lib::* …snip… # 1. execute the command if [catch {cli_open} result] { error $result $errorInfo } else { array set cli1 $result } if [catch {cli_exec $cli1(fd) "en"} result] { error $result $errorInfo } # save exact execution time for command set time_now [clock seconds] # execute command if [catch {cli_exec $cli1(fd) $_show_cmd} result] { error $result $errorInfo } else { set cmd_output $result # format output: remove trailing router prompt set prompt [format "(.*\n)(%s)(\\(config\[^\n\]*\\))?(#|>)" $routernam e] if [regexp "[set prompt]" $result dummy cmd_outpu t] { # do nothing, match will be in $cmd_output } else { # did not match router prompt so use original output set cmd_output $result } } if [catch {cli_close $cli1(fd) $cli1(tty_id)} resul t] { error $result $errorInfo } # 2. log the success of the CLI command set msg [format "Command \"%s\" executed successful ly" $_show_cmd] action_syslog priority info msg $msg if {$_cerrno != 0} { set result [format "component=%s; subsys err=%s; posix err=%s;\n%s" \ $_cerr_sub_num $_cerr_sub_err $_cerr_posix_err $_cerr_str] error $result } # 3. if _log_file is defined, then attach it to the file if {[info exists _log_file]} { # attach output to file if [catch {open $_log_file a+} result] { error $result } set fileD $result # save timestamp of command execution
204
# (Format = 00:53:44 PDT Mon May 02 2005) set time_now [clock format $time_now -format "%T %Z %a %b %d %Y"] puts $fileD "%%% Timestamp = $time_now" puts $fileD $cmd_output close $fileD } # 4. if _email_server is defined send the email out if {[info exists _email_server]} { if {[string match "" $routername]} { error "Host name is not configured" } if [catch {smtp_subst [file join $tcl_library email_template_cmd.tm]} \ result] { error $result $errorInfo } if [catch {smtp_send_email $result} result] { er ror $result $errorInfo } }
Figura 134 - Cisco EEM: tm_cli_cmd.tcl
Come si evince dai commenti questa policy
esegue periodicamente un comando CLI e ne invia i
risultati via email oppure li memorizza in un file. Vediamo come utilizzarla nel caso piu' semplice.
Dobbiamo innanzitutto inizializzare le variabili "_cron_entry" e "_log_file" e "_show_cmd" con dei
valori.
Per inizializzare le variabili bisogna utilizzare il
comando "event manager environment {variabile} {valore}". Con il comando "show
event manager environment all" e' possibile verificare i valori di tutte le variabili inserite. Il cron
si aspetta nell'ordine: minuti, ore, giorno del mese, mese, giorno della settimana. Per la ripetizione si
usa lo "/" e per gli intervalli il "-". Per eseguire lo script ogni 10 minuti inseriamo "*/10 * * * *".
205
Con il comando "event manager policy
{nomepolicy} type system" registriamo la policy che cosi' viene resa utilizzabile dal sistema. Se si
vuole attivare il debug per EEM utilizzare il comando "debug event manager all".
Nella figura che segue vediamo un esempio di
applicazione. Inizializziamo le variabili per far eseguire il comando "show run" e per inserirne
l'output nel file di nome "test.log".
GIA-7204(config)# event manager environment _cron_entry */10 * * * * GIA-7204(config)# event manager policy tm_cli_cmd.tcl type system GIA-7204(config)# event manager environment _log_file flash:/test.log giahouse#show event manager environment all No. Name Value 1 _log_file flash:/test.log 2 _ show_cmd show run 3 _cron_entry 0-59/5 * * * 4 ... GIA-7204# show event manager policy registered No. Class Type Event Type Trap Ti me Registered Secu Name 1 script system timer cron Off Sa t Dec 26 13:20:42 2009 none tm_cli_cmd.tcl name {crontimer2} cron entry {*/10 * * * *} nice 0 queue-priority normal maxrun 240.000 schedul er rp_primary
Figura 135 - Cisco EEM: registrazione delle policy
Riprenderemo la spiegazione di questo codice
Cisco piu’ avanti. Presentiamo adesso l'altra policy
fornita da Cisco che abbiamo attenzionato. Il suo nome e' sl_intf_down.tcl e monitorizza il syslog di
sistema inviando una email nel caso in cui appaia
206
un messaggio che fa match con una espressione
regolare indicata dall'utente. E' molto utile per monitorare lo stato delle interfacce.
Le policy che abbiamo visto sinora sono di
sistema ovvero fornite da Cisco. Non e' possibile modificare queste policy. Quello che si puo' fare e'
duplicarne il contenuto e quindi editarlo a piacimento.
EEM e gli script TCL creati dall'utente
La prima cosa da fare quando si vogliono scrivere
script TCL e' definire nel router la directory dove questi verranno posizionati. Nella shell di Cisco sono
ormai presenti molti comandi simili a quelli della shell di Linux. Ad esempio si possono utilizzare i
comandi "mkdir" "rmdir" per creare o rimuovere una directory. E' possibile utilizzare "more" per
visualizzare su schermo un file di testo. E' anche possibile utilizzare "dir" e "cd". Per creare una
directory, nel caso in cui il nostro dispositivo di memorizzazione e' "flash:", procediamo come
indicato in figura.
giahouse#mkdir flash: Create directory filename []? mieitcl Created dir flash:mieitcl
Figura 136 - Creazione directory con il comando 'mkdir'
E' ora necessario impostare questa directory per l'uso con TCL con i comandi in figura.
207
giahouse(config)# event manager directory user library flash:/mieitcl giahouse(config)# event manager directory user policy flash:/mieitcl giahouse(config)#exit giahouse# show event manager directory user library flash:/mieitcl giahouse# giahouse# show event manager directory user policy flash:/mieitcl giahouse#
Figura 137 - Cisco EEM: registrazione directory per gli
script
Adesso siamo pronti per la realizzazione dei
nostri script TCL. I nomi devono seguire le convenzioni Cisco. Ci limitiamo per adesso alla piu'
banale, ovvero tutti i file devono terminare con ".tcl".
Minicorso di TCL
Ovviamente non si puo' apprendere un linguaggio di programmazione in poche pagine. Per imparare il
TCL si rimanda ad un testo specifico. Questo paragrafo e' una buona traccia per comprenderne la
filosofia e i comandi principali.
Per poter inserire comandi TCL si deve entrare nella shell TCL di IOS. Si entra nella shell comandi
TCL con il comando "tclsh". Con il comando "tclsh {pathfile}" si esegue uno script TCL che puo'
208
trovarsi nel router oppure in una location esterna
(piu' avanti scenderemo nel dettaglio).
Nella shell tclsh potete inserire direttamente
comandi TCL e vederne subito i risultati in quanto si
tratta di un linguaggio interpretato. Per eseguire dei programmi completi TCL bisogna scriverli nel
proprio PC in quanto Cisco non ha un editor di testo embedded nel sistema operativo. Questo non
complica le cose in quanto e' possibile eseguire in tempo reale dei programmi TCL che sono esterni al
router e solo successivamente, dopo aver
completato tutti i test, e' possibile trasferire all'interno del router. E' possibile selezionare come
"pathfile" del comando tclsh una destinazione comprendente una delle seguenti parole chiave:
TFTP, FTP, TCP, SCP, HTTP, HTTPS. Per eseguire uno script gia' presente nel router bastera' digitare
"tclsh {script.tcl}".
Anche se TCL e' un linguaggio interpretato e' possibile caricare nel router degli script precompilati
oppure compilati. Questo e' utile ai fini della
sicurezza in quanto un codice precompilato non e' facilmente consultabile. E' disponibile gratuitamente
un compilatore TCL presso l'URL http://tclpro. sourceforge.net. Per conoscere quale versione di
TCL e' installata e i comandi disponibili si eseguono i comandi nella figura che segue.
209
giahouse(tcl)# info patchlevel 8.3.4 giahouse(tcl)# info commands tell socket subst open eof pwd glob list exec pid snmp_getone time eval lrange tcl_trace fblocked lse arch gets case lappend proc break variable llength retur n linsert snmp_getid error catch clock info split arr ay if log_user fconfigure concat join lreplace snmp_setan y source fcopy global switch snmp_getbulk update clos e cd for file append format udp_open read package set bi nary namespace scan verify_signature seek while flush af ter vwait snmp_getnext typeahead uplevel continue hostn ame ios_config foreach rename fileevent regexp upvar un set encoding expr load regsub interp history puts incr lindex lsort udp_peek string
Figura 138 - Cisco TCL - versione installata e comandi
disponibili -
Variabili TCL e I/O di base
TCL supporta sia tipi di dati numerici che
stringhe. I tipi di dati stringa utilizzano i doppi apici
e non hanno limitazione in lunghezza (questa non e' una considerazione secondaria in quanto in un tipo
stringa spesso inseriremo l'output di comandi di IOS che puo' essere piuttosto lungo). Con il comando
"set" si assegnano dei valori alle variabili mentre con il comando "puts" si visualizza sullo schermo
un messaggio oppure il valore di una variabile. Con il comando "expr" si utilizzano i valori delle variabili
che possono essere elaborati, ad esempio con operazioni aritmetiche in caso di valori numerici.
Esistono anche gli array che si definiscono utilizzando le parentesi tonde. Poi vi sono varie
funzioni di elaborazione delle stringhe, come
"match" o "lenght" che ci permettono di trovare
210
una sottostringa oppure determinare la lunghezza.
La figura mostra un’applicazione di quanto detto.
giahouse(tcl)#set miavar1 5 5 giahouse(tcl)#set miavar2 6 6 giahouse(tcl)#puts $miavar1 5 giahouse(tcl)#info exists miavar2 1 giahouse(tcl)#puts $miavar1+$miavar2 5+6 giahouse(tcl)#expr {$miavar1+$miavar2} 11 giahouse(tcl)#puts [expr {$miavar1+$miavar2}] 11 giahouse(tcl)#puts "ciao [expr {$miavar1+$miavar2}] " ciao 11 giahouse(tcl)#puts "Prima riga \nSeconda riga" Prima riga Seconda riga giahouse(tcl)#puts "\t Colonna 1 \t Colonna2" Colonna 1 Colonna2 giahouse(tcl)#set b(1) 1 1 giahouse(tcl)#set b(2) 2 2 giahouse(tcl)#set b(3) 3 3 giahouse(tcl)#set miafrase "casa cisco router inter net" casa cisco router internet giahouse(tcl)#string match cisco $miafrase 0 giahouse(tcl)#string match *cisco* $miafrase 1 giahouse(tcl)#string match *cisbo* $miafrase 0 giahouse(tcl)#string length $miafrase 26
Figura 139 - Cisco TCL - Variabili -
I commenti si inseriscono con "#" a inizio riga.
211
File
La gestione dei file ci permette di creare dei file
di testo inserendone o leggendone dei valori. Se non indicato altrimenti questi file vengono inseriti
nel device di default che in genere e' "flash:". Un file si crea o si apre con il comando "open"
indicando per la lettura la lettera "w" oppure per la scrittura la lettera "r". Con il comando "puts" e'
possibile inserire dati e con "close" chiudere il file. Segue un esempio.
giahouse(tcl)#set miofile [ open "filetesto1" w] file0 giahouse(tcl)#puts $miofile "prova" giahouse(tcl)#close $miofile giahouse(tcl)#more flash:/filetesto1 prova giahouse(tcl)#set miofile [ open "filetesto1" r] file0 giahouse(tcl)#gets $miofile prova giahouse(tcl)#close $miofile
Figura 140 - Cisco TCL - Gestione file -
Espressioni regolari
Dovete imparare bene l'utilizzo delle espressioni
regolari se volete poter scrivere degli script utili con
IOS. Infatti molto spesso uno script legge l'output di comandi di IOS alla ricerca di dati o valori ben
precisi. Per fare questo si utilizzano le espressioni regolari. Nella figura che segue, assegnata una
stringa di testo estraiamo alcuni valori utilizzando delle espressioni regolari. Si utilizza il comando
212
"regexp" che si aspetta in input la stringa su cui
effettuare la ricerca e poi una seconda variabile in cui memorizzare il risultato. Il comando restituisce
anche l'esito dell'operazione ovvero "1" nel caso in cui abbia trovato un match, "0" in caso contrario.
Con ".*" si intende una qualsiasi sequenza di testo o numeri, con "[0-9]" si intende una singola cifra,
con "[0-9]+" si intende una sequenza di cifre. Il valore "\" indica di non interpretare il carattere
successivo, nel caso in cui si crei un'ambiguita' perche' quel carattere e' anche un comando di
espressione regolare.
giahouse(tcl)#set stringa "L'indirizzo IP e' 192.168.30.10" L'indirizzo IP e' 192.168.30.10 giahouse(tcl)#regexp {IP.*} $stringa risultato 1 giahouse(tcl)#puts $risultato IP e' 192.168.30.10 giahouse(tcl)#set ris [regexp {[0-9]} $stringa risu ltato] 1 giahouse(tcl)#puts $risultato 1 giahouse(tcl)#set ris [regexp {[0-9]+} $stringa ris ultato] 1 giahouse(tcl)#puts $risultato 192 giahouse(tcl)#regexp {[0-9]+\.[0-9]+} $stringa risu ltato 1 giahouse(tcl)#puts $risultato 192.168
Figura 141 - Cisco TCL - Espressioni regolari -
Gestione errori
Con il comando "catch" possiamo intercettare le condizioni di errore. Nell'esempio che segue
213
inseriamo nella variabile "risultato" la
configurazione del router. In una ipotesi di errore questo viene catturato e inserito nella variabile
"errore" e quindi puo' essere gestito all'interno del codice.
giahouse(tcl)#if {[ catch {set risultato [exec {show run}]} errore]} { puts "Errore: $e" }
Figura 142 - Cisco TCL - Comando 'catch' -
Se invece di "show run" avessimo utilizzato un
comando non presente nella versione di IOS in uso oppure un comando improprio avremmo potuto
gestire l’errore. Se riprendiamo il file TCL di
esempio tm_cli_cmd.tcl presentato nei paragrafi precedenti osserviamo l'utilizzo del comando
"catch" ad ogni esecuzione di un comando per intercettare una condizione di errore.
Procedure
Come in tutti i linguaggi di programmazione e'
possibile scrivere subroutine da chiamare nel
codice. Nella figura 143 si mostra una subroutine che effettua la moltiplicazione di due valori numerici
e ne restituisce il risultato.
214
gia(tcl)#proc moltiplica {var1 var2} { +>set x [expr {$var1 * $var2}] +>return $x +>} gia(tcl)#puts [moltiplica 2 3] 6
Figura 143 - Cisco TCL - Procedure -
Cicli
Anche in questo caso si tratta dei soliti comandi
presenti praticamente in ogni linguaggio di
programmazione, con una sintassi differente, ovvero gli onnipresenti "for" e "while".
gian(tcl)#for {set i 0 } { $i <= 20} {incr i} {puts $i} 0 ... 20 gian(tcl)#set x 10 gian(tcl)#while {$x < 12} { +>puts $x +>set x [expr {$x +1}] +>} 10 11
Figura 144 - Cisco TCL - Cicli -
Espressioni condizionali
Si utilizzano i comandi "if...then...else" e "switch"
come in figura.
215
gia(tcl)#if {$x == 2} {puts "vale 2"} else {puts "v ale 3"} gia(tcl)#if {$x != 3} {puts "ciao"} gia(tcl)#set x 20 gia(tcl)#switch $x { +>"10" { puts "dieci"} +>"20" { puts "venti"} +>}
Figura 145 - Cisco TCL - Espressioni condizionali -
Esecuzione comandi IOS
Dall'interno degli script TCL e' possibile eseguire
un qualsiasi comando IOS. Questo da grandi
potenzialita' ai nostri script che hanno piena visibilita' della configurazione del router e possono
modificarla a piacimento. Con le istruzioni "exec {comando}" e "ios_config {comando1}
{comando2}" e' possibile eseguire comandi in modalita' privilegiata oppure in modalita'
configurazione. L'uso di piu' comandi in ios_config potrebbe essere utilizzato per configurare le
subinterface, ad esempio.
giahouse(tcl)#exec "show ver | include ATM" 1 ATM interface giahouse(tcl)#ios_config "hostname prova" prova(tcl)#ios_config "hostname giahouse" giahouse(tcl)# giahouse(tcl)#ios_config "int atm0" "description -- rete 1 ---"
Figura 146 - Cisco TCL - Esecuzione comandi CLI –
216
Socket
Sappiamo che i socket sono degli endpoint per la
comunicazione IP. Un socket e' caratterizzato da un indirizzo IP e da una porta e permette la
comunicazione tra dispositivi presenti in una rete TCP/IP. Qualunque programma del nostro PC che si
interfaccia con la rete IP utilizza i socket: browser http, client di posta, client FTP, programmi di
comunicazione come quelli di chat, voip, peer-to-peer.
Ogni linguaggio di programmazione che si rispetti
permette di creare socket per permettere la
comunicazione tra processi presenti nello stesso o in PC differenti tramite il protocollo IP.
Molti virus, trojan e quant'altro utilizzano i
socket. Un socket infatti apre il nostro PC a comuni-cazioni verso l'esterno, e questo e' sconosciuto ai
comuni utenti Internet. E' possibile utilizzare i
socket in TCL? La risposta e' affermativa. Lo strumento e' potente e pericoloso. Roba tosta,
ragazzi.
Per capire come funzionano i socket, e divertirci
allo stesso tempo, creiamo una backdoor nel nostro
router, utile come accesso di emergenza.
Osserviamo il codice in figura 147.
217
set port 1212 set miosock [socket -server miaprocedura $port] vwait attendi
Figura 147 - Cisco TCL - Socket - esempio parte 1 -
Il comando "socket" ci permette di creare un
endpoint TCP per la comunicazione. La sintassi "socket -server {funzione} {porta}" apre il
socket in ascolto nella porta indicata con 'porta', ovvero crea il lato server di una comunicazione con
uno o piu' client. Nel caso dell'esempio non appena arrivera' una richiesta di connessione alla porta
1212 verra' automaticamente chiamata la funzione
'miaprocedura'. Dopo l'apertura di un socket viene rilasciato dal sistema un identificativo, inserito
nell'esempio nella variabile "miosock" con il quale e' possibile fare riferimento al socket durante tutto lo
script TCL.
Con il comando "vwait {var}" lo script entra in attesa finche' la variabile 'var' non viene modificata.
Senza quest'ultima condizione lo script non e' in grado di restare in ascolto. Entrare in attesa e'
fondamentale per poter accettare in qualsiasi
momento richieste esterne. Sara' nostra responsabilita' utilizzare la variabile al momento
giusto, cosi' da arrivare alla successiva istruzione 'close' dell'esempio, altrimenti il server restera' in
attesa indefinitivamente, cosa che pero' e' normalmente voluta.
218
Andiamo dunque alla seconda parte dell'esempio
ovvero la scrittura della procedura da avviare al momento in cui arriva una richiesta di connessione
dall'esterno.
# Occhio ai commenti, che siano a inizio riga # Occhio alle parentesi graffe, devono essere apert e nella # stessa riga dei comandi proc miaprocedura {sock indirizzoip porta} { puts "Debug: Connessione $sock accettata dall'indi rizzo $indirizzoip con porta $porta" fconfigure $sock -buffering line -translation lf # # Invia un messaggio al client # puts $sock "----------------------------" puts $sock "|- GF backdoor - welcome |" puts $sock "----------------------------" puts $sock "gf>" # # Legge un messaggio dal client # fileevent $sock readable [list leggi $sock] }
Figura 148 - Cisco TCL - Socket - esempio parte 2 -
Non appena arriva una richiesta esterna il
sistema chiama automaticamente la procedura
'miaprocedura' e questo perche' l'abbiamo istruito il tal modo con il comando 'socket'. Per facilitare la
fase di test dello script, visualizziamo sullo schermo un messaggio indicante l'avvenuta connessione da
parte di un client. A questo punto introduciamo il comando "fconfigure {socket}{parametri}" che
ci permette di impostare delle opzioni per un socket. Con '-buffering line' richiediamo una
trasmissione separata per ogni linea che termina con un newline. Detto in altri termini ogni comando
'puts' del nostro esempio inviera' un suo pachetto
219
IP. Con '-translation lf' definiamo il tipo di
'newline'. In questo caso con 'lf' intendiamo lo stile UNIX di utilizzare un singolo carattere di newline.
Con il comando "fileevent {sock} readable |
writable {script}" il sistema aggancia uno script ad un canale (tecnicamente file event handler).
Quando e' possibile leggere o scrivere dal canale il sistema utilizza lo script indicato. Nel nostro
esempio non appena il client invia qualche dato lo script chiama automaticamente la procedura 'leggi'
passando come parametro l'identificativo del
socket. L'uso del comando "list" che crea una lista, ovvero una sequenza di dati, serve per poter inviare
a fileevent il nome della procedura con tutti i suoi parametri correttamente. A questo punto ci manca
semplicemente la procedura per gestire le richieste del client.
proc leggi {sock} { if {[eof $sock] || [catch {gets $sock richiesta}] } { # situazione di anormalita', ad esempio cad uta connessione puts "Debug: condizione di errore nella let tura dal client rilevata" } else { set risposta[exec "$richiesta"] puts $sock "gf>" puts $sock $response # Termina la comunicazione con un client # L'applicazione TCL rimane in ascolto # Togliere questa riga per fare piu' interrogazioni al router in una unica # connessione close $sock } }
Figura 149 - Cisco TCL - Socket - esempio parte 3 -
220
E' necessario attenzionare la posizione delle
parentesi graffe negli script. Come avrete forse notato dai commenti le parentesi graffe vanno
aperte o chiuse nella stessa riga in cui si trova il comando associato. Intendo dire che "} else {"
non e' la stessa cosa di "else" con le parentesi in righe differenti. Per lo stesso motivo si scrive "if
{condizione} {" e non "if {condizione}" e la parentesi nella riga successiva. A questo punto
vorremmo lanciare questo script e testarlo. Lo script e' in grado di leggere messaggi da una porta
TCP. Cosa possiamo utilizzare come client? Utilizzeremo il comando "nc" presente nei sistemi
Linux e che consente di inviare facilmente dei dati tramite connessioni TCP/IP.
Colleghiamoci al router e lanciamo manualmente
lo script creato nel server FTP.
giahouse#tclsh ftp://itesys:[email protected]/CISCO_TCL/giaserv er.tcl Loading CISCO_TCL/giaserver.tcl ! [OK - 1076/4096 bytes]
Figura 150 - Cisco TCL: lancio di script da shell tcl
Da una postazione client Linux colleghiamoci al
router tramite la backdoor creata. Quindi lanciamo
un comando.
221
[root@radius1 ~]# nc 192.168.50.12 1213 ---------------------------- |- GF backdoor - welcome | ---------------------------- gf> show ver | include Cisco gf> Cisco IOS Software, C870 Software (C870-ADVIPSERVIC ESK9-M), Version 15.1(3)T, RELEASE SOFTWARE (fc1) Copyright (c) 1986-2010 by Cisco Systems, Inc. use. Delivery of Cisco cryptographic products does not imply A summary of U.S. laws governing Cisco cryptographi c products may be found at: Cisco 877 (MPC8272) processor (revision 2.0) with 2 36544K/25600K bytes of memory.
Figura 151 - Cisco TCL: Utilizzo comando linux 'nc' per
connessione a server
Come si vede e' possibile inviare comandi al
router e vedere le risposte senza utilizzare il telnet o l'ssh. Vediamo cosa succede se proviamo a
cambiare la configurazione del router tramite la backdoor.
[root@radius1 CISCO_TCL]# nc XX.XX.XX.XX 1213 ---------------------------- |- GF backdoor - welcome | ---------------------------- gf> conf t gf> % Configuration not allowed from TCL shell.Use
'ios_config' instead
Figura 152 - Cisco TCL: comandi di configurazione e
comando exec
Editando lo script opportunamente e' possibile
pertanto anche modificare la configurazione.
222
L'esempio e' molto istruttivo anche perche' ci
introduce a nuovi tipi di minacce alla sicurezza dei nostri router che prima non esistevano. E'
abbastanza ovvio che per inserire lo script TCL nel router bisogna averne prima l'accesso quindi non e'
il caso di allarmarsi eccessivamente.
Questo esempio ci suggerisce la possibilita’ per uno script TCL in esecuzione in un router di
collegarsi in telnet ad un secondo router e di interagire con esso con una sequenza di comandi.
Allora in caso di condizioni di guasto possiamo non
solo modificare la configurazione di un router A ma anche router esterni B e C che NON hanno supporto
TCL.
giahouse# tclsh ftp://itesys:[email protected]/CISCO_TCL/giaserv er.tcl Loading CISCO_TCL/giaserver.tcl ! [OK - 1060/4096 bytes] sock0_ipv4 couldn't open socket: address already in use while executing "socket -server miaprocedura $port" invoked from within "set miosock [socket -server miaprocedura $port]" (file "ftp://itesys:[email protected]/CISCO_TCL/giaser ver.tcl" line 33) giahouse# show processes cpu | include Tcl 48 44 21 2095 0.00% 0.00% 0.00% 2 Tcl Serv - tty2 giahouse# show users Line User Host(s) Idle Location 2 vty 0 gianrico idle 00:16:23 69it.itesys.it * 3 vty 1 gianrico idle 00:00:00 69it.itesys.i t Interface User Mode Idle Peer Addres s
Figura 153 - Cisco TCL: controllo script in esecuzione
223
Tornando al nostro esempio si puo' osservare che
lo script lanciato da TCL sembra instoppabile. Di fatto rimane in esecuzione. Se si apre una nuova
sessione con il router ecco mostrato in figura 153 come individuare gli script che sono in esecuzione
in background.
Secondo la documentazione con il comando "clear line" si dovrebbe poter stoppare l'esecu-
zione di uno script. Infatti non esiste un comando "kill" per fermare i processi come in Linux. Nel mio
caso ho dovuto riavviare il router tuttavia e'
probabile che dipenda dalla versione di IOS utilizzata nel lab. Approfitto per segnalare che gli
esempi riportati in questo libro sono legati a specifiche versioni di IOS la cui evoluzione e'
continua. Inoltre vi sono un numero notevole di versioni differenti ognuna con dei bug noti (basta
cercare nel sito cisco le keyword 'caveats release' per rendersene conto). Quindi per far funzionare
tutto bene nel vostro sistema potrebbero essere necessari degli aggiustamenti.
Namespace
I namespace sono collezioni di procedure e
variabili. Sono un po' come le classi in C. Permettono di creare librerie di funzioni che non
interferiscono con il codice esterno al namespace. Per esempio le variabili in un namespace possono
avere lo stesso nome di altre variabili in altri
namespace. Con il simbolo "::" ci si muove all'interno di una gerarchia di namespace. La root
224
della gerarchia e' il simbolo "::" posto inizialmente.
Sotto il namespace globale c'e' definito il namespace "cisco" che ha a sua volta il namespace
"eem" al suo interno.
Lo script tm_cli_cmd.tcl
Riprendiamo lo script di esempio mostrato nei
paragrafi precedenti per capire altri elementi di TCL specifici ai router Cisco.
- La prima riga di uno script TCL e' di
fondamentale importanza in quanto definisce quan-do lo script verra' eseguito. E' possibile schedulare
l'esecuzione di uno script un po' come si fa in ambiente linux utilizzando 'crontab'.
Nello script tm_cli_cmd.tcl la prima riga e' la
seguente:
::cisco::eem:: event_register_timer cron name crontimer2 cron_entry $_cron_entry maxrun 240
Figura 154 - Cisco TCL: schedulazione script TCL
Questa indica che lo script deve essere eseguito periodicamente in base a quanto indicato nella
variabile _cront_entry che e' prescelta dall'utente.
Con "maxrun" si indica al sistema il tempo massimo che puo' impiegare lo script per la sua esecuzione.
225
Se lo script non dev'essere schedulato si utilizza
'event_register_none' come in figura.
:cisco::eem:: event_register_none
Figura 155 - Cisco TCL: script non schedulato
- Le righe successive normalmente verificano che
l'utente abbia inserito un valore per le variabili richieste.
if![info exists _email_server]} { set result \ "Policy cannot be run: variable _email_server has not been set" error $result $errorInfo }
Figura 156 - TCL: verifica esistenza variabili
set par1 [lindex $argv 0] # primo parametro set par2 [lindex $argv 1] # secondo parametro
Figura 157 - Cisco TCL: passaggio parametri
- A questo punto incontriamo l'import dei
namespace relativi a eem e lib. Questo permette allo script di utilizzare le procedure presenti in
questi namespace. Si veda nel sito Cisco l'elenco completo. Nel prossimo script di esempio ne e'
presentata qualcuna.
226
namespace import ::cisco::eem::* namespace import ::cisco::lib::*
Figura 158 - TCL: 'namespace'
Ecco in figura un'applicazione che utilizza gli
ultimi concetti descritti. E’ derivata direttamente da
uno degli esempi messi a disposizione da Cisco con TCL in IOS.
:cisco::eem::event_register_none #'event_register_none' : # questa policy viene eseguita da cli quando si esegue il comando 'event manager run' # - Si puo' anche usare 'event_register_timer' # per indicare ogni quanto la policy dev'essere e seguita # - Si puo' anche usare 'event_register_syslog' # per fare eseguire la policy se nel syslog appar e un # certo messaggio per un certo numero di volte # - Si puo' anche usare 'event_register_ipsla' # per fare eseguire la policy in conseguenza ad u n # trigger 'ip sla' # - Si puo' anche usare 'event_register_inteface' # per far eseguire la policy se un contatore # in una interfaccia # supera una certa soglia # - Si puo' anche usare 'event_register_rpc' # per far eseguire la query da un sistema remoto tramite # SSH. # Vedi anche perl 'CISCO::EEM::RPC' # Vedi anche nel sito Cisco cerca "Writing Embedd ed Event Manager Policies Using Tcl". # # Questo script esegue una sequenza di comandi e ne # memorizza l'output in un file # namespace import ::cisco::eem::* namespace import ::cisco::lib::* # # Nella procedura che segue vedete delle funzioni p resenti # nel namespace. In particolare'cli_open' apre una vty, # cioe' una shell che e' poi importante chiudere # 'cli_close' alla fine del codice. # Fallisce se non ci sono almeno 3 vty libere proc CLICmdProc {cmds} {
227
if [catch {cli_open} result] { error $result $errorInfo } else { array set cli1 $result } # Si esegue il comando 'enable' if [catch {cli_exec $cli1(fd) "enable"} result] { error $result $errorInfo } # 'cli_exec' e' una procedura Cisco che esegue un c omando # di shell .Notate il comando "term lenght 0" che # disabilita la space bar per far # avanzare l'output dei comandi su schermo if [catch {cli_exec $cli1(fd) "term len 0"} resul t] { error $result $errorInfo } # In questo ciclo si eseguono i comandi richiesti foreach comando $cmds { if [catch {cli_exec $cli1(fd) $comando} resu lt] { error $result $errorInfo } else { lappend risultato $result } } if [catch {cli_close $cli1(fd) $cli1(tty_id)} res ult] { error $result $errorInfo } # Restituisce una lista contenente l'output return $risultato } # MAIN - INIZIO ESECUZIONE - # # Creiamo una lista di comandi: 'lappend' aggiunge un # elemento ad una lista lappend clicmd "show ip int brief" lappend clicmd "show tech" lappend clicmd "show clock" # Si eseguono i comandi. 'cliout' contiene il valor e # restituito dalla procedura set cliout [CLICmdProc $clicmd] # Il valore di 'cliout' viene memorizzato in un file set idfile [open "fileuscita" w+] foreach outs $cliout { puts $idfile $outs } close $idfile
Figura 159 - Esempio di script in TCL