Publish Date: September 18, 2015

Cisco IOS Embedded Event Manager

Cisco IOS Embedded Event Manager (EEM) is a powerful and flexible subsystem that provides real-time network event detection and onboard automation. It gives you the ability to adapt the behavior of your network devices to align with your business needs. It allows you to automate tasks, perform minor enhancements and create workarounds.

There are two independent pieces of EEM: Applets and Scripts

  • Applets are a collection of CLI commands
  • Scripts are actions coded up in TCL (Tool Command Language).

Embedded Event Manager (EEM) uses event detectors and actions to provide notifications of those events.

EEM detectors can be:

  1. SNMP : Monitoring SNMP objects.
  2. Syslog : Responds to various syslog messages, allowing for matching on regular expressions.
  3. Counter : Monitoring and responding to interface counter when cross threshold settings.
  4. CLI events : Screening CLI input for a regular expression match.
  5. None : This event detector is use to test EEM script/applet using “event manager run” command.
  6. Timers : Countdown, watchdog and CRON
  7. IP SLA and Netflows events.

Common Regular expressions:

^  =  Start of string
$  =  End of string
.   =  Any single character
*  =  Zero or more instances
+ =  One or more instance
?  =  Zero or one instance

EEM Actions can be:

  1. Sending a email messages
  2. Executing a CLI command
  3. Generating SNMP traps
  4. Reloading the router
  5. Generating prioritized Syslog messages
  6. Switching to a secondary processor in a redundant platform
  7. Requesting system information when an event occurs (like show tech, show proccess cpu history).

Sample EEM Scripts

1). Syslog Event Detector: The following example shows the syslog event detector. When the ISP1 interface has been shutdown, the below applet automatically runs to turn on the interface and send the alert to specific email address including logged in user information.

R2#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
R2(config)#event manager applet Intf_Management
R2(config-applet)#event syslog pattern "Interface FastEthernet0/0, changed state to administratively down"
R2(config-applet)#action 1.0 cli command "enable"
R2(config-applet)#action 2.0 cli command "config t"
R2(config-applet)#action 3.0 cli command "interface f0/0"
R2(config-applet)#action 4.0 cli command "no shutdown"
R2(config-applet)#action 5.0 cli command "end"
R2(config-applet)#action 6.0 cli command "who"
R2(config-applet)#action 7.0 mail server "mail.techtutsonline.com" to ".[email protected]." from "[email protected]." subject ".ISP1_Interface_fa0/0_SHUT." body "Current users $_cli_result"
R2(config-applet)#end
R2#

Now, I will enable the debug on R2 to get closer view of EEM. Then I will remotely login into Router R2 and shutdown the interface FastEthernet0/0 and see what happens.

R2#debug event manager action cli
Debug EEM action cli debugging is on
R2#debug event manager action mail
Debug EEM action mail debugging is on

I am now going to shutdown the interface FastEthernet0/0 from remote router. As soon as Shutdown command is issued on interface, you will see the following output on R2 router’s console:

*Sep 18 11:39:57.735: %LINK-5-CHANGED: Interface FastEthernet0/0, changed state to administratively down
*Sep 18 11:39:57.735: %ENTITY_ALARM-6-INFO: ASSERT INFO Fa0/0 Physical Port Administrative State Down
*Sep 18 11:39:57.755: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : CTL : cli_open called.
*Sep 18 11:39:57.855: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT :
*Sep 18 11:39:57.859: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT : R2>
*Sep 18 11:39:57.859: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : IN  : R2>enable
*Sep 18 11:39:57.875: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT :
*Sep 18 11:39:57.875: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT : R2#
*Sep 18 11:39:57.875: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : IN  : R2#config t
*Sep 18 11:39:57.891: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT :
*Sep 18 11:39:57.891: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT : Enter configuration commands, one per line.  End with CNTL/Z.
*Sep 18 11:39:57.891: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT : R2(config)#
*Sep 18 11:39:57.891: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : IN  : R2(config)#interface fa0/0
*Sep 18 11:39:57.907: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT :
*Sep 18 11:39:57.907: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT : R2(config-if)#
*Sep 18 11:39:57.911: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : IN  : R2(config-if)#no shutdown
*Sep 18 11:39:57.943: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT :
*Sep 18 11:39:57.943: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT : R2(config-if)#
*Sep 18 11:39:57.947: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : IN  : R2(config-if)#end
*Sep 18 11:39:57.955: %SYS-5-CONFIG_I: Configured from console by  on vty1 (EEM:Intf_Management)
*Sep 18 11:39:57.959: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT :
*Sep 18 11:39
R2#:57.959: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT : R2#
*Sep 18 11:39:57.959: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : IN  : R2#who
*Sep 18 11:39:57.979: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT :
*Sep 18 11:39:57.983: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT :     Line       User       Host(s)              Idle       Location
*Sep 18 11:39:57.983: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT :    0 con 0                idle                 00:00:09
*Sep 18 11:39:57.987: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT :    2 vty 0                idle                 00:00:02 202.164.42.1
*Sep 18 11:39:57.987: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT : *  3 vty 1                idle                 00:00:00 EEM:Intf_Management
*Sep 18 11:39:57.987: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT :
*Sep 18 11:39:57.991: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT :   I
Translating "mail.techtutsonline.com"

% Bad IP address for host mail.techtutsonline.comnterface    
*Sep 18 11:39:57.991: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT :
*Sep 18 11:39:57.991: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : OUT : R2#
*Sep 18 11:39:57.995: fh_policy_send_mail(): smtp connect attempt: 1
*Sep 18 11:39:57.999: fh_policy_send_mail(): fh_policy_smtp_connect failed at attempt 1
*Sep 18 11:39:59.923: %LINK-3-UPDOWN: Interface FastEthernet0/0, changed state to up
*Sep 18 11:39:59.923: %ENTITY_ALARM-6-INFO: CLEAR INFO Fa0/0 Physical Port Administrative State Down
R2#
*Sep 18 11:40:00.999: fh_policy_send_mail(): smtp connect attempt: 2
*Sep 18 11:40:00.999: fh_policy_send_mail(): fh_policy_smtp_connect failed at attempt 2
*Sep 18 11:40:10.015: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : IN  : R2#exit
*Sep 18 11:40:10.015: %HA_EM-6-LOG: Intf_Management : DEBUG(cli_lib) : : CTL : cli_close called.

Take a look at the CLI output. The interface is automatically re-enabled by EEM commands and it also tried to send an email to given address but my lab router is not connected to SMTP server which is located on internet. So, it could not send email. If your router is connected to internet, you can use this technique to automatically enable a critical interface of Cisco router or switch and it can also send an email to administrator.

2). CLI Event Detector: Every network administrator knows that debug command will heavily use the CPU and memory resources of device. If your production router is always busy doing some highly critical work, you do not want any user to be able to use debug command on router so that precious system resources can be utilized where they are really required. You want to setup a policy so that no user can use debug command on router.

The following example will create an applet to stop any user from enabling “debugging” command on the Cisco router. If anyone enter the debug command it will have no effect, and the clock and user’s information will be captured in flash to identify the offending user.

R2#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
R2(config)#event manager applet DENY_DEBUG
R2(config-applet)#event cli pattern "debug" sync no skip yes
R2(config-applet)#action 1.0 cli command "enable"
R2(config-applet)#action 2.0 cli command "show users | append flash:Debug"
R2(config-applet)#action 3.0 cli command "show clock | append flash:Debug_Clock"
R2(config-applet)#end

To view the registered policies on router R2, you can use the following command:

R2#show event manager policy registered
No.  Class   Type    Event Type          Trap  Time Registered           Name
1    applet  user    cli                 Off   Fri Sep 18 12:15:15 2015  DENY_DEBUG
 pattern {debug} sync no skip yes
 action 1.0 cli command "enable"
 action 2.0 cli command "show users | append disk0:Debug"
 action 3.0 cli command "show clock | append disk0:Debug_Clock"

To verify if our policy is working, I will remotely login into router R2 and try to run debug ip packet detail command. This command will eat up more CPU cycles.

GW1#telnet 202.164.42.10
Trying 202.164.42.10 ... Open

User Access Verification

Password:
R2>en
Password:
R2#debug ip packet detail
R2#
R2#show debugging
R2#

When I used show debugging, nothing is displayed because, the debug ip packet detail command is not run; it is skipped by our EEM policy.

Let’s check if something has been captured on router’s flash. Use show flash command to list the contents of flash:

R2#show flash:
-#- --length-- -----date/time------ path
1          676 Sep 18 2015 12:19:58 +00:00 Debug
2           70 Sep 18 2015 12:19:58 +00:00 Debug_Clock
3     17793652 Sep 15 2015 02:57:38 +10:00 c1841-advsecurityk9-mz.124-3g.bin

[output cut]

If you see Debug and Debug_Clock files in flash, it means policy is successfully doing its job. You can read the contents of these files using more command as shown below:

R2#more flash:Debug
    Line       User       Host(s)              Idle       Location
   0 con 0                idle                 00:03:26
   2 vty 0     helpdesk   idle                 00:00:00 202.164.42.1
*  3 vty 1                idle                 00:00:00 EEM:DENY_DEBUG

  Interface    User               Mode         Idle     Peer Address

    Line       User       Host(s)              Idle       Location
   0 con 0                idle                 00:03:36
   2 vty 0     helpdesk   idle                 00:00:00 202.164.42.1
*  3 vty 1                idle                 00:00:00 EEM:DENY_DEBUG

R2#more flash:Debug_clock
*12:19:48.531 UTC Fri Sep 18 2015

*12:19:59.211 UTC Fri Sep 18 2015

Here you can see the name of user who violated your policy is “helpdesk” and the date/time when the he entered debug command.

3). TCL Script: TCL (Tool Control Language) is a scripting language which can be used to facilitate the testing and automating of various functions in the Cisco IOS. Cisco IOS gives you ping command which can help you test the connectivity to remote host. But you can not ping multiple hosts in a single command in router. If you want to ping multiple hosts in a single command, you can create a TCL script for this.

In the following example, I am going to create a multi-ping.tcl script on my PC and then I will copy multi-ping.tcl file to router using TFTP server and configure the router to use the script.

Writing the script:

You can use any text editor of your choice like notepad, notepad++. If you are use using Linux, you can use nano or even vim editor. The important thing to remember is that the file should be saved with .tcl extension. To prevent any typo, I recommend you to copy and paste the following text to your editor and save the file with multi-ping.tcl name.

proc multi-ping { iplist } {
      foreach ip $iplist {
        if { [regexp "(!!!)" [exec "ping $ip timeout 1" ]] } {
          puts "Ping to $ip Successful"
        } else { puts "Ping to $ip Failed" }
      }
    }

You do not need to change anything in above code. This will work for you by default.

Transfer the Script to Router:

Once you have create the multi-ping.tcl file, copy this file from your PC to router using TFTP server. You can download tftpd32 from here and install it to your PC. After installing tftpd32, copy the multi-ping.tcl file to the same location where tftpd32.exe is located. Then copy the script to router as shown below:

R2#copy tftp:multi-ping.tcl flash:
Address or name of remote host []? 192.168.10.10
Destination filename [multi-ping.tcl]?
Accessing tftp://192.168.10.10/multi-ping.tcl...
!!!!!!!!!!!!!!!
[OK - 240 bytes]

Now you can confirm that the script is successfully copied to router’s flash using show flash command.

R2#show flash: 
-#- --length-- -----date/time------ path
1     17793652 Jul 22 2007 02:57:38 +10:00 c1841-advsecurityk9-mz.124-3g.bin
2         201 Sep 18 2015 19:27:10 +10:00 multi-ping.tcl

Configure Router to Use the Script:

To configure your router to use multi-ping.tcl script, all you have to do is enter into global configuration mode and then run the following command:

R2#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
R2(config)#scripting tcl init flash:multi-ping.tcl.
R2(config)#end

Testing the script:

Now, this is time to test the multi-ping script. Enter the multiple remote IP or host names you want to ping as shown below:

R2#tclsh 
R2(tcl)#multi-ping {8.8.8.8 4.4.4.4 techtutsonline.com cisco.com microsoft.com}
Ping to 8.8.8.8 Successful
Ping to 4.4.4.4 Failed
Ping to techtutsonline.com Successful
Ping to cisco.com Successful
Ping to microsoft.com Failed

R2(tcl)#tclquit
R2#

This is just the beginning of what you can do with Embedded Event Manager and TCL scripting. Once you start understanding the basics of EEM, you can take the full advantage of EEM and TCL Scripts to change the behavior of your network devices to align with your business needs.

Back

 



Microsoft Certified | Cisco Certified