on 07-22-2013 07:34 AM
Purpose:
This document aims to outline a way to extract client association data from a Cisco WLC so that it can be referenced later. My organization has a business requirement to track all wireless users. We use the techniques outlined in this document to take a "snap-shot" of our wireless clients associated with a Cisco WLC every 5 minutes and import that data into Splunk, where we can index and search through it any time we want.
This document will cover some basics needed to successfully extract connected client data from a Cisco WLC via SNMP. Although this feat has probably been done before, I was able to find little documentation on how to extract this specific data and use it for historical purposes. This document will provide MIB information to key OIDs of value, a bash scripting example, and lessons learned.
SNMP MIBs:
Cisco provides excellent SNMP MIB documentation. For those who don't know what a MIB is, it stands for Management Information Base. A MIB is like a road map for SNMP enabled systems. The MIB allows you to identify and navigate to key data points that you wish to query. Without a MIB for a corresponding piece of equipment, you will be making arbitrary requests for seemingly random data-points.
The easiest way to find what you are looking for is to use Cisco's SNMP Object Browser: http://tools.cisco.com/Support/SNMP/do/BrowseOID.do
This tool allows you to step through an SNMP tree and locate the OID you are looking for, so you can query the data you want. In this tutorial we will be using the SNMP tool suite for Linux and the snmpget and snmpwalk commands specifically.
The OIDS below will be what we focus on.
AP Names:
1.3.6.1.4.1.14179.2.2.1.1.3
Client MAC Address List:
1.3.6.1.4.1.14179.2.1.4.1.1
snmpwalk -v 2c -O x -c public 10.1.1.252 1.3.6.1.4.1.14179.2.1.4.1.1
Client IP Address List:
1.3.6.1.4.1.14179.2.1.4.1.2
snmpwalk -v 2c -c public 10.1.1.252 1.3.6.1.4.1.14179.2.1.4.1.2
Client Username List:
1.3.6.1.4.1.14179.2.1.4.1.3
snmpwalk -v 2c -c public 10.1.1.252 1.3.6.1.4.1.14179.2.1.4.1.3
AP MAC Address List:
1.3.6.1.4.1.14179.2.1.4.1.3
snmpwalk -v 2c -O x -c public 10.1.1.1.252 1.3.6.1.4.1.14179.2.1.4.1.4
Client SSID List:
1.3.6.1.4.1.14179.2.1.4.1.7
snmpwalk -v 2c -c public 10.1.1.252 1.3.6.1.4.1.14179.2.1.4.1.7
-=EXAMPLE OUTPUT=-
SNMPv2-SMI::enterprises.14179.2.1.4.1.1.252.199.52.222.11.140 = Hex-STRING: FC C7 34 DE 0B 8C
SNMPv2-SMI::enterprises.14179.2.1.4.1.2.252.199.52.222.11.140 = IpAddress: 10.1.11.21
SNMPv2-SMI::enterprises.14179.2.1.4.1.3.252.199.52.222.11.140 = STRING: "jdoe"
SNMPv2-SMI::enterprises.14179.2.1.4.1.4.252.199.52.222.11.140 = Hex-STRING: 84 78 AC B8 2F 90
Using the above OIDs and command examples we can collect the data we want.
By querying 1.3.6.1.4.1.14179.2.1.4.1.1 we get a complete list of client MAC addresses currently associated with the WLC. You may have noticed in the example output, that the different pieces of information all contain the same unique sequence on the end of the query. (Ex.
252.199.52.222.11.140) This will allow us to query a specific user's attributes. Now that we know the basics of SNMP and know where the data is, we can start scripting to put everything into a more readable format.
Script Example:
(Please excuse my scripting. I'm no coder. This is for practical application and demonstration purposes only.)
The script example below is a bash script that was designed to be cron'd on a Linux host. The output of the script looks like this:
SYSTEM=CISCO MAC=E4:D5:3D:3B:81:4D IP=10.1.0.233 USER=DOMAIN\\jdoe17 AP=84:78:AC:B8:33:F0 SSID=Marketing
SYSTEM=CISCO MAC=E8:3E:B6:3B:CA:8D IP=10.1.240.243 USER=Unknown AP=84:78:AC:B8:8A:E0 SSID=Guest
SYSTEM=CISCO MAC=EC:85:2F:14:A9:BA IP=10.1.248.197 USER=Unknown AP=1C:E6:C7:1C:D8:90 SSID=Guest
SYSTEM=CISCO MAC=F0:1C:13:09:0E:B2 IP=10.1.252.151 USER=Unknown AP=54:78:1A:71:81:B0 SSID=Guest
SYSTEM=CISCO MAC=F0:4F:7C:B9:5F:B3 IP=10.1.0.221 USER=jdoe12 AP=54:78:1A:71:81:B0 SSID=Marketing
SYSTEM=CISCO MAC=F0:4F:7C:D6:0A:D9 IP=10.1.251.29 USER=Unknown AP=54:78:1A:70:EE:10 SSID=Guest
SYSTEM=CISCO MAC=F0:A2:25:A7:BD:F5 IP=10.1.251.85 USER=Unknown AP=84:78:AC:B8:8C:60 SSID=Guest
SYSTEM=CISCO MAC=F0:CB:A1:32:B3:D0 IP=10.1.136.163 USER=jdoe76 AP=84:78:AC:B8:8C:60 SSID=Admin-Wifi
SYSTEM=CISCO MAC=F0:CB:A1:C7:2E:6F IP=10.1.0.179 USER=jdoe1 AP=84:78:AC:B8:33:F0 SSID=Marketing
SYSTEM=CISCO MAC=F0:D1:A9:6E:05:2A IP=10.1.248.141 USER=Unknown AP=54:78:1A:71:D7:00 SSID=Guest
SYSTEM=CISCO MAC=F0:D1:A9:92:5C:7F IP=10.1.0.164 USER=jdoe23 AP=1C:E6:C7:1C:D3:E0 SSID=Marketing
SYSTEM=CISCO MAC=F0:DC:E2:02:4F:35 IP=10.1.248.104 USER=Unknown AP=54:78:1A:71:D7:00 SSID=Guest
SYSTEM=CISCO MAC=F0:DC:E2:BF:E1:A1 IP=10.1.0.240 USER=jadoe4 AP=84:78:AC:B8:33:F0 SSID=Marketing
SYSTEM=CISCO MAC=F4:6D:E2:E9:69:58 IP=10.1.252.180 USER=Unknown AP=54:78:1A:71:BF:B0 SSID=Guest
SYSTEM=CISCO MAC=F8:D0:BD:2F:BF:21 IP=10.1.0.128 USER=jdoe48 AP=1C:E6:C7:1C:D8:90 SSID=Marketing
SYSTEM=CISCO MAC=F8:DB:7F:9F:5A:22 IP=10.1.252.182 USER=Unknown AP=1C:E6:C7:1D:2F:60 SSID=Guest
SYSTEM=CISCO MAC=FC:C7:34:DE:0B:8C IP=10.1.0.44 USER=jdoe1 AP=84:78:AC:B8:2F:90 SSID=Marketing
(*NOTE: This format is easily digested by Splunk or syslog)
Example Script:
#!/bin/bash
##########################
snmp_community="public"
snmp_host="10.1.1.252"
###########################
rm -f /tmp/cn-wlc.txt
####################################################################
#Set input system to break on new-line when adding data to an array#
####################################################################
IFS=$'\n'
############################################################################################
#Perform SNMP walks to get data of interest and load them into array variables to use later#
############################################################################################
while [ "1" -ne "2" ]
do
Unique_OID=($(snmpwalk -v 2c -O x -c $snmp_community $snmp_host 1.3.6.1.4.1.14179.2.1.4.1.1))
Client_IP=($(snmpwalk -v 2c -c $snmp_community $snmp_host 1.3.6.1.4.1.14179.2.1.4.1.2))
Client_Username=($(snmpwalk -v 2c -c $snmp_community $snmp_host 1.3.6.1.4.1.14179.2.1.4.1.3))
Client_AP=($(snmpwalk -v 2c -O x -c $snmp_community $snmp_host 1.3.6.1.4.1.14179.2.1.4.1.4))
Client_SSID=($(snmpwalk -v 2c -c $snmp_community $snmp_host 1.3.6.1.4.1.14179.2.1.4.1.7))
############################################################################################
#Ensure all SNMP walk requests contain the same amount of data and break loop when they do #
############################################################################################
count1=${#Unique_OID[@]}
count2=${#Client_IP[@]}
count3=${#Client_Username[@]}
count4=${#Client_AP[@]}
count5=${#Client_SSID[@]}
if [ "$count1" -eq "$count2" ]; then
if [ "$count2" -eq "$count3" ]; then
if [ "$count3" -eq "$count4" ]; then
if [ "$count4" -eq "$count5" ]; then
break
fi
fi
fi
fi
done
####################################################################
#Create a loop to match and extract data between the various arrays#
####################################################################
wait
index=0
while [ "$index" -lt "$count1" ]
do
id=$(echo ${Unique_OID[$index]} | cut -d "=" -f1 | awk -F "." '{print $8 "."$9 "." $10 "." $11 "." $12 "." $13 }')
cMAC=$(echo ${Unique_OID[$index]} | grep $id | awk -F " " '{print $4 ":" $5 ":" $6 ":" $7 ":" $8 ":" $9 }')
cIP=$(echo ${Client_IP[$index]} | grep $id | awk -F " " '{print $4}')
cUser=$(echo ${Client_Username[$index]} | grep $id | awk -F " " '{print $4}' | sed s/\"//g)
cAP=$(echo ${Client_AP[$index]} | grep $id | awk -F " " '{print $4 ":" $5 ":" $6 ":" $7 ":" $8 ":" $9 }')
cSSID=$(echo ${Client_SSID[$index]} | grep $id | awk -F " " '{print $4}' | sed s/\"//g)
if [ "$cUser" = "\"\"" ]; then
cUser="Unknown"
fi
if [ "$cUser" = "" ]; then
cUser="Unknown"
fi
if [ "$cIP" = "0.0.0.0" ]; then
donothing="True"
else
# write our data out to a file so we can do something with it later
echo "SYSTEM=CISCO MAC="$cMAC "IP="$cIP "USER="$cUser "AP="$cAP "SSID="$cSSID >> /tmp/cn-wlc.txt
#echo "SYSTEM=CISCO MAC="$cMAC "IP="$cIP "User="$cUser "AP="$cAP "SSID="$cSSID
fi
((index++))
done
Lessons Learned:
Summary:
With the data you can collect using Cisco's MIBs and SNMP there is no limit to what information your gear can show you. My organization has used it with great success to meet business requirements. Being able to historically see who was on your wireless network at any time will give you a huge advantage. We can turn around DMCA notices, track users, identify usage peaks and wireless trends at various facilities, and to a certain degree, identify coverage issues. We also have a similar script to collect this same data from Meru systems as well. Although this guide may not be perfect and the scripting could be improved, I felt it necessary to share.
Best of luck!
Thank you very much.
I have used it with my WLC and worked like a charm.
Best regards,
Ricardo Canto
Update:
I now have too many wireless clients for the above method to work. The script would basically get caught in a loop waiting for all the right conditions to be met before it would dump data. If you have a LOT of users the above method will not work because their associations will come and go and the 4 conditions the script waits for will never be met.
I've since switched to an SNMP trap method to get logs into Splunk. The attached bash script will parse SNMP trap messages and dump them out to a cleaned file for splunk to index. This only works with only client authentication trap messages enabled form the controller. (only a single trap message type selected on the WLC)
This method works a lot better and you don't end up collecting a list of all of your clients currently on the system with every poll. This method gathers client information in real-time, with a 5 minute lag, and won't clutter up your Splunk.
I've also included a copy of my Splunk dashboard. It's use will require a Cisco-WLC sourcetype to be configured and upon initial setup of the trap message indexing, you will be required to properly format the timestamps on the data. (this can be tricky) If you don't format the timestamps properly the event data will not look properly.
Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: