Python 100 project #31: Cisco IOS Login notification to Slack with EEM

It is best practice and most of the router console is only accessible from certain ip address. Usually it is both from the service provider and internal ip address. But time to time, some of internal staff tries to access the router. It’s still just a tedious problem if there is centralised management system(or any syslog actually) to check those activities. But it will be a problem if the deployment is distributed and not centralised. In this project, I used cisco EEM along with python script so that it posts into the channel if there is any login activities.

 

Output Example:

 

Here is the code:

this is relevant eem config in cisco router-

us-east-1_e-rtr-01#sh run | sec event manager
event manager applet login_success_post
 event syslog pattern "SEC_LOGIN-5-LOGIN_SUCCESS"
 action 0.0 cli command "en"
 action 1.0 regexp "([0-9]+\.[0-9]+\.[0-9]+\.[0-9])" "$_syslog_msg" match source_ip
 action 2.0 cli command "guestshell run python /bootflash/gs_scripts/login_post.py $_info_routername success $source_ip"

this is relevant script which is saved as /bootflash/gs_scripts/login_post.py in the router-

import sys

import requests

# from cred import token
token = ***

def post_slack(msg, channel, hostname):

    headers = {
        "Content-type": "application/json"
    }

    params = {
        "token": token,
        "text": msg,
        "channel": channel,
        "as_user": False,
        "username": hostname,
        "icon_emoji": ":cisco-rtr:"
    }

    url = "https://slack.com/api/chat.postMessage"

    resp = requests.post(url, params=params, headers=headers)

    return resp.status_code

if __name__ == "__main__":

    if len(sys.argv) != 4:
        print "usage: %s 'hostname' 'fail|success' 'source_ip_address'"
        sys.exit(0)

    post_slack('Login %s from %s' % (sys.argv[2], sys.argv[3]), "security_logs", sys.argv[1])