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.

169

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' automaticamente 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
170

tempo reale ed intervenire automaticamente con delle azioni in conseguenza al verificarsi di determinati 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' necessario 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
171

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"

172

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 GigabitEthernet0/1 timeout 20 frequency 70 ip sla schedule 10 life forever start-time now ip sla reaction-configuration 10 react connectionLoss thresholdtype 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 preceden173

te vediamo come verificare che lo SLA sia correttamente 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 if randomly scheduled) Next Scheduled Start Time: Start Time already passed 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 react 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'

174

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 reactionconfiguration' 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
175

comandi monitoriamo servizio ftp:

la

raggiungibilita'

di

un

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 generazione 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
176

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 10 interface ATM0/3/0

Parameter line-protocol

Value Last Change 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:

177

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 interface 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 delay expired 000935: Jan 20 16:12:29.079: Track: 10 Change #5 interface 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'

178

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 versioni !oppure "track 50 rtr 10" in vecchie

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 irraggiungibile, 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.

179

*Jan 20 16:26:16.532: IP SLAs(10) saaSchedulerEventWakeup *Jan 20 16:26:16.532: IP SLAs(10) operation *Jan 20 16:26:16.532: IP SLAs(10) http operation *Jan 20 16:26:16.532: IP SLAs(10) dns operation *Jan 20 16:26:16.532: IP SLAs(10) - www.itesys.it *Jan 20 16:26:16.532: IP SLAs(10) server - 151.99.125.2 *Jan 20 16:26:16.532: IP SLAs(10) target queried = www.itesys.it *Jan 20 16:26:16.616: IP SLAs(10) return code - no error *Jan 20 16:26:16.616: IP SLAs(10) Address 82.85.14.71 *Jan 20 16:26:16.616: IP SLAs(10) *Jan 20 16:26:16.760: IP SLAs(10) 18 bytes *Jan 20 16:26:16.760: IP SLAs(10) connection - connected *Jan 20 16:26:16.948: IP SLAs(10) first byte: 328 ms *Jan 20 16:26:16.948: IP SLAs(10) *Jan 20 16:26:16.948: IP SLAs(10)

Scheduler: Scheduler: Starting an http operation: Starting dns operation: Starting dns operation: Query name dns operation: Query name dns operation: actual dns operation: Query dns operation: received IP dns operation: RTT=87 http operation: Sent 18 of http operation: Wait http operation: Time to http operation: RTT=417 Scheduler: Updating 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 funzionante, magari con messaggi del tipo "service
180

unavailable". In questo caso per il router il sito web e' funzionante. Quindi il comando "http get" dell'esempio e' valido per verificare la raggiungibilita' 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
181

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 utilizzata 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'
182

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'.
183

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 -

184

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

185

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 interface outside num-packets 5 frequency 5 sla monitor schedule 123 life forever start-time now 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
186

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.

187

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
188

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 reactionconfiguration" 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, changed 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.255.255.0 1.1.1.1" action 4.0 mail server "192.85.14.73" to "gianrico@gianrico.com" from "ciscorouter26" subject "interfaccia down" body "attivato routing secondario"

Figura 126 - Cisco EEM: invio email in caso di evento

189

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
190

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' esecuzione 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 Secu Name 1 applet user syslog Off Thu Dec 30 15:01:09 none mioapplet pattern {Interface Ethernet 0/0, changed status to 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.255.255.0 1.1.1.1" action 1.3 mail server "192.85.14.73" to "gianrico@gianrico.com" from "cisco" subject "interfaccia 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 irraggiungibilita' 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
191

correttamente un disservizio in un collegamento Internet quindi questo applet e' di larga applicabilita'.

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.
192

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 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 19.16.4.1" action 4.0 cli command "exit" action 5.0 mail server "112.112.12.12" to "gianrico@prova.it" from "catalyst@gia.it" 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

193

event manager applet ErroreGrave event track 100 state down action 1.0 syslog msg "Errore grave, riavvio il router" 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' istruttiva con la presenza di due circuiti HDSL che
194

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-sharing --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

195

! 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 Dialer1 overload ip nat inside source route-map uscitaload1 interface Serial0/0/0.1 overload ip nat inside source route-map uscitaload2 interface Serial0/0/1.1 overload ! access-list 10 remark -- classi di IP sorgenti per HDSL --

196

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

197

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

198

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: ADSLDOWN 2 Fri Jan 8 08:47:25 2010 track applet: ADSLUP 3 Fri Jan 8 13:53:37 2010 track applet: ADSLDOWN 4 Fri Jan 8 13:54:28 2010 track applet: ADSLUP 5 Fri Jan 8 16:18:33 2010 track applet: DUEHDSLDOWN 6 Fri Jan 8 16:22:43 2010 track applet: DUEHDSLUP 7 Fri Jan 8 16:24:08 2010 track applet: DUEHDSLDOWN 8 Fri Jan 8 16:28:43 2010 track applet: DUEHDSLUP 9 Fri Jan 8 16:40:03 2010 track applet: DUEHDSLDOWN 10 Fri Jan 8 16:47:48 2010 track applet: DUEHDSLUP gianricotest#show ip route track-table ip route 0.0.0.0 0.0.0.0 Serial0/0/0.1 track 10 state is [up] ip route 0.0.0.0 0.0.0.0 Serial0/0/1.1 track 11 state is [up]

Figura 132 - Esempio di configurazione EEM + SLA

199

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" possiamo vedere quali policy sono installate nel nostro router.
giahouse#show event manager No. Type Time Created Name 1 system Mon Feb 7 07:28:15 2 system Mon Feb 7 07:28:15 3 system Mon Feb 7 07:28:15 4 system Mon Feb 7 07:28:15 5 system Mon Feb 7 07:28:15 6 system Mon Feb 7 07:28:15 7 system Mon Feb 7 07:28:15 policy available 2036 2036 2036 2036 2036 2036 2036 ap_perf_test_base_cpu.tcl cl_show_eem_tech.tcl no_perf_test_init.tcl sl_intf_down.tcl tm_cli_cmd.tcl tm_crash_reporter.tcl tm_fsys_usage.tcl

Figura 133 - Cisco EEM: script TCL preinstallati

200

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 command # 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 to. ### If this variable is defined, the ### output is appended to the specified ### file with a timestamp added. ### Example: _log_file disk0:/my_file.log ### ### _email_server (mandatory without _log_file)

201

### - A Simple Mail Transfer Protocol (SMTP) ### mail server used to send e-mail. ### Example: _email_server mailserver.customer.com ### ### _email_from (mandatory without _log_file) ### - The address from which e-mail is sent. ### Example: _email_from devtest@customer.com ### ### _email_to (mandatory without _log_file) ### - The address to which e-mail is sent. ### Example: _email_to engineering@customer.com ### ### _email_cc (optional)- The address to which the e-mail ### must be copied. ### Example: _email_cc manager@customer.com ### ### _show_cmd (mandatory) - The CLI command to be executed ### when the policy is run. ### Example: _show_cmd show version ### # 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 _log_file or _email_server has not been set" error $result $errorInfo } if {![info exists _email_from]} { set result \ "Policy cannot be run: variable _log_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 not been set" error $result $errorInfo

202

} 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\]*\\))?(#|>)" $routername] if [regexp "[set prompt]" $result dummy cmd_output] { # 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)} result] { error $result $errorInfo } # 2. log the success of the CLI command set msg [format "Command \"%s\" executed successfully" $_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

203

# (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] { error $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 * * * *".
204

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 Time Registered Secu Name 1 script system timer cron Off Sat Dec 26 13:20:42 2009 none tm_cli_cmd.tcl name {crontimer2} cron entry {*/10 * * * *} nice 0 queue-priority normal maxrun 240.000 scheduler 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
205

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.
206

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'

207

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.

208

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 lsearch gets case lappend proc break variable llength return linsert snmp_getid error catch clock info split array if log_user fconfigure concat join lreplace snmp_setany source fcopy global switch snmp_getbulk update close cd for file append format udp_open read package set binary namespace scan verify_signature seek while flush after vwait snmp_getnext typeahead uplevel continue hostname ios_config foreach rename fileevent regexp upvar unset 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
209

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 internet" 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.

210

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
211

"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 risultato] 1 giahouse(tcl)#puts $risultato 1 giahouse(tcl)#set ris [regexp {[0-9]+} $stringa risultato] 1 giahouse(tcl)#puts $risultato 192 giahouse(tcl)#regexp {[0-9]+\.[0-9]+} $stringa risultato 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
212

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.

213

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.

214

gia(tcl)#if {$x == 2} {puts "vale 2"} else {puts "vale 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 –

215

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-topeer.

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 comunicazioni 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.

216

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.

217

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 aperte nella # stessa riga dei comandi proc miaprocedura {sock indirizzoip porta} { puts "Debug: Connessione $sock accettata dall'indirizzo $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
218

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 caduta connessione puts "Debug: condizione di errore nella lettura 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 -

219

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:itesys@192.168.14.70/CISCO_TCL/giaserver.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.

220

[root@radius1 ~]# nc 192.168.50.12 1213 ---------------------------|- GF backdoor - welcome | ---------------------------gf> show ver | include Cisco gf> Cisco IOS Software, C870 Software (C870-ADVIPSERVICESK9-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 cryptographic products may be found at: Cisco 877 (MPC8272) processor (revision 2.0) with 236544K/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.
221

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:it7jhd@192.168.14.70/CISCO_TCL/giaserver.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:itesys75@82.85.14.70/CISCO_TCL/giaserver.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.it Interface User Mode Idle Peer Address

Figura 153 - Cisco TCL: controllo script in esecuzione
222

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'esecuzione 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
223

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 quando 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.

224

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.

225

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 eseguita # - Si puo' anche usare 'event_register_syslog' # per fare eseguire la policy se nel syslog appare un # certo messaggio per un certo numero di volte # - Si puo' anche usare 'event_register_ipsla' # per fare eseguire la policy in conseguenza ad un # 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 Embedded 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 presenti # 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} {

226

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 comando # 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"} result] { error $result $errorInfo } # In questo ciclo si eseguono i comandi richiesti foreach comando $cmds { if [catch {cli_exec $cli1(fd) $comando} result] { error $result $errorInfo } else { lappend risultato $result } } if [catch {cli_close $cli1(fd) $cli1(tty_id)} result] { 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 valore # 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
227

Sign up to vote on this title
UsefulNot useful