4. Scripts
4.1. Intro
When I have to do things twice, I get bored. When I have to do it three times, I create a script to automate it.
My switch still uses telnet (yes I know) and I used expect to interface with my switch.
The following template will be used.
#!/usr/bin/expect set timeout 60 set ip 192.168.10.1 set user cisco set password secret spawn telnet $ip expect "ername:" send "$user\r" expect "assword: " send "$password\r" expect "DEMO" send "enable\r" expect "assword: " send "$password\r" expect "DEMO" send -- "exit\r"
Because I have a test of short duration and becaise I am on a stand-alone network without connection to the rest of the world, I can put the password in my script. In a real life situation that would be unthinkable.
the DEMO is a part of the prompt for the switch. If you are very precise, you could put in the exact prompt that will be presented ( DEMO> or DEMO# in enable mode, and so on for the different config modes. That will make the scripts better, but this will do for our test.
4.2. Resetting scripts with expect
If a port needs to be reset, you can log in to the switch, do enable and conf t and type all the IOS commands by hand. Or you could use an expect script.
#!/usr/bin/expect set port [lindex $argv 0] set mac [lindex $argv 1] set timeout 60 set ip 192.168.10.1 set user cisco set password secret spawn telnet $ip expect "ername:" send "$user\r" expect "assword: " send "$password\r" expect "DEMO>" send "enable\r" expect "assword: " send "$password\r" expect "DEMO" send "conf t\r" expect "DEMO" send "int fa0/$port\r" expect "DEMO" send "shut\r" expect "DEMO" send "end\r" expect "DEMO" send "conf t\r" expect "DEMO" send "int fa0/$port\r" expect "DEMO" send "no shut\r" expect "DEMO" send "end\r" expect "DEMO" send -- "exit\r"
It should not be dificult to create scripts for the main transactions. I created expect scripts for the following.
|
script
|
purpose
|
commands
|
|
down_port.xpct
|
make a port admin down
|
conf t<br>int fa0/port<br>shut<br>end
|
|
remove_mac_on_port_sticky.exp
|
remove a sticky mac from a port
|
conf t<br> int fa0/port<br> shut<br> no switchport port-security mac-address sticky mac<br> no shut
|
|
reset_port.xpct
|
reset a port
|
conf t<br>int fa0/port<br>shut<br>no shut<br>end
|
|
show_port.xpct
|
show settings
|
sh run interface fa0/port<br>sh port-security interface fa0/port
|
4.3. A demo menu
This test was part of a demonstration of how port security works. I used the following script to hide the nitty gritty details from the audience.
#!/bin/bash TMP=/tmp/rgh.$$ sudo tail -f /var/log/messages | grep PSECURE_VIOLATION & tokill=$!
The syslog messages about port security violations are written over the menu. This shows that we actually see an alert when something is happening.
disp(){
printf "%4.4s %16.16s %16.16s %12.12s\n" port allowed last_seen status
for port in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
expect show_port.xpct $port | sed 's/\r//' > $TMP
mac=`awk '/switchport port-security mac-address.*[0-9a-f]+\.[0-9a-f]/{print $NF}' $TMP`
lastseen=`sed -n 's/Last Source Address:Vlan *: *//p' $TMP | sed 's/:1*0//'`
status=`sed -n 's/Port Status *: *//p' $TMP`
nstat='unknown'
case a$status in
(aSecure-up) nstat='UP' ;;
(aSecure-down) nstat='No device' ;;
(aSecure-shutdown)
if [ "$mac" = "" ] ; then
nstat='No device'
else
nstat="Violation"
fi
;;
esac
if grep '^ *shutdown' $TMP > /dev/null ; then
nstat='adm down'
fi
printf "%4.4s %16.16s %16.16s %12.12s\n" "$port" "$mac" "$lastseen" "$nstat"
done
rm -f $TMP
}
The goal of this function is to provide a display of what is actually happening. It shows a table that is easier to interpret than the standard IOS output.
rmmac(){
port=$1
expect show_port.xpct $port | sed 's/\r//' > $TMP
mac=`awk '/switchport port-security mac-address.*[0-9a-f]+\.[0-9a-f]/{print $NF}' $TMP`
if [ "$mac" != "" ] ; then
expect remove_mac_on_port_sticky.exp $port $mac
fi
}
This function removes a MAC ID from a port. The function first looks which MAC ID is available on the port.
reset(){
port=$1
expect reset_port.xpct $port
}
down(){
port=$1
expect down_port.xpct $port
}
These functions reset a port (shut, no shut) or just shut the port.
quit=no while [ $quit = no ] ; do clear disp echo "d for shut down a port" echo "n for new MAC id" echo "r for reset port" echo "q for quit" echo "enter for refresh" read line case a$line in (ar) echo -n "Port nummer : " read line reset $line ;; (ad) echo -n "Port nummer : " read line down $line ;; (an) echo -n "Port nummer : " read line rmmac $line ;; (aq) quit=yes ;; esac done sudo pkill tail exit
The main loop presents a simple menu.