Collecting crypto VPN traffic info from Cisco routers


Cisco crypto site to site VPNs are quite useful but it is difficult to collect traffic stats when there is no virtual interface for SNMP to track. Instead the stats are held in the Cisco SNMP mibs in various places and you have to cross-reference between those places to work out which SNMP entry refers to which VPN tunnel. This gets harder the more tunnels you have from your router.

With this in mind I’ve created a WhatsUp performance monitor script to collect the traffic receive (rx) and transmit (tx) stats through SNMP. You’ll need to grab the Cisco router mibs and install them into the WhatsUp mibs directory first before this script will work.

On the Cisco side you’ll be setting up a vpnmap entry such as this one:

crypto map mymap 141 ipsec-isakmp set peer x.x.x.x set transform-set xxxx match address myvpn-acl 

The crypto map number is useful as this is how the script finds the correct VPN tunnel in SNMP:

'The remote peer
strVPNMapNumber="141"

The other variable to alter is whether the statistic to be collected is receive (rx) or transmit (tx) with respect to the router being polled. This is specified by this line:

' The direction of traffic (rx or tx)
strDirection="rx"

How the script works

The script gets a list of all the ipsec tunnels (get_ipsecTunnel_list) which is held at SNMP OID 1.3.6.1.4.1.9.9.172.1.2.1.1.3. It looks down the list for entries which relate to the vpnmap number, 141 in this case and compiles a list of entries. This list is then used to collect the receive or transmit statistics and add the values together for each ipsec tunnel associates with that isakmp tunnel (there can be many ipsec tunnels per isakmp tunnel depending on your match acl setup).

The script in full

'The remote peer
strVPNMapNumber="141"

' The direction of traffic (rx or tx)
strDirection="rx"

ipSecVPNMapIndex = "1.3.6.1.4.1.9.9.172.1.2.1.1.3"
ipSecInOct              = "1.3.6.1.4.1.9.9.171.1.3.2.1.26"
ipSecOutOct             = "1.3.6.1.4.1.9.9.171.1.3.2.1.39"

set objSNMPReq = CreateObject("CoreAsp.SnmpRqst")
strDeviceID = Context.GetProperty("DeviceID")
set objSNMPInit = objSNMPReq.Initialize(strDeviceID)

if objSNMPInit.Failed then
    '.
else
    ' Get a list of indexes which match the VPN map number
    arrIpsecIndex = split(get_ipsecTunnel_list(ipSecVPNMapIndex,strVPNMapNumber),",")

    intFirstReading = get_TrafficSum()
    context.logmessage "FirstReading=" & intFirstReading 
    sleep(1)
    intSecondReading = get_TrafficSum()
    context.logmessage "SecondReading=" & intSecondReading 
    intTotalTrafficReading = intSecondReading - intFirstReading
    'value is in bytes
    Context.SetValue (intTotalTrafficReading * 8)/1000
    context.logmessage "Total=" & (intTotalTrafficReading * 8)/1000
end if

function get_TrafficSum()
    inttmpTotalTrafficReading=0
    context.logmessage ubound(arrIpsecIndex)
    for each ipsecTunnelID in arrIpsecIndex
        context.logmessage "Processing Tunnel ID " & ipsecTunnelID
        if string_compare(strDirection,"rx") then
            strtmpOID=ipSecInOct
        else
            strtmpOID=ipSecOutOct
        end if
        inttmpResult=get_SNMPget(strtmpOID & "." & ipsecTunnelID)
        context.logmessage ipsecTunnelID & "=" & inttmpResult
        inttmpTotalTrafficReading = inttmpTotalTrafficReading + inttmpResult
    next
    get_TrafficSum = inttmpTotalTrafficReading
end function

function get_ipsecTunnel_list (strOID,strtmpTargetValue)
    tmpReturnValue=""
    boolExitWhile=0

    set objtmpSNMPResult = objSNMPReq.GetNext(strOID)

                context.logmessage "Looking for entry index OID for target " & strtmpTargetValue

    While boolExitWhile <> 1
        currSNMPPayload = objtmpSNMPResult.GetValue
        currSNMPIndex=objtmpSNMPResult.GetOID
        context.logmessage currSNMPIndex & "=" & currSNMPPayload 

        if currSNMPPayload = strtmpTargetValue then 
                                    context.logmessage currSNMPPayload & "=" & strtmpTargetValue
            currIndexNum=get_indexFromOID(currSNMPIndex)
            if tmpReturnValue = "" then
                tmpReturnValue=currIndexNum
                                                '    context.logmessage "ipsec index num is " & currIndexNum
            else 
                tmpReturnValue = tmpReturnValue & "," & currIndexNum
                                                '                   context.logmessage "ipsec index num is " & currIndexNum
            end if
            context.logmessage "index num is " & tmpReturnValue
        end if

        if string_compare(strOID,currSNMPIndex) then
            'context.logmessage "Setting next entry after " & currSNMPIndex
            set objtmpSNMPResult = objSNMPReq.GetNext(currSNMPIndex)
        else
            'context.logmessage currSNMPIndex & " isn't in OID " & strOID
            'context.logmessage "Didn't find match for target " & strtmpTargetValue 
            boolExitWhile=1
        end if
    wend
    context.logmessage "Got value=" &  tmpReturnValue
    get_ipsecTunnel_list = tmpReturnValue
end function

function get_SNMPget(strtmpOID)
    set objtmpSNMPResult = objSNMPReq.Get(strtmpOID)
    strtmpValue=objtmpSNMPResult.GetPayload
    context.logmessage strtmpOID & " returned value " & strtmpValue
    get_SNMPget=strtmpValue
end function

private function string_compare(expression,targetstring)
    set oreg= new regexp
    oReg.pattern=expression
    oReg.IgnoreCase = TRUE
    if ("" = expression OR "" = targetstring) then
        boolSearchResult=0
    end if
    if oReg.test (targetstring) then
        boolSearchResult=1
    else
        boolSearchResult=0
    end if
    string_compare=boolSearchResult
end function

function sleep(intseconds)
    intstarttime = timer()
    while timer() < intstarttime+intseconds
        '.
    wend
end function

function get_indexFromOID(strtmpOID)
    strtmpValue=""

    arrtmpOID=split(strtmpOID,".")
    inttmpSize=ubound(arrtmpOID)
    strtmpValue=arrtmpOID(inttmpSize)
    context.logmessage "get_indexFromOID=" & strtmpValue

    get_indexFromOID=strtmpValue
end function

Download the script (rename to zip)

Advertisements
Tagged , , , , , , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: