How to use MRTG to log specific protocol traffic using SNMP and Cisco’s NBAR
We've all seen these nifty graphs that some sites seem to be able to provide.
This particular overview shows us the in- and outbound traffic that goes over my ADSL link over the last 24 hours. The nice thing about it is that the tool used here is capable of showing you longer periods of time, a day, a week, a month or even up to a year it will show you the trends of the growth of your traffic volume, helping you to decide when to upgrade that link, or ban p2p tools from your network.
This article is –not- about simply implementing that, the tool used here is MRTG, it will run under Linux and Windows (in my case windows) and uses perl. In fact, the MRTG website gives you more than enough information on how to get things going. Instead; we want to dive in deeper and view specific information about the specific protocols going over the interfaces.
This article assumes you know to a certain extend how to get information from you routers using SNMP (Simple Network Management Protocol). It goes more in depth on that: what if you are only interested in certain sub-protocols? For example: suppose you have a customer using terminal server over an SDSL link, and this customers reports that things are slow, usually between 12:00 and 14:00 hours. Would it not be great to be able to see an overview of all kinds of traffic around that time?
Cisco has something called NBAR
(Network Based Application Recognition)
in it's IOS, this will make this kind of information available, and the good news is, we can read it using SNMP!
This opens it up for the use of MRTG…
Here you can see an example of one interface showing us HP-printing traffic, as well as HTTP traffic on that interface over the last 24 hours. This data came from a typical office environment, as you can see from the HTTP traffic ;-)
Where to start
To begin, you'll need a number of things:
In our case we have installed the Windows version, and we are running it as a service. How to do this is not part of this article, but the listed webpage has details on how to approach this., it can be found here: MRTG - The MRTG 2.16.2 Windows Installation Guide
MRTG uses Perl, so you'll need this as part of MRTG.
We'll be using the snmpwalk as well as the snmpget utilities.
Cisco SNMP Object Navigator
- Cisco MIBs for NBAR, and dependencies:
It is important to make sure the following Cisco MIB is copied to the /share/snmp/mibs directory under the Net-SNMP tools:
Better yet, why not put all the dependencies there too? (if not there already) This will later help snmpwalk.exe and snmpget.exe to understand what information is being gathered.
Once all is installed, we can start…
Suppose a router is located at IP 172.24.1.1
We want to make sure the router supports NBAR on the correct interface(s). If the router is recent (>2003, and has a fairly recent IOS, you'll have a pretty good chance of it supporting NBAR). Typically we are only interested in one or two interfaces to see what exactly is going on protocol-wise.
Telnet or ssh into the router and check (sho run) the configuration, go into the interface you'll want monitored. (enable (if needed)), conf t, and select the interface.
To enable NBAR for this interface give the command: 'ip nbar protocol-discovery'.
Get out of config mode, and check with:
'show ip nbar protocol-discovery interface yourinterface X stats bit-rate top-n 5'
(where "yourinterface" can be something like: Fast Ethernet X or Tunnel Y for example)
Next step is to make sure NBAR understands all the port mappings, for example, you may want to manually add the RDP protocol:
'ip nbar custom rdp tcp 3389'
More info on the port mappings:
show ip nbar port-map
Also note that printer is typically port 515, you may want to add hp-print or something like that to capture port tcp 9100, typically used by the HP Jetdirect boxes.
We've now got the software installed and the router ready and waiting, lets start experimenting with SNMP!
First you need to understand the concept of MIB's en how to access the router's SNMP Agent IOD's. Good luck with that. For this manual it suffices to explain that for every interface, protocol, channel etc. there's an ID that looks something like:
Looks like an IP on steroids doesn't it. This particular one identifies (represents) the CISCO-NBAR-PROTOCOL-DISCOVERY-MIB by the way, this is the one we'll be using to dig into SNMP and gather statistics.
Some more information on these numbers and how to use them in MRTG can be found here:
www.vermeer.org: Graphing Cisco Systems (NBAR) Network-based application recognition with MRTG;
And here is s nice overview of what all these numbers (Object ID's or OID's) mean:
ipMonitor :: CISCO-NBAR-PROTOCOL-DISCOVERY-MIB: Cisco Network Based Application Recognition (NBAR) Protocol Discovery
Now that you have a better understanding of what all these numbers are, we'll start walking around in SNMP to get some information from them. If you have installed the Net-SNMP package correctly, and have copied the Cisco MIB's to the correct place, you will be able to get some names instead of numbers using the MIB information, this will help you determine what interface to access.
snmpwalk -c public -v2c 172.24.1.1 | more
Will give you a nice idea of the kind of information that can be found in the router. This info might help you find the correct interface number.
C:\mrtg-2.14.3\snmp\usr\bin>snmpwalk -c public -v2c 172.24.1.1 | more
SNMPv2-MIB::sysDescr.0 = STRING: Cisco IOS Software, 2800 Software (C2800
Technical Support: Cisco - Shortcut
Copyright (c) 1986-2006 by Cisco Systems, Inc.
Compiled Wed 19-Apr-06 09:18 by alnguyen
SNMPv2-MIB::sysObjectID.0 = OID: SNMPv2-SMI::enterprises.9.1.576
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (67387120) 7 days, 19:11
SNMPv2-MIB::sysContact.0 = STRING:
SNMPv2-MIB::sysName.0 = STRING: rt-nevo-nieu-01.nevobo.nl
SNMPv2-MIB::sysLocation.0 = STRING:
SNMPv2-MIB::sysServices.0 = INTEGER: 78
SNMPv2-MIB::sysORLastChange.0 = Timeticks: (0) 0:00:00.00
IF-MIB::ifNumber.0 = INTEGER: 14
IF-MIB::ifIndex.1 = INTEGER: 1
IF-MIB::ifIndex.2 = INTEGER: 2
IF-MIB::ifIndex.3 = INTEGER: 3
IF-MIB::ifIndex.4 = INTEGER: 4
IF-MIB::ifIndex.5 = INTEGER: 5
IF-MIB::ifIndex.6 = INTEGER: 6
IF-MIB::ifIndex.7 = INTEGER: 7
IF-MIB::ifIndex.8 = INTEGER: 8
IF-MIB::ifIndex.9 = INTEGER: 9
IF-MIB::ifIndex.10 = INTEGER: 10
IF-MIB::ifIndex.11 = INTEGER: 11
IF-MIB::ifIndex.12 = INTEGER: 12
IF-MIB::ifIndex.13 = INTEGER: 13
IF-MIB::ifIndex.14 = INTEGER: 14
IF-MIB::ifDescr.1 = STRING: FastEthernet0/0
IF-MIB::ifDescr.2 = STRING: FastEthernet0/1
IF-MIB::ifDescr.3 = STRING: ATM0/0/0
IF-MIB::ifDescr.4 = STRING: Null0
IF-MIB::ifDescr.5 = STRING: ATM0/0/0-atm layer
IF-MIB::ifDescr.6 = STRING: ATM0/0/0.0-atm subif
IF-MIB::ifDescr.7 = STRING: ATM0/0/0-aal5 layer
IF-MIB::ifDescr.8 = STRING: ATM0/0/0.0-aal5 layer
IF-MIB::ifDescr.9 = STRING: Tunnel0
I would like to see the traffic that is going over a VPN tunnel. The above shows me that the interface I'm interested in (the Tunnel0 interface) is number 9. We'll need this information later.
Lets look a little closer…
snmpwalk -m ALL -c public -v2c 172.24.1.1 188.8.131.52.184.108.40.206.244 | more
Gives us more detailed information about NBAR, as 220.127.116.11.18.104.22.168.244 is the CISCO-NBAR-PROTOCOL-DISCOVERY-MIB. Now we get to see (amongst other information) a list of the different protocols we might want to check:
C:\mrtg-2.14.3\snmp\usr\bin>snmpwalk -m ALL -c public -v2c 172.24.1.1 22.214.171.124.126.96.36.199.244
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusPdEnable.1 = INTEGER: false(2)
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusPdEnable.2 = INTEGER: false(2)
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusPdEnable.3 = INTEGER: false(2)
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusPdEnable.4 = INTEGER: false(2)
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusPdEnable.5 = INTEGER: false(2)
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusPdEnable.6 = INTEGER: false(2)
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusPdEnable.7 = INTEGER: false(2)
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusPdEnable.8 = INTEGER: false(2)
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusPdEnable.9 = INTEGER: true(1)
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusPdEnable.10 = INTEGER: true(1)
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusPdEnable.11 = INTEGER: false(2)
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusPdEnable.12 = INTEGER: true(1)
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusPdEnable.13 = INTEGER: false(2)
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusPdEnable.14 = INTEGER: false(2)
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusLastUpdateTime.1 = Timeticks: (0) 0:00:00.00
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusLastUpdateTime.2 = Timeticks: (0) 0:00:00.00
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusLastUpdateTime.3 = Timeticks: (0) 0:00:00.00
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusLastUpdateTime.4 = Timeticks: (0) 0:00:00.00
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusLastUpdateTime.5 = Timeticks: (0) 0:00:00.00
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusLastUpdateTime.6 = Timeticks: (0) 0:00:00.00
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusLastUpdateTime.7 = Timeticks: (0) 0:00:00.00
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusLastUpdateTime.8 = Timeticks: (0) 0:00:00.00
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusLastUpdateTime.9 = Timeticks: (6888779) 19:08:07.79
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusLastUpdateTime.10 = Timeticks: (6888779) 19:08:07.79
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusLastUpdateTime.11 = Timeticks: (0) 0:00:00.00
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusLastUpdateTime.12 = Timeticks: (66110432) 7 days, 15:38:24.32
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusLastUpdateTime.13 = Timeticks: (0) 0:00:00.00
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdStatusLastUpdateTime.14 = Timeticks: (0) 0:00:00.00
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsProtocolName.9.1 = STRING: "ftp"
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsProtocolName.9.2 = STRING: "http"
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsProtocolName.9.3 = STRING: "egp"
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsProtocolName.9.4 = STRING: "gre"
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsProtocolName.9.5 = STRING: "icmp"
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsProtocolName.9.6 = STRING: "eigrp"
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsProtocolName.9.7 = STRING: "ipinip"
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsProtocolName.9.8 = STRING: "ipsec"
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsProtocolName.9.9 = STRING: "ospf"
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsProtocolName.9.10 = STRING: "bgp"
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsProtocolName.9.11 = STRING: "cuseeme"
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsProtocolName.9.12 = STRING: "dhcp"
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsProtocolName.9.13 = STRING: "dns"
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsProtocolName.9.14 = STRING: "finger"
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsProtocolName.9.15 = STRING: "gopher"
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsProtocolName.9.16 = STRING: "secure-http"
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsProtocolName.9.17 = STRING: "imap"
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsProtocolName.9.18 = STRING: "secure-imap"
The rdp protocol we added manually (custom) in this particular case is number 81. (not shown) In this list we only
see the interfaces where we have enabled NBAR on, in the above example; interface number 9, which happens to be the tunnel we are interested in. The conclusion is that I want to look at interface number 9, with protocol number 81. The complete list will also show us that we can select cnpdAllStartInPkts on interface 8 protocol 81. Since we have the MIB's we can do this like this:
snmpget -m ALL -c public -v2c 172.24.1.1 CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsInPkts.9.81
(notice we are now using snmpget
instead of snmpwalk)
This produces the following output:
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsInPkts.9.81 = Counter32: 30678687 packets
This is close to the information we are after, but I'd rather have bytes instead of packets:
C:\mrtg-2.14.3\snmp\usr\bin>snmpget -m ALL -c public -v2c 172.24.1.1 CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsInBytes.9.81
CISCO-NBAR-PROTOCOL-DISCOVERY-MIB::cnpdAllStatsInBytes.9.81 = Counter32: 1180202481 bytes
If we would not use the MIB names, we should use the numbers:
snmpget -m ALL -c public -v2c 172.24.1.1 188.8.131.52.184.108.40.206.244.1.2.1.220.127.116.11
This will result in the same output, and since we are using the MIB information (-m ALL) we can also check the output to confirm that we are indeed listing the cnpdAllStatsInBytes.9.81 counter.
Getting it into MRTG
We are getting there! We now know exactly what SNMP IOD agent to list, so now lets translate this into MRTG. I would advise to make a include file that seperates the NBAR info from the rest of the config. We do this by creating a .inc file, and referring to it in the main .cfg file, like was done here:
As shown on the www.vermeer.org
pages we have the following information in the .inc file (in this example we monitor the RDP as well as Printer protocols)
## rdp Traffic Analysis
SetEnv[nbar-rdp]: MRTG_INT_IP="" MRTG_INT_DESCR=""
Title[nbar-rdp]: Cisco Nbar Protocol Analysis
## printer Traffic Analysis
SetEnv[nbar-printer]: MRTG_INT_IP="" MRTG_INT_DESCR=""
Title[nbar-printer]: Cisco Nbar Protocol Analysis
Simply restart the mrtg service to make the data show up in a sepereate NBAR directory created under the root directory used by MRTG.
I hope this article helped you on your way, let me know if it did