You know those times when you paste innocuous config to a router and it just freezes up on you? Even if you know you’ve done nothing wrong it can be a few scary seconds until the router starts to respond again. While reading up on onePK I was trying to come up with a use case. Though I eventually thought about some other things that would actually be useful. The very first thing that came to mind was something to test just for fun.
Picture this; You ask a co-worker to login to a router and shutdown an interface which won’t be used anymore. Your colleague logs into the device and disables the interface and the session hangs. Only it doesn’t just hang, it’s dead and apparently your colleague can’t ping the device now. At this point it can be a good idea to ask your co-worker about what exactly he changed.
Cisco One Platform Kit (onePK) is toolkit which gives you an API against routers and switches. onePK is part of Cisco’s Open Network Environment software defined networking (SDN) strategy. While the onePK website talks about “Unlimited Possibilities”, I have yet to be blown away by its greatness. It could be that I’m just too new with it or that I was expecting something else. At least in the current 1.3 release onePK seems to be focused around dynamic temporary changes to router behavior. While that’s good for some scenarios what I really wanted was a tool I could use for configuration changes. Currently onePK doesn’t seem to be that toolkit.
Today onePK have SDKs for C, Java and Python. One thing to note is that the feature set is different depending on the language you use. Regardless, if you aren’t already a developer I would suggest that you learn Python. It’s fairly easy to learn the basics and you’ll be able to start writing useful applications in no time.
For this prank you choose a victim and a command which will “hang” the router. Actually what will happen is that when your victim issues your chosen command the Python script will have a connection to the router and use a CLIListener and see when the command is issued. This will trigger a check to see if the victim is logged in. If the user is logged into the device the IP address the victim logged in from will be null routed. The route will remain in place until you terminate the script.
To begin you have to verify that your device has support for onePK. Check the compatibility matrix of the current onePK release. I was using a Cisco ISR 881 router with 15.4(2)T2
onep transport type tls disable-remotecert-validation service set vty
It’s also assumed that you’ve setup aaa on your device and can login using different users.
In this example tls is used to encrypt the connection to the router. But the certificate used is just ignored. I will write more about setting up a secure onePK connection in the future. For now I just wanted to test it out in a quick way.
A few things needs to be in included in a script for this to work.
If we start by looking at the script from the command prompt using the -h argument.
patrick@srv-master-1:~$ ./onepk-blackhole-victim.py -h usage: onepk-blackhole-victim.py [-h] [-t T] [-u U] [-c C] [-v V] Used to black hole the ip address of a specific user when he/she issues a specified command. optional arguments: -h, --help show this help message and exit -t T Target router -u U Your username -c C Command to trigger event on -v V The victims username REMEMBER: With great power comes great responsibility. patrick@srv-master-1:~$
Let’s run the script.
./onepk-blackhole-victim.py -t r2 -u patrick -c ^shut -v john Please enter your password: ----- NetworkElement [ r2 ] Product ID : 881 Processor : MPC8300 Serial No : FCZ1643C2WX sysName : R2 sysUpTime : 1010 sysDescr : Cisco IOS Software, C880 Software (C880DATA-UNIVERSALK9-M), Version 15.4(2)T2, RELEASE SOFTWARE (fc1) Technical Support: http://www.cisco.com/techsupport Copyright (c) 1986-2014 by Cisco Systems, Inc. Compiled Mon 27-Oct-14 11:17 by prod_rel_team ----- Waiting for command: ^shut ----- Type a key to exit script
So what happens now? I won’t go into the script line by line here, but I intend to write more about onePK in the future. However if you download the script you might be able to follow along. First we use the argparse module to sort through the options. Then we connect to a router called r2 with the username “patrick”.
The next step is to setup a CLIListener. Which will trigger an event whenever someone issues a command starting with “shut”, i.e. “no shutdown” won’t trigger the event.
When the event triggers we create a VTYservice to issue the “who” command to check which users are logged into the router. We then parse the output from this command and see if our victim “john” is logged on. If he is we store the information about which IP address he has logged in from.
Armed with the information of John’s IP we use the onePK routing modules to create a null route for this ip.
When John shuts down any interface on the router this will appear in our script window:
Caught: shutdown ----- ----- User is on the system: john Blackholing ip: 172.29.50.39 ----- Type a key to exit script
If we login to the device we can see that it’s shown as an application route.
R2#show ip route Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2 E1 - OSPF external type 1, E2 - OSPF external type 2 i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2 ia - IS-IS inter area, * - candidate default, U - per-user static route o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP a - application route + - replicated route, % - next hop override Gateway of last resort is 172.29.50.33 to network 0.0.0.0 S* 0.0.0.0/0 [1/0] via 172.29.50.33 172.29.0.0/16 is variably subnetted, 3 subnets, 2 masks C 172.29.50.32/27 is directly connected, FastEthernet4 a 172.29.50.39/32 [1/0] via 0.0.0.0, 00:02:18, Null0 L 172.29.50.60/32 is directly connected, FastEthernet4 R2#
Here John’s ip address 172.29.50.39 is routed to the null0 interface and he won’t be able to get any packets back from the device. (This is where you ask John what the hell he just did.)
The application route will stay in the routing table until the Python script is terminated. Which will happen when you type another character in the script window.
If you really want to mess with your coworker you can also null route your Nagios server. Or how about redistributing the application routes into the rest of your network.
While reading through this you there is one thing which might disturb you (well I guess it could be more than one thing). If you look at how we found out about the fact that John was logged in and got his IP address it isn’t really that pretty. Even with this toolkit which offers “unlimited possibilities” we are actually reduced to screen scraping. Granted I might have overlooked something and onePK is still quite new, but this solution feels a bit off.
So if we instead look at a real world scenario. It would actually be useful to create null routes in this way and redistribute them. That’s what is done with remotely triggered black holes for BGP.
Let’s face it we live in a world where we still have to write “do not eat” on those tasty looking bags which you get when you buy disk drives. So; if you love your job it might be unwise to run this script. I wrote it to learn more about onePK and to be able to demonstrate what can be done with onePK. What you do with it is up to you. You could just use it to learn more about onePK.
Also this script is very crude. The goal wasn’t to create something pretty. I didn’t want to spend much time on it, the goal was just to get more familiar with onePK.
You can find the onePK prank script on Github.