domingo, 14 de febrero de 2010
EEM, Show CPU
Como continuación de lo visto en Embedded Event Manager (EEM), en esta ocasión se verá el uso de otras funciones que permitirán manipular valores del output de un comando. En particular se utilizarán:
- action set (EEM)
- action cli
- action foreach
- action regexp
- action if
- action append
- action subtract
- action end
- action puts
event manager applet CPU
event none sync yes
action 001 set first "0"
action 003 set third "0"
action 010 cli command "enable"
action 011 cli command "show processes cpu sorted 5sec | exclude 0.00% 0.00% 0.00% "
action 020 foreach line "$_cli_result" "\n"
action 030 regexp "([0-9]+)(%/)([0-9]+)" "$line" all first second third
action 031 if $_regexp_result eq 1
action 032 append output "Average total CPU utilization during last five seconds: $first \n"
action 033 append output "Average CPU utilization due to interrupts, during last five seconds: $third \n"
action 034 subtract $first $third
action 035 append output "Average CPU utilization due to processes, during last five seconds: $_result \n"
action 036 end
action 040 regexp "(one minute:) ([0-9]+)" "$line" all first second
action 041 if $_regexp_result eq 1
action 044 append output "Average total CPU utilization during last minute: $second \n"
action 045 end
action 050 regexp "(five minutes:) ([0-9]+)" "$line" all first second
action 051 if $_regexp_result eq 1
action 054 append output "Average total CPU utilization during last five minutes: $second \n\n"
action 073 else
action 074 regexp "#" "$line"
action 075 if $_regexp_result eq 0
action 076 append output "$line"
action 078 end
action 079 end
action 080 end
action 090 puts "$output"
Básicamente se señala que para el applet CPU no será gatillado por un evento en particular (event none) si no más bien deberá ser corrido con event manager run en la línea de comandos (CLI).
Luego se inicializan los valores de las variables $first y $third en 0 con set puesto que serán utilizadas para una operación matemática más adelante.
Con cli command se entra en modo proviligediado y se ejecuta show processes cpu ordenando los procesos de acuerdo a su porcentaje los últimos 5 segundos (sorted 5sec) y se exluyen aquellos que no han visto actividad en los últimos 5 minutos.
Luego se entra en un ciclo con foreach para cada línea (almacenada ahora en la variable $line) del comando ejecutado cuyo output se encuentra en la variable $_cli_result. La fragmentación por línea es básicamente por que eso se especificó como caracter delimitador, el salto de línea; "\n".
Las líneas ($line) serán examinadas con expresiones regulares con regexp para obtener algunos valores. Si existe match, la variable $_regexp_result tomará el valor de 1, de lo contrario 0. regexp permite extraer múltiples valores por línea al realizar la separación de los fragmentos con paréntesis como por ejemplo en; regexp "(one minute:) ([0-9]+)" "$line" all first second se busca la línea tenga la frase "one minute:" y a continuación un número. La variable $all toma el valor del fragmento completo, $first en este caso será sólo "one minute:" y $second el valor de interés que es variable.
Con los valores extraídos se pueden realizar operaciones matemáticas tales como subtract y add, el resultado es almacenado en la variable $_result.
Por último se va construyendo una variable ($output) a la que se agregan distintos fragmentos con append. Finalmente esta variable puede ser utilizada para diversos propósito, mandarla como contenido en un email (action mail) o simplemente imprimirla en pantalla con puts como este caso.
R2#event manager run CPU
Average total CPU utilization during last five seconds: 30
Average CPU utilization due to interrupts, during last five seconds: 3
Average CPU utilization due to processes, during last five seconds: 27
Average total CPU utilization during last minute: 28
Average total CPU utilization during last five minutes: 15
PID Runtime(ms) Invoked uSecs 5Sec 1Min 5Min TTY Process
115 64256 172013 373 25.35% 24.53% 12.67% 0 IP Input
5 179700 22573 7960 0.55% 0.11% 0.07% 0 Check heaps
3 6200 28980 213 0.55% 0.17% 0.06% 0 Exec
179 256 47353531 0 0.31% 0.34% 0.32% 0 HQF Shaper Backg
38 12 59730 0 0.07% 0.00% 0.00% 0 Net Background
2 24 37928 0 0.00% 0.03% 0.02% 0 Load Meter
9 5040 122375 41 0.00% 0.01% 0.00% 0 OSPF-1 Hello
42 8 189640 0 0.00% 0.01% 0.00% 0 Per-Second Jobs
52 63236 3175 19916 0.00% 0.01% 0.00% 0 Per-minute Jobs
180 20 1896064 0 0.00% 0.01% 0.00% 0 RBSCP Background
303 12 1896076 0 0.00% 0.01% 0.00% 0 FR Broadcast Out
viernes, 22 de enero de 2010
Router IP Traffic Export (RITE)
RITE se encarga de enviar una copia de ciertos paquetes IP a la MAC de un Sniffer o IDS conectado en una interface VLAN o LAN.
Su configuración se basa en sólo dos comando principales; ip traffic-export apply y ip traffic-export profile. Para troubleshooting; show ip traffic-export y debug ip traffic-export events.
R5#conf t
Enter configuration commands, one per line. End with CNTL/Z.
R5(config)#
R5(config)#ip traffic-export profile NOMBRE
R5(conf-rite)#?
IP traffic export profile configuration commands
bidirectional Enable bidirectional traffic export
exit Exit from ip traffic export profile sub mode
incoming Configure incoming IP traffic export
interface Specify outgoing interface for exporting traffic
mac-address Specify ethernet address of destination host
no Negate or set default values of a command
outgoing Configure outgoing IP traffic export
R5(conf-rite)#
lunes, 18 de enero de 2010
Embedded Event Manager (EEM)
Para entender esta poderosa herramienta que se podría decir está actualmente en desarrollo (Cisco IOS Release 12.3(4)T -> EEM 1.0, .... , 12.4(20)T -> EEM 2.4, 12.4(22)T -> EEM 3.0, 15.0(1)M -> EEM 3.1), hay que distinguir los dos tipos de políticas EEM (Embedded Event Manager Policies) que existen; estas son:
event manager applet EJEMPLO
event syslog pattern "CONFIG"
action 1.0 cli command "sh ver | i IOS"
action 2.0 puts "$_cli_result"
R5(config)#^Z
R5#
*Jan 18 18:18:15.783: %SYS-5-CONFIG_I: Configured from console by console
R5#
R5#
*Jan 18 18:18:15.827: %HA_EM-6-LOG: EJEMPLO: Cisco IOS Software, 2800 Software (C2800NM-ADVENTERPRISEK9-M), Version 12.4(24)T1, RELEASE SOFTWARE (fc3)
R5>
miércoles, 12 de agosto de 2009
TCL y SNMP en routers Cisco
TCL (Tool Command Language) es un lenguaje de programación cuya versión 8.3.4 puede ser ejecutada desde la línea de comandos (CLI) de un router Cisco, dependiendo eso si de la versión de IOS. Cisco documenta su uso en Cisco IOS Scripting with Tcl. Ivan Pepelnjak, por su parte, escribió un tutorial en Tclsh on Cisco IOS tutorial así como más de cincuenta posts al respecto en su blog.
Algunos comandos básicos son:
- tclsh: Para ingresar al modo interactivo de TCL (debe ser ejecutado en modo EXEC privilegiado)
- tclquit: Para salir al modo interactivo de TCL (debe ser ejecutado en modo EXEC privilegiado)
- exec: Ejecuta comando en modo EXEC.
- ios_config: Comandos en modo de configuración.
R3#tclsh
R3(tcl)#exec "show version | include IOS"
Cisco IOS Software, 7200 Software (C7200-ADVIPSERVICESK9-M), Version 12.4(22)T, RELEASE SOFTWARE (fc1)
R3(tcl)#ios_config "interface Loopback0" "shutdown"
R3(tcl)#
*Aug 11 12:31:00.645: %LINK-5-CHANGED: Interface Loopback0, changed state to administratively down
*Aug 11 12:31:01.645: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback0, changed state to down
R3(tcl)#exec "show interface Loopback 0 | include protocol"
Loopback0 is administratively down, line protocol is down
0 unknown protocol drops
R3(tcl)#tclquit
R3#
No se entrará en más detalles de cómo programar en TCL puesto que se escapa de nuestro propósito. Se recomienda revisar por ejemplo la definición de TCL en Wikipedia en Español, para descubrir herramientas que permitan generar scripts más interesantes. Por ejemplo para un sencillo chequeo de conectividad se puede utilizar un código como el que sigue:
tclsh
proc PingTest {} {
for {set i 2} {$i<5} {incr i} {
puts [ exec "ping 10.$i.$i.$i repeat 2"] }
}
Que aplicado genera:
R4#tclsh
R4(tcl)#proc PingTest {} {
+>(tcl)#for {set i 2} {$i<5} {incr i} {
+>(tcl)#puts [ exec "ping 10.$i.$i.$i repeat 2"] }
+>(tcl)#}
R4(tcl)#PingTest
Type escape sequence to abort.
Sending 2, 100-byte ICMP Echos to 10.2.2.2, timeout is 2 seconds:
!!
Success rate is 100 percent (2/2), round-trip min/avg/max = 36/82/128 ms
Type escape sequence to abort.
Sending 2, 100-byte ICMP Echos to 10.3.3.3, timeout is 2 seconds:
!!
Success rate is 100 percent (2/2), round-trip min/avg/max = 192/204/216 ms
Type escape sequence to abort.
Sending 2, 100-byte ICMP Echos to 10.4.4.4, timeout is 2 seconds:
!!
Success rate is 100 percent (2/2), round-trip min/avg/max = 4/4/4 ms
R4#
Para ejemplos más complejos se puede revisar el documento escrito por Peter J. Welcher; TCL'ing Your Cisco Router.
Antes de entrelazar este lenguaje y el protocolo SNMP (RFC 1157) se verá una pequeña introducción a los OID de éste. La configuración del protocolo en sí para permitir que los sistemas de administración recopilen datos del equipo se detalla en Configuring SNMP Support.
Un buen lugar para comenzar es OID assignments from the top node, donde se puede explorar el árbol de las MIBs que los OID identifican. La mayoría de las MIBs que se utilizan parten con .1.3.6.1.2.1 (SNMP MIB-2), que en palabras (y números) sería: .iso(1).org(3).dod(6).internet(1).mgmt(2).mib-2(1). Entre otras MIBs acá se encuentran:
1.3.6.1.2.1.1 - SNMP MIB-2 System
1.3.6.1.2.1.2 - SNMP MIB-2 Interfaces
1.3.6.1.2.1.3 - at
1.3.6.1.2.1.4 - ip
1.3.6.1.2.1.5 - icmp
1.3.6.1.2.1.6 - tcp
1.3.6.1.2.1.7 - udp
1.3.6.1.2.1.8 - egp
1.3.6.1.2.1.9 - cmot
1.3.6.1.2.1.10 - transmission
1.3.6.1.2.1.11 - snmp
1.3.6.1.2.1.14 - OSPF Version 2 MIB
1.3.6.1.2.1.15 - BGPv4
Además cada vendor publica sus propias MIBs específicas a partir de .1.3.6.1.4.1 (IANA-registered Private Enterprises) cuya asignación se puede revisar en: PRIVATE ENTERPRISE NUMBERS. Entres otras se tiene:
1.3.6.1.4.1.2 - IBM
1.3.6.1.4.1.9 - Cisco
1.3.6.1.4.1.1991 - Foundry Networks
1.3.6.1.4.1.2011 - Huawei-3Com
1.3.6.1.4.1.2636 - JuniperMIB
Entendiendo esto se puede añadir a los scripts de TCL información específica del equipo. A continuación un par de ejemplos sencillos. Primero veremos cómo obtener la utilización de CPU de nuestro router Cisco. En How to Collect CPU Utilization on Cisco IOS Devices Using SNMP se especifican los OID cpmCPUTotal1minRev (.1.3.6.1.4.1.9.9.109.1.1.1.1.7) y cpmCPUTotal5minRev (.1.3.6.1.4.1.9.9.109.1.1.1.1.8) para IOS 12.2(3.5) o posterior. Se obtendrán estos valores utilizando snmp_getnext.
router#sh proc cpu sort | e 0.00
CPU utilization for five seconds: 6%/2%; one minute: 6%; five minutes: 7%
PID Runtime(ms) Invoked uSecs 5Sec 1Min 5Min TTY Process
161 112248 327754883 0 1.06% 1.09% 1.13% 0 HQF Shaper Backg
190 1704 1854 919 0.90% 0.23% 0.24% 514 Virtual Exec
3 51154976 98581304 518 0.40% 0.63% 0.72% 0 Skinny Msg Serve
102 40918976 113690709 359 0.24% 0.35% 0.33% 0 IP Input
101 52780 578783459 0 0.16% 0.12% 0.09% 0 IP ARP Retry Age
95 56116 578783464 0 0.08% 0.11% 0.14% 0 ACCT Periodic Pr
2 10964 3715535 2 0.08% 0.04% 0.02% 0 Load Meter
19 6485540 24835008 261 0.08% 0.02% 0.01% 0 ARP Input
Gateway#tclsh
Gateway(tcl)#snmp_getnext SNMP 1.3.6.1.4.1.9.9.109.1.1.1.1.7
{<obj oid='cpmCPUTotalTable.1.7.1' val='6'/>}
Gateway(tcl)#snmp_getnext SNMP 1.3.6.1.4.1.9.9.109.1.1.1.1.8
{<obj oid='cpmCPUTotalTable.1.8.1' val='7'/>}
Gateway(tcl)#tclquit
Gateway#
A continuación un nuevo output utilizando snmp_getbulk.
R3(tcl)#$snmp_getbulk SNMP 1 14 1.3.6.1.2.1.2.1 1.3.6.1.2.1.2.2.1.2 1.3.6.1.2.1.2.2.1.8
{<obj oid="'ifNumber.0'" val="'14'/">}
{<obj oid="'ifDescr.1'" val="'FastEthernet0/0'/">}
{<obj oid="'ifOperStatus.1'" val="'2'/">}
{<obj oid="'ifDescr.2'" val="'Serial1/0'/">}
{<obj oid="'ifOperStatus.2'" val="'2'/">}
{<obj oid="'ifDescr.3'" val="'Serial1/1'/">}
{<obj oid="'ifOperStatus.3'" val="'1'/">}
{<obj oid="'ifDescr.4'" val="'Serial1/2'/">}
{<obj oid="'ifOperStatus.4'" val="'2'/">}
{<obj oid="'ifDescr.5'" val="'Serial1/3'/">}
{<obj oid="'ifOperStatus.5'" val="'2'/">}
...
El primer OID (1.3.6.1.2.1.2.1) corresponde a ifNumber que según la descripción del RFC 2863 corresponde a "The number of network interfaces (regardless of their current state) present on this system", que en nuestro caso son 14 (por eso se utilizó ese valor en los argumentos de snmp_getbulk). El segundo OID (1.3.6.1.2.1.2.2.1.2) corresponde a ifDescr y el tercero (1.3.6.1.2.1.2.2.1.8) a ifOperStatus. Si revisamos la definición (formato ASN.1) de este último en el RFC 2863 se tiene:
ifOperStatus OBJECT-TYPE
SYNTAX INTEGER {
up(1), -- ready to pass packets
down(2),
testing(3), -- in some test mode
unknown(4), -- status can not be determined
-- for some reason.
dormant(5),
notPresent(6), -- some component is missing
lowerLayerDown(7) -- down due to state of
-- lower-layer interface(s)
}
...
Por lo que del output anterior se tiene que la interface Serial1/1 está arriba (up).
Por último un par de comandos en Unix que pueden ser útiles para trabajar con SNMP; snmpwalk y snmptranslate.
nicolas@server:~$ snmpwalk -v1 -On -c SNMP X.X.X.X interfaces.ifTable.ifEntry.ifDescr
.1.3.6.1.2.1.2.2.1.2.1 = STRING: FastEthernet0/0
.1.3.6.1.2.1.2.2.1.2.2 = STRING: FastEthernet0/1
.1.3.6.1.2.1.2.2.1.2.3 = STRING: Null0
.1.3.6.1.2.1.2.2.1.2.4 = STRING: FastEthernet0/1.80-802.1Q vLAN subif
.1.3.6.1.2.1.2.2.1.2.5 = STRING: FastEthernet0/1.350-802.1Q vLAN subif
nicolas@server:~$ snmptranslate -Of .1.3.6.1.2.1.2.2.1.8
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifOperStatus