Michael McNamara https://blog.michaelfmcnamara.com technology, networking, virtualization and IP telephony Fri, 22 Apr 2022 17:42:47 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.3 Let’s Encrypt SSL Wildcard Certificate https://blog.michaelfmcnamara.com/2022/04/lets-encrypt-ssl-wildcard-certificate/ https://blog.michaelfmcnamara.com/2022/04/lets-encrypt-ssl-wildcard-certificate/#comments Fri, 22 Apr 2022 17:42:47 +0000 https://blog.michaelfmcnamara.com/?p=7363

In July of 2020 I wrote about the relative cheap cost of a standard SSL certificate from RapidSSLonline in an article titled, “Your certificate expires in 1 day!!!“. While standard SSL certificates were available for ~ $14.99/year at the time the cost of a wildcard SSL certificate is considerably more expensive than a standard SSL certificate. In December 2021 the wildcard SSL certificate that I use on this site was set to expire so I made the decision to try Let’s Encrypt.

I’m happy to report that it’s been an extremely painless adventure with the only caveat being that I had to manually renew the SSL certificate every 90 days. After some research I found that really isn’t an issue thanks to Martijn Veldpaus. Martin has written some scripts that help bring together certbot and the API calls to GoDaddy, I’m using GoDaddy as my domain registrar and as my DNS provider, to perform the DNS verification that’s required by Let’s Encrypt to prove that you own the domain.

I’m saving myself about $149/year by using Let’s Encrypt instead of a traditional Certificate Authority.

If you are a GoDaddy customer looking for an extremely easy way to setup the automated renewal of your wildcard SSL certificates with Let’s Encrypt I would strongly suggest you check out Martin’s github repository Certbot-Godaddy.

Cheers!

]]>
https://blog.michaelfmcnamara.com/2022/04/lets-encrypt-ssl-wildcard-certificate/feed/ 2
Story – Packet Loss and Failing 10Gbps SFP+ Optic https://blog.michaelfmcnamara.com/2019/07/story-packet-loss-and-failing-10gbps-sfp-optic/ Sat, 06 Jul 2019 16:55:18 +0000 https://blog.michaelfmcnamara.com/?p=6182 Here’s an old story that I never published.. and seeing that I haven’t been writing much lately I’m going to take the easy route and just publish this.

It’s been another interesting weekend… and by interesting I actually mean another weekend of working through yet another challenging issue.

Summary

It started back on Thursday with more than a few alerts from my own custom built monitoring solution. A few years back I wrote a Bash script to help monitor the Internet facing infrastructure and numerous VIPs that we host in our Data Centers. That script has worked well over the years helping validate application availability against network availability. With everything else going on I purposely ignored the alerts, assuming there was some DoS attack or other malady that the Internet was suffering from and it would soon fix itself.  By late Friday afternoon I could no longer ignore the alerts as they were pilling up in my Inbox by the hundreds and it was long past time to roll up the sleeves and figure out what had broken where. I initially assumed that I would find some issue or problem with either the hosting company or an Internet Service Provider. A cursory review of the Internet border routers revealed that a few 10Gbps Internet links had bounced within the past 30 days but everything was running clean from the Internet Service Provider through our border routers, switches and firewalls up to our Internet facing load balancers. Initially I thought there was an issue with either AT&T or NTT as a number of the monitoring servers were traversing those ISPs but after a number of tests I found that packet loss across either of those ISPs was generally less than 0.4% which isn’t all that bad. If the plumbing was looking good then why were the alerts firing? I looked at the alert again and noticed that the messages read “socket timeout” and not “socket connection failure”.

In any event I ran a quick packet trace using tcpdump from one of the monitoring servers and found that there was traffic flowing, although there was a significant amount of retransmissions and missing packets. It looked like the health checks were timing out at the default of 10 seconds. I increased the timeout to 20 seconds and bingo the majority of health checks were now returning successfully. I’m not sure I agree with the verbiage of “socket timeout” since the socket was exchanging information between the client and server, it was more of an overall application timeout since the request was not completed with the specified timeout value.

Data Analysis

Now the $1,000,000 question, what had changed that I needed to increase the timeout?

Thankfully I’ve been logging this data for the past 3+ years so I was able to import of a few of the data points since Sept 2017 (207K rows – 1 every 60 seconds) into Excel and using the quick chart shortcut (Alt-F1) I was able to quickly visualize the data which provided some interesting results. The amount of time it was taking the health checks to complete had risen significantly in the past few weeks.

With that data it was now clear that the health checks were failing because they were hitting the 10 second default timeout. But what had happened that it was now taking on average longer than 10 seconds for the backend to return the result to the client? Was the backend slower to respond that it had previously been? Was the Internet slower than it had previously been? Was there enough packet loss and retransmissions to impact the timing? Was the size of the data being returned changing?

In short the answer appears to be a little bit of everything above.

  • Was the backend slower to respond that it had previously been? Yes
  • Was the Internet slower than it had previously been? Yes (I always assuming the Internet is getting more and more congested)
  • Was there enough packet loss and retransmissions to impact the timing? Yes (especially with 3K+ miles between the endpoints)
  • Was the size of the data being returned changing? Yes (the size of the HTML was increased causing more data to be transferred)

An interesting but logical side affect, the monitoring servers that were the farthest from the Data Center in question had a greater number of errors. This is logical because they would have the greater latency to reach that specific Data Center, any packet loss or retransmissions would cause additional delay given the latency. This explains why some monitoring servers were reporting no issues or problems and others were reporting all sorts of issues and problems. The increased physical distance between the Data Center and the monitoring server was exacerbating the timing because of the inherit packet loss and retransmissions on the Internet which was further exacerbated by the growing size of the HTML that was being transferred across those vast distances and increased time it was taking the backend to ultimately serve up the response.

This is a great example of why you can’t always just blame the network, even though it’s the easiest thing to do.

Resolution

In the end I found a failing 10Gbps SFP in the Internet facing load-balancers that needed to be replaced. I placed a monitoring probe on the local network and found the same amount of packet loss and re-transmissions which confirmed that the problem was local to my Data Center. I failed over between the primary and secondary Internet facing load-balancers and the problem disappeared so the issue was with the primary Internet facing load-balancer.

Cheers!

]]>
Response: Scripting Does Not Scale For Network Automation https://blog.michaelfmcnamara.com/2014/07/response-scripting-does-not-scale-for-network-automation/ https://blog.michaelfmcnamara.com/2014/07/response-scripting-does-not-scale-for-network-automation/#comments Mon, 21 Jul 2014 21:06:32 +0000 http://blog.michaelfmcnamara.com/?p=4446 About three weeks ago Greg Ferro from Etherealmind posted an article entitled “Scripting Does Not Scale For Network Automation“. It’s quite clear from reading the article that Greg really is “bitter and jaded“.  While I agree that there are challenges in scripting they also come with some large rewards for those that are able to master the skill.

In a subsequent comment Greg really hits on his point.. “We need APIs for device consistency, frameworks for validation and common actions. But above that we need platforms that solve big problems – scripting can only solve little problems.

I agree but for now we need to work with what we have available, and that’s no reason to stop scripting today. That said scripting is not a tool that’s going to solve every problem in IT. It might helpful for initial deployments, provisioning, backups, monitoring, testing, etc. but it’s rare that scripting will solve every problem. I personally employ a combination of commercial management solutions with scripting to achieve my goals. I’ve worked with the following methods and technologies: EXPECT/TCL, SNMP, PHP, PERL, XML, NETCONF. These all have their individual challenges but each can be used in their own fashion to help automate a task or process depending on the task or the vendor in question. If you need to-do something once or twice there’s no need for a script or automation, but if you are going to-do something daily or weekly across dozens or hundreds of assets then a script can be extremely helpful.

The point of writing a script is really two fold in my opinion, first to automate the task but more importantly to remove the human error element. I do a lot of my work in the wee morning hours when the eyes are bloodshot and the mind isn’t always as rested as it should be. It’s easy to make simple stupid mistakes repeating monotonous commands on dozens even hundreds of switches or routers. A script helps to actually do the work and it makes sure that I won’t accidentally blow something up, I’m really there just to monitor for problems or issues.

It should be no surprise that there’s effort required to maintain a script, it’s just like a commercial vendor maintaining a product. Here’s the changelog for a Perl script I maintained between 2003 and 2014  that utilized SNMP and TFTP against Avaya/Nortel, Cisco, Motorola/Symbol and HP gear. You can see some of the challenges that Greg referred to in his article;

# Changes:
#
#     May 04, 2011 (M.McNamara) added support for HP C-Class GbE2c and legacy P-Class GbE2
#                               thanks to Karol Perkowski for his code addition
#     Dec 28, 2010 (M.McNamara) added additional code to support ERS4500 being slow TFTP transfer
#     Dec 27, 2010 (M.McNamara) updated CISCO-PRODUCTS-MIB to cover ciscoCBS3120 blade
#     Dec 20, 2010 (M.McNamara) updated ASCII routine with OID s5AgSysAsciiConfigManualUpload
#     Aug 31, 2010 (M.McNamara) added routines to handle binary and ASCII data for Avaya ERS switches
#				also added code to keep 4 archive copies per device
#     Dec 02, 2009 (M.McNamara) cleaned up code added additional debug routines
#     Oct 23, 2008 (M.McNamara) added support for Motorola RFS7000 Wireless LAN Switch
#     Oct 22, 2008 (M.McNamara) added support for ASCII configuration files for Avaya ERS switches
#     Oct 10, 2008 (M.McNamara) added support for Cisco switches
#     Jan 22, 2008 (M.McNamara) added support for HP GbE2c (C-Class) switch
#     Apr 24, 2007 (M.McNamara) added support for WS5100 3.x software
#     Oct 24, 2006 (M.McNamara) added support for ERS1600 v2.1 release
#     Sep 29, 2006 (M.McNamara) added support for BayStack 470 PwR 48T
#     Oct 20, 2005 (M.McNamara) added support for Baystack 5510 24 port also added 
#				Ethernet Routing Switch (formerly Passport) 8600 code
#     Mar 01, 2005 (M.McNamara) incorporated a sub to check for the presence of the
#				proper filename on the TFTP server (/tftpboot) thereby 
#				eliminating the first script "readytftpbackup.pl"
#     Feb 25, 2005 (M.McNamara) added the ability to retry a failed backup
#     Jan 13, 2004 (M.McNamara) some minor bugs throughout code base
#     Jan 06, 2004 (M.McNamara) implemented a workaround for the Passport RAPID-CITY MIB 
#				> 3.2 problem, copied OIDs for Passport 1600 into 
#				 existing MIB along with required MIBS and added sub 
#				to handle 1600s
#     Jan 05, 2004 (M.McNamara) issues with SNMP MIB for Passport 8600 v3.3.4 is presenting
#				problems with the Net-SNMP perl modules and the old MIB 
#				cannot identify the newly added Passport 1600 switches.
#     Dec 11, 2003 (M.McNamara) resolved issue with Passport 8600 not backing up properly
#     Sep 17, 2003 (M.McNamara) added code to incorporate all BayStack switches into backup
#     Oct  1, 2003 (M.McNamara) added code to email status report to notify@acme.org
#				also added Perl script to weekly crontab

Will the scripts I write today be useless in two years, possibly but that’s pretty much the case with anything these days including your phone, your laptop, etc. While we wait for something else to come along the the scripts I write and maintain will be very helpful in making my job easier and making me more efficient.

Cheers!

PS: I’ve finally cleaned up the Scripting section of my blog, fixing all the broken links and updating all the code.

]]>
https://blog.michaelfmcnamara.com/2014/07/response-scripting-does-not-scale-for-network-automation/feed/ 1
Expect Automation Examples https://blog.michaelfmcnamara.com/2014/03/expect-automation-examples/ https://blog.michaelfmcnamara.com/2014/03/expect-automation-examples/#comments Wed, 26 Mar 2014 00:49:02 +0000 http://blog.michaelfmcnamara.com/?p=4304 I’ve been working for my new employer for just under 90 days now, carefully studying the network topology slowly pealing back the layers mindful not to break anything. There have been some exciting moments not including the Cisco Catalyst 6509 VSS member that decided to go into recovery mode one evening – revealing a cabling problem with a pair of Cisco ASA 5585-X running in an HA configuration.

A few weeks back I had the opportunity to show off some of my scripting skills by automating the configuration change of some 450+ Motorola RFS4000 and Symbol WS2000 Wireless LAN Switches. We were migrating from Microsoft’s Internet Authentication Service (IAS) to Microsoft’s Network Policy Service (NPS).

The first problem, nobody had an inventory of the wireless LAN switches that we needed to reconfigure. No problem – a quick dump of the logs on the IAS servers provided a nice lengthy list of IP addresses which had authenticated with IAS over the past 6 months. I wrote a quick Perl script to interrogate each IP address, first via ICMP, then via SNMP, and lastly via WGET/CURL.  The result was a list of each model switch we had to contend with along with the software versions; WS2000 v1.x, RFS4000 v4.x and RFS4000 v5.x . There weren’t too many RFS4000 v5.x switches so we decided to handled those changes manually, although on retrospect it would have been far easier to also code that solution as opposed to manually logging into all those WiNG 5.x devices at 4AM in the morning.

I did have a challenge with the passwords. There were multiple administrator passwords in use across all the different models so I had to add some logic to deal with the three different possible passwords. It was good that there were only three passwords because a fourth failed password attempt would cause the wireless LAN switch to disconnect the session and would have made the task a lot harder .

I ended up writing two scripts, one for the WS2000 v1.x and one for the RFS4000 v4.x due to the time constraints. I could have combined the two scripts and detected the version of software but there were some anxious managers waiting eagerly on this change. I added a bash shell script to kick off the Expect script for each switch model and then loop through all the IP addresses or FQDNs.

This wasn’t a sexy solution by any means, it required a bit of testing to determine the commands that were needed for each model and software release but it was a much better solution than manually making the changes on some 450+ devices. We did have to-do a bit of error checking to make sure that the configurations went down to all 450+ devices. We had one or two instances where the WAN connection to that specific office just happen to go offline while the script was running. Thankfully we were able to use the logfile size (logs generated by the Expect script) as a quick determination if there had been a problem or discrepancy that required additional investigation.

If you have a similar challenge hopefully you’ll find the code below helpful.

Symbol WS2000 v1.x

run-ws2000.sh

#!/bin/bash
#
# Language: Bash Shell Script
#
# Filename: /usr/local/etc/run-ws2000.sh
#
# Purpose:  This script will kickoff the Expect scripts that will re-configure 
#           the RADIUS configuration on the Motorola (formerly Symbol) WS-2000
#           Wireless LAN Switches.
#
# Author:   Michael McNamara
# Date:     February 21, 2014
# Version:  1.0
#
# Changes:
#

# Variables
PATH_TO=/usr/local/etc/
EXPECT=/usr/local/etc/symbolws2000radius.exp
SWITCHES='10.1.1.1 10.1.1.2 10.1.1.3 10.1.1.4'

##########################################################################
# M  A I N   S C R I P T  B O D Y
##########################################################################

for SWITCH in $SWITCHES
do
	$EXPECT $SWITCH
done

exit

symbolws2000radius.exp

#!/usr/bin/expect -f
#
# Language: Expect
#
# Filename: /usr/local/etc/symbolws2000radius.exp
#
# Purpose:  This is an Expect script that will login to a Motorola (formerly
#           Symbol) WS2000 Wireless LAN Switch v1.x and modify the RADIUS servers
#           used for 802.1x EAP authentication of the corporate ESSID/WLAN.
#
# Author:   Michael McNamara
#
# Date:     February 21, 2014
#
# Version:  1.0
#
# Changes:
#           February 24, 2014 (M.McNamara) v1.1 - issue with enable prompt changing,
#               abstract prompt in a varaible to account for all possibilities.
#
# License:
#           Copyright (C) 2010 Michael McNamara (mfm@michaelfmcnamara.com)
#
#           This program is free software: you can redistribute it and/or modify
#           it under the terms of the GNU General Public License as published by
#           the Free Software Foundation, either version 2 of the License, or
#           (at your option) any later version.
#
#           This program is distributed in the hope that it will be useful,
#           but WITHOUT ANY WARRANTY; without even the implied warranty of
#           MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#           GNU General Public License for more details.
#
#           You should have received a copy of the GNU General Public License
#           along with this program.  If not, see <http://www.gnu.org/licenses/>.

# Variables

set PATH "/usr/local/etc"
set TELNET "/usr/bin/telnet"

set SWITCH [lindex $argv 0]
set USERNAME admin
set PASSWORDS {password1 password2 password3}
set PINDEX 0

# Which Wireless LAN are we going to change?
set WLAN_IDX 2

# RADIUS/NPS Servers
set RADIUS1 10.1.1.1
set RADIUS2 10.1.1.2

set PROMPTS "(%|#|cli\>|admin\>|\$|\-\-\-\>)"

set TODAY [timestamp -format %y%m%d ]
set WEEKDAY [timestamp -format %a ]
set DATE [timestamp -format %c ]

stty -echo

log_file $PATH/logs/$SWITCH.radius.log
log_user 0	# Disable logging to STDOUT
#log_user 1	# Enable logging to STDOUT

# Useful information out to logfile
send_log "*********************************************************************\r\n"
send_log "Starting logfile for $SWITCH on $DATE\r\n"
send_log "*********************************************************************\r\n"

set timeout 30
spawn $TELNET $SWITCH

expect {
	"Connected to" {

		expect "login:"
		send -- "$USERNAME\r"
		expect -exact "assword:"
		send -- "[lindex $PASSWORDS $PINDEX]\r"

		expect {
			"Login incorrect" {
				send_user "\nDEBUG: Login failed with $USERNAME [lindex $PASSWORDS $PINDEX] on $SWITCH\n"
				send_log "\nDEBUG: Login failed with $USERNAME [lindex $PASSWORDS $PINDEX] on $SWITCH\n"

				incr PINDEX
				if {$PINDEX == [llength $PASSWORDS]} {
					send_user "ERROR: PASSWORD ISSUE WITH $SWITCH - UNABLE TO LOGIN!\n" 
					send_log "*********************************************************************\r\n"
					send_log "End of logfile for $SWITCH on $DATE \r\n"
					send_log "*********************************************************************\r\n"
					exit	
				}

				expect "login:"
				send -- "$USERNAME\r"
				expect -exact "assword:"
				send -- "[lindex $PASSWORDS $PINDEX]\r"

				exp_continue
			}
			"admin>" {
				send -- "network\r"
				expect -re $PROMPTS
				send -- "wlan\r"
				expect -re $PROMPTS
				send -- "show eap $WLAN_IDX\r"
				expect -re $PROMPTS

				####################################################################
				# REMOVE THE FOLLOWING # FROM THE FILE TO ACTUALLY MAKE THE CHANGES
				####################################################################
				# REMOVE THE FOLLOWING # FROM THE FILE TO ACTUALLY MAKE THE CHANGES
				####################################################################

				send -- "set eap server $WLAN_IDX 1 $RADIUS1\r"
				expect -re $PROMPTS
				send -- "set eap server $WLAN_IDX 2 $RADIUS2\r"
				expect -re $PROMPTS
				send -- "show eap $WLAN_IDX\r"
				expect -re $PROMPTS
				send -- "save\r"
				expect -re $PROMPTS

				####################################################################

				send -- "quit\r"
				expect eof
			}
		}

	}

	"No route to host" {
		send_log "ERROR: Unable to connect to $SWITCH via telnet!\n"
		send_user "ERORR: Unable to connect to $SWITCH via telnet!\n"
	}

}

send_log "*********************************************************************\r\n"
send_log "End of logfile for $SWITCH on $DATE \r\n"
send_log "*********************************************************************\r\n"

exit 0

Motorola RFS4000 v4.x

run-rfs4000.sh

#!/bin/bash
#
# Language: Bash Shell Script
#
# Filename: /usr/local/etc/run-rfs4000.sh
#
# Purpose:  This script will kickoff the Expect scripts that will re-configure 
#           the RADIUS configuration on the Motorola RFS 4000 v4.x
#           Wireless LAN Switches.
#
# Author:   Michael McNamara
# Date:     February 21, 2014
# Version:  1.0
#
# Changes:
#
#

# Variables
PATH_TO=/usr/local/etc
EXPECT=/usr/local/etc/motorolarfs4000radius.exp
SWITCHES='10.1.1.1 10.1.1.2 10.1.1.3 10.1.1.4'

##########################################################################
# M  A I N   S C R I P T  B O D Y
##########################################################################

for SWITCH in $SWITCHES
do
	$EXPECT $SWITCH
done

exit

motorolarfs4000radius.exp

#!/usr/bin/expect -f
#
# Language: Expect
#
# Filename: /usr/local/etc/motorolarfs4000radius.exp
#
# Purpose:  This is an Expect script that will login to a Motorola (formerly
#           Symbol) RFS4000 Wireless LAN Switch v4.x and modify the RADIUS servers
#           used for 802.1x EAP authentication of the corporate ESSID/WLAN.
#
# Author:   Michael McNamara (mfm@michaelfmcnamara.com)
#
# Date:     February 21, 2014
#
# Version:  1.1
#
# Changes:
#	    February 25, 2014 (M.McNamara) v1.1 - disable StrictHostKeyChecking so the
#		the initial SSH connection doesn't generate a yes/no dialog which
#		could hang up the Expect script.
#
#           February 24, 2014 (M.McNamara) v1.0 - issue with enable prompt changing, 
#		abstract prompt in a varaible to account for all possibilities.
#
# License:
#           Copyright (C) 2014 Michael McNamara (mfm@michaelfmcnamara.com)
#
#           This program is free software: you can redistribute it and/or modify
#           it under the terms of the GNU General Public License as published by
#           the Free Software Foundation, either version 2 of the License, or
#           (at your option) any later version.
#
#           This program is distributed in the hope that it will be useful,
#           but WITHOUT ANY WARRANTY; without even the implied warranty of
#           MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#           GNU General Public License for more details.
#
#           You should have received a copy of the GNU General Public License
#           along with this program.  If not, see <http://www.gnu.org/licenses/>.

# Variables

set PATH "/usr/local/etc"
set TELNET "/usr/bin/telnet"
set SSH "/usr/bin/ssh"

set SSH_OPTIONS "-o StrictHostKeyChecking=no"

set SWITCH [lindex $argv 0]
set USERNAME admin
set PASSWORDS {password1 password2 password3}
set PINDEX 0

# Which Wireless LAN are we going to change?
set WLAN_IDX 2

# RADIUS/NPS Servers
set RADIUS1 10.1.1.1
set RADIUS2 10.1.1.2

set PROMPTS "(%|#|cli\>|admin\>|\$|\-\-\-\>)"

set TODAY [timestamp -format %y%m%d ]
set WEEKDAY [timestamp -format %a ]
set DATE [timestamp -format %c ]

stty -echo

# Setup the logging
log_file $PATH/logs/$SWITCH.radius.log
log_user 0	# Disable logging to STDOUT
#log_user 1	# Enable logging to STDOUT

# Useful information out to logfile
send_log "*********************************************************************\r\n"
send_log "Starting logfile for $SWITCH on $DATE\r\n"
send_log "*********************************************************************\r\n"

# Set the timeout to 30 seconds for the following commands
set timeout 30

# Spawn an SSH connection to the switch
spawn $SSH $SSH_OPTIONS $USERNAME@$SWITCH

expect {
	"yes/no" {
		send "yes\r" }

	"User Access Verification" {

		expect "*?sername:"
		send -- "$USERNAME\r"
		expect -exact "assword:"
		send -- "[lindex $PASSWORDS $PINDEX]\r"

		expect {
			"Incorrect Login" {
				send_user "\nDEBUG: Login failed with $USERNAME [lindex $PASSWORDS $PINDEX] on $SWITCH\n"
				send_log "\nDEBUG: Login failed with $USERNAME [lindex $PASSWORDS $PINDEX] on $SWITCH\n"

				incr PINDEX
				if {$PINDEX == [llength $PASSWORDS]} {
					send_user "ERROR: PASSWORD ISSUE WITH $SWITCH - UNABLE TO LOGIN!\n" 
					send_log "*********************************************************************\r\n"
					send_log "End of logfile for $SWITCH on $DATE \r\n"
					send_log "*********************************************************************\r\n"
					exit	
				}

				expect "*?sername:"
				send -- "$USERNAME\r"
				expect -exact "assword:"
				send -- "[lindex $PASSWORDS $PINDEX]\r"

				exp_continue
			}
			">" {
				send -- "terminal length 0\r"
				expect -re $PROMPTS
				send -- "enable\r"
				expect -re $PROMPTS
				send -- "show wireless mobile-unit\r"
				expect -re $PROMPTS
				send -- "show wireless wlan config $WLAN_IDX\r"
				expect -re $PROMPTS

				#####################################################################
				# REMOVE THE FOLLOWING # FROM THE FILE TO ACTUALLY MAKE THE CHANGES
				#####################################################################
				# REMOVE THE FOLLOWING # FROM THE FILE TO ACTUALLY MAKE THE CHANGES
				#####################################################################

				send -- "config t\r"
				expect -re $PROMPTS
				send -- "wireless\r"
				expect -re $PROMPTS
				send -- "wlan $WLAN_IDX radius server primary $RADIUS1\r"
				expect -re $PROMPTS
				send -- "wlan $WLAN_IDX radius server secondary $RADIUS2\r"
				expect -re $PROMPTS
				send -- "exit\r"
				expect -re $PROMPTS
				send -- "show wireless wlan config $WLAN_IDX\r"
				expect -re $PROMPTS
				send -- "write mem\r"
				expect -re $PROMPTS

				#####################################################################

				send -- "quit\r"
				expect eof
			}
		}

	}

	"No route to host" {
		send_log "ERROR: Unable to connect to $SWITCH via telnet!\n"
		send_user "ERORR: Unable to connect to $SWITCH via telnet!\n"
	}

}

send_log "*********************************************************************\r\n"
send_log "End of logfile for $SWITCH on $DATE \r\n"
send_log "*********************************************************************\r\n"

exit 0

Cheers!

]]>
https://blog.michaelfmcnamara.com/2014/03/expect-automation-examples/feed/ 1
Cisco Nexus Switch Backups with Perl SNMP https://blog.michaelfmcnamara.com/2010/09/cisco-nexus-switch-backups-perl-snmp/ https://blog.michaelfmcnamara.com/2010/09/cisco-nexus-switch-backups-perl-snmp/#comments Wed, 01 Sep 2010 14:00:22 +0000 http://blog.michaelfmcnamara.com/?p=1602 I’ve spent some time over the past few days trying to get our home grown Perl script designed to backup all our network switches to work with the Cisco Nexus 7010 and 5010 switches.

With previous Cisco switches such as the 6509, 3750, 2960, etc we know that the following commands (when sent via a Perl script using the Net-SNMP Perl module) would instruct the switch to copy it’s running-config to a TFTP server.

snmpset -v1 -c$COMMUNITY $HOST ccCopyProtocol.$RANDOM i 1
snmpset -v1 -c$COMMUNITY $HOST ccCopySourceFileType.$RANDOM i 4
snmpset -v1 -c$COMMUNITY $HOST ccCopyDestFileType.$RANDOM i 1
snmpset -v1 -c$COMMUNITY $HOST ccCopyServerAddress.$RANDOM a "10.1.1.50"
snmpset -v1 -c$COMMUNITY $HOST ccCopyFileName.$RANDOM s "sw-train-acme.cfg"
snmpset -v1 -c$COMMUNITY $HOST ccCopyEntryRowStatus.$RANDOM i 1
sleep 5
snmpget -v1 -c$COMMUNITY $HOST ccCopyState.$RANDOM
#if not successful sleep 3 and re-check ccCopyState else continue and destroy table entry
snmpset -v1 -c$COMMUNITY $HOST ccCopyEntryRowStatus.$RANDOM i 6

I know that the both the Cisco Nexus 7010 and 5010 both balk at the SNMP OIDS/MIBS used above. So I’m searching for a set of equivalent SNMP OIDS/MIBS as those in CISCO-CONFIG-COPY-MIB for NX-OS. I’m not sure that such a OID/MIB even exists for NX-OS but it doesn’t hurt to search and ask.

I’m curious if anyone else has come across this issue? I know that there is an XML interface available but I would prefer to keep using the PERL/SNMP script that I’ve already developed. In the interim I’ll probably write an Expect script (or add some Expect code to my existing Perl script) to remotely connect to the switches and issue the appropriate copy commands.

Cheers!

Updated: Monday June 27, 2011

I’ve finally found the issue and now I’m able to backup the Cisco Nexus switches as expected.
[ad name=”ad-articlefooter”]

]]>
https://blog.michaelfmcnamara.com/2010/09/cisco-nexus-switch-backups-perl-snmp/feed/ 29
ASCII Configuration Generator (ACG) for Nortel Switches https://blog.michaelfmcnamara.com/2008/10/ascii-configuration-generator-acg-for-nortel-switches/ https://blog.michaelfmcnamara.com/2008/10/ascii-configuration-generator-acg-for-nortel-switches/#comments Tue, 28 Oct 2008 02:00:28 +0000 http://blog.michaelfmcnamara.com/?p=478 I wrote a Perl script a long time ago to backup the binary configuration files for all our Nortel Ethernet and Ethernet Routing Switches (including BayStack 350 and 450s, Ethernet Switch 460 and 470s, Ethernet Routing Switch 4500s and Ethernet Routing Switch 5500s, Ethernet Routing Switch 1600 and 8600s along with Motoroal WS5100 and RFS7000s and HP GbE2s). The Perl script was very simple and straightforward. The problem was that the Nortel configuraiton files were binary files that we as engineers were unable to review or analyze. There were no tools (at least not that I’m aware of) that could allow us to review those configurations. If we had a question about the configuration stored in the binary file we had to restore the configuration to a mock up switch(s) in our testlab in order to be able to review the actually configuration. It seems that Nortel finally heard our cries for help and added a new feature in v3.7.x (ES460/ES470) and v5.1.x (ERS5500) software that would allow us to TFTP upload the ASCII configuration from the ACG.

There was one problem though… the SNMP OID has yet to be documented in the Nortel SNMP MIBS. I had to run a packet trace against Nortel’s Device Manager to determine the OID that Device Manager was using to initiate the manual config upload. I found that the OID was ”
1.3.6.1.4.1.45.1.6.4.4.19.0″

I took my existing script and created a new subroutine and had everything working within about 30 minutes.

Here’s some of the code I wrote;

############################################################################
# Subroutine baystack_tftp_config_ascii
#
# Purpose: use SNMP to instruct BayStack switches to TFTP upload their
# ASCII configuration file to the central TFTP server
############################################################################
sub baystack_tftp_config_ascii {

#s5AgSysTftpServerAddress
#s5AgSysAsciiConfigFilename
#s5AgSysAsciiConfigManualUpload (NOT IN THE MIBS) USE 1.3.6.1.4.1.45.1.6.4.4.19.0
# snmpset -v2c -cprivate 10.1.1.100 1.3.6.1.4.1.45.1.6.4.4.19.0 i 4

   # Declare Local Variables
   my $setresult;

   $filename = "ascii/".$filename;

   my $sess = new SNMP::Session (  DestHost  => $snmphost,
                                   Community => $community,
                                   Version   => SNMPVER );

   my $vars = new SNMP::VarList(
                        ['s5AgSysTftpServerAddress', 0, "10.1.1.20",],
                        ['s5AgSysAsciiConfigFilename', 0, $filename,] );

   my $go = new SNMP::VarList(
                        ['.1.3.6.1.4.1.45.1.6.4.4.19', 0, 4, 'INTEGER'] );

   &check_filename($filename);

   # Set TFTP source and destination strings
   $setresult = $sess->set($vars);
   if ( $sess->{ErrorStr} ) {
      print "ERROR: {BayStack} problem setting the TFTP parameters (TFTP IP, FILENAME) for $snmphost\n";
      print "ERROR: {BayStack} sess->{ErrorStr} = $sess->{ErrorStr}\n";
   }

   # Start TFTP copy
   $setresult = $sess->set($go);
   if ( $sess->{ErrorStr} ) {
      print "ERROR: {BayStack} problem setting the TFTP action bit for $snmphost\n";
      print "ERROR: {BayStack} sess->{ErrorStr} = $sess->{ErrorStr}\n";
   }

   # Pause while the TFTP copy completes
   sleep $PAUSE;

   # Check to see if the TFTP copy completed
   $setresult = $sess->get('.1.3.6.1.4.1.45.1.6.4.4.19.0');
   if ( $sess->{ErrorStr} ) {
      print "ERROR: problem checking the TFTP result for $snmphost\n";
      print "ERROR: sess->{ErrorStr} = $sess->{ErrorStr}\n";
   }

   # If TFTP failed output error message
   if ($setresult != 1) {
        while ($setresult == 2) {
           print "DEBUG: config upload status = $setresult (waiting)\n" if (DEBUG);
           sleep $PAUSE;
           $setresult = $sess->get('.1.3.6.1.4.1.45.1.6.4.4.19.0');
        } #end while
   } #end if $test ne "success"

   # If the upload command failed let's try again
   if ($setresult == 3) {

      print "DEBUG: initial command returned $setresult\n" if (DEBUG);
      print "DEBUG: lets try the upload command again\n" if (DEBUG);

      # Let's pause here for a few seconds since the previous command failed
      sleep $PAUSE;

      # Start TFTP copy
      $setresult = $sess->set($go);
      if ( $sess->{ErrorStr} ) {
         print "ERROR: problem setting the TFTP action bit for $snmphost\n";
         print "ERROR: sess->{ErrorStr} = $sess->{ErrorStr}\n";
      }

      # Pause while the TFTP copy completes
      sleep $PAUSE;

      # Check to see if the TFTP copy completed
      $setresult = $sess->get('.1.3.6.1.4.1.45.1.6.4.4.19.0');
         if ( $sess->{ErrorStr} ) {
            print "ERROR: problem checking the TFTP result for $snmphost\n";
            print "ERROR: sess->{ErrorStr} = $sess->{ErrorStr}\n";
      }

      # If TFTP failed output error message
      if ($setresult != 1) {
         while ($setresult == 2) {
            print "DEBUG: config upload status = $setresult (waiting)\n" if (DEBUG);
            sleep $PAUSE;
            $setresult = $sess->get('.1.3.6.1.4.1.45.1.6.4.4.19.0');
         } #end while
      } #end if
   } #end if

   if ($setresult != 1) {
      print "DEBUG: $snmphost config upload *FAILED*!\n";
      print SENDMAIL "ERROR:$snmphost ($sysObjectID) config (ASCII) upload *FAILED*!
\n";
   } elsif ($setresult == 1) {
      print SENDMAIL "$snmphost ($sysObjectID) was successful (ASCII)
\n";
      print "DEBUG: $snmphost ($sysObjectID) was successful (ASCII)\n";
   } else {
      print "DEBUG: unknown error return = $setresult (ASCII)" if (DEBUG);
   } #end if

   print "DEBUG: upload config file results = $setresult (ASCII)\n" if (DEBUG);

   return 1;

} #end sub baystack_tftp_config_ascii

Cheers!
Update: Friday April 10, 2009

I’ve discovered a small issue using the MIB “s5AgSysAsciiConfigFilename”. While the MIB says the value can be between 0..128 characters long I’ve actually found that the value can’t be an longer than 30 characters. If you try to use a filename that is greater than 30 characters you’ll get an SNMP set error. I actually had quite a few switches failing to backup properly because I was prepending “ascii/” to the filename. I tested this with software v3.7.2.x and v3.7.3.x on a Ethernet Switch 470.

s5AgSysAsciiConfigFilename OBJECT-TYPE
        SYNTAX  DisplayString (SIZE (0..128))
        MAX-ACCESS      read-write
        STATUS  current
        DESCRIPTION
                "Name of the ascii configuration file that will be
             downloaded/uploaded either at boot time when the
             s5AgSysAsciiConfigAutoDownload object is set to
             useConfig(3), or when the s5AgSysAsciiConfigDownloadStatus
             object is set to startDownload(4).  When not used, the
             value is a zero length string."
        ::= { s5AgentSystem 6 }

Cheers!

]]>
https://blog.michaelfmcnamara.com/2008/10/ascii-configuration-generator-acg-for-nortel-switches/feed/ 12
Expect Scripts for ERS8600 Troubleshooting https://blog.michaelfmcnamara.com/2008/09/expect-scripts-for-ers8600-troubleshooting/ https://blog.michaelfmcnamara.com/2008/09/expect-scripts-for-ers8600-troubleshooting/#comments Sat, 06 Sep 2008 13:00:54 +0000 http://blog.michaelfmcnamara.com/?p=410 Whenever you contact Nortel, Cisco or Juniper support these days your going to need to spend some time and effort collecting a fair amount of information for the engineer assigned to your case.

I’ve written a very simple Expect script that will telnet into a Nortel Ethernet Routing Switch 8600 and issue a series of commands saving all the output so you can forward it to Nortel (or examine it yourself offline).

#!/usr/bin/expect -f
#
# Filename: /usr/local/etc/8600dump.exp
#
# Purpose:  Dump technical information from Nortel Ethernet Routing Switch
#           via telneting to the device and issuing various "show" cmds.
#           The output will then be saved to the working directory using
#           a filename based on the switch name used to call the script.
#
# Language: Expect
#
# Author:   Michael McNamara
#
# Date:     May 6, 2003
#
# Changes:
#
#   Sept 29, 2006: cleaned up script/updated documentation
#    Dec 30, 2005: added command line arguments for portability
#    Mar 18, 2005: added file logging for troubleshooting and monitoring
#    May 20, 2003: fine tuned script removing a great many "expect" commands.
#    May  6, 2003: original Expect script generated from auto_expect
#
# Notes:
#        Command Line Reference;
#          ./8600dump.exp <switch> <username> <password>
#
# This Expect script was generated by autoexpect on Thu Aug 18 10:57:50 2005
# Expect and autoexpect were both written by Don Libes, NIST.
#
# 

set force_conservative 0  ;# set to 1 to force conservative mode even if
              ;# script wasn't run conservatively originally
if {$force_conservative} {
    set send_slow {1 .1}
    proc send {ignore arg} {
        sleep .1
        exp_send -s -- $arg
    }
}

#
# Declare Global Variables
#
set PATH "/usr/local/etc/"
set TELNET "/usr/bin/telnet"

#
# Assign Command Line Variablbes
#
set SWITCH [lindex $argv 0]
set USERNAME [lindex $argv 1]
set PASSWD [lindex $argv 2]

#
# Time Date Stamp
#
set TODAY [timestamp -format %y%m%d ]
set WEEKDAY [timestamp -format %a ]
set DATE [timestamp -format %c ]

set send_human {.1 .3 1 .05 2}

######################################################################
# proc usage
#
# Purpose: display the usage information to the enduser.
######################################################################
proc usage {} {
    send_user "\n"
    send_user "ERROR: command line paramaters incorrect\n"
    send_user "\n"
    send_user "usage: 8600dump.exp <switch> <username> <password>\n"
    send_user "\n"
    send_user "    switch        the DNS or IP address of switch    \n"
    send_user "    username        the username for login to the switch    \n"
    send_user "    password        the password for username\n"
    send_user "\n"
    send_user "\n"
    exit
}
#######################################################################

#######################################################################
# M A I N    P R O G R A M
#######################################################################

if {[llength $argv]!=3} usage

log_file $PATH/$SWITCH.dump.log
log_user 0      # Disable logging to STDOUT
#log_user 1     # Enable logging to STDOUT

# Useful information out to logfile
send_log "******************************************************************\r\n"
send_log "* STARTING LOGFILE FOR $SWITCH ON $DATE         \r\n"
send_log "******************************************************************\r\n"

set timeout -1
spawn $TELNET $SWITCH
match_max 100000
expect "Connected to"
expect "Login: "
send -- "$USERNAME\r"
expect "Password: "
send -- "$PASSWD\r"
expect -re "\:.\#|> "

# DATE
send -- "date\r"
expect -re "\:.\#|> "

####################################################
# YOU CAN ADD AND REMOVE COMMANDS AS YOU SEE FIT
####################################################

# CONFIG CLI MORE FALSE
send -- "config cli more false\r"
expect -re "\:.\#|> "

# SHOW TECH
send -- "show tech\r"
expect -re "\:.\#|> "

# SHOW CONFIG
send -- "show config\r"
expect -re "\:.\#|> "

# SHOW SYS TOPO
send -- "show sys topo\r"
expect -re "\:.\#|> "

# SHOW
send -- "show ports error show-all\r"
expect -re "\:.\#|> "

# SHOW PORT ERROR MAIN
#send -- "show port error main\r"
#expect -re "\:.\#|> "

# SHOW PORT ERROR EXT
#send -- "show port error ext\r"
#expect -re "\:.\#|> "

# SHOW IP ROUTE INFO ALTERNATIVE
#send -- "show ip route info alternative\r"
#expect -re "\:.\#|> "

# SHOW IP BGP SHOW-ALL
#send -- "show ip bgp show-all\r"
#expect -re "\:.\#|> "

# DATE
send -- "date\r"
expect -re "\:.\#|> "

send -- "logout\r"
expect eof

#######################################################################
# E N D    P R O G R A M
#######################################################################

You can also download the complete Expect script from my website here.

Occasionally you might have multiple switches that you’ll need to interrogate and for that I’ve written a quick and dirty little Bash shell script to loop through the FQDN of the switches calling the Expect script above.

#!/bin/sh
#
# Filename: /usr/local/etc/8600dump.sh
#
# Purpose:  Dump technical information from Nortel Ethernet Routing Switch
#           via telneting to the device and issuing various "show" cmds.
#           The output will then be saving to the working directory using
#           a filename based on the switch name used to call the script.
#
# Language: Bash Script
#
# Author:   Michael McNamara
#
# Date:     May 6, 2003
#
# Changes:
#
#   Sept 29, 2006: cleaned up script/updated documentation
#    Dec 30, 2005: added command line arguments for portability
#    Mar 18, 2005: added file logging for troubleshooting and monitoring
#    May 20, 2003: fine tuned script removing a great many "expect" commands.
#    May  6, 2003: original Expect script generated from auto_expect
#
# Notes:
#        Command Line Reference;
#          ./8600dump.sh
#
# There are system and network specific variables below. Obviously the "PATH"
# to the location of the Bash script and supporting Expect script. The location
# of MUTT if email is used and most importantly the username and password to the
# Nortel Ethernet Routing Switch 8600. I would highly suggest using the ro (ReadOnly)
# account for all scripting purposes that are "read-only" in nature. The last most
# obvious piece is the list of switches that you'd like the script run against.
#

# Global Variables
PATH_TO=/usr/local/etc/mlh
DUMP=8600dump.exp
MAIL_LIST=''
PAGER_LIST=''
ERROR_FLAG=0
MAILEXE='/usr/bin/mutt'
MAILTXT='/tmp/mutt.txt'
LOCKFILE=/tmp/trace.lck
USERNAME=ro
PASSWORD=

SWITCHES='switch1.domain switch2.domain'

#############################################################################
#  B E G I N   M A I N
#############################################################################

for SWITCH in $SWITCHES
do
    $PATH_TO/$DUMP $SWITCH $USERNAME $PASSWORD
    $MAILEXE -s "ALERT: Dump Report for $SWITCH" $MAIL_LIST -a $PATH_TO/$SWITCH.trace.log < $MAILTXT
done

exit
#############################################################################
#  E N D   M A I N
#############################################################################

You can also download the complete shell script here.

The use of Expect really helps save me a lot of time and it speeds up the troubleshooting process with the vendor.

Cheers!

]]>
https://blog.michaelfmcnamara.com/2008/09/expect-scripts-for-ers8600-troubleshooting/feed/ 1
Expect Script – Daylight Saving Time https://blog.michaelfmcnamara.com/2008/07/expect-script-daylight-saving-time/ https://blog.michaelfmcnamara.com/2008/07/expect-script-daylight-saving-time/#comments Sun, 13 Jul 2008 21:00:09 +0000 http://blog.michaelfmcnamara.com/2008/07/expect-script-daylight-saving-time/ O\'Reilly Exploring Expect[ad name=”ad-articlebodysq”]In one of my previous posts entitled, Network Time Protocol (NTP), I discussed how to setup a network time protocol sever and how to configure the Nortel Ethernet Switch and Ethernet Routing Switches for NTP including Daylight Saving Time (DST) support.

I recently received a message from someone looking for someway to automated the re-configuration of over 100 switches with the correct Daylight Saving Time configuration. I explained to the person that the best long term solution would probably be to use the SNMP MIB but a quick and dirty solution might be to use Expect and call it from a Bash script looping over all the switches that needed to be re-configured. In short Expect is a scripting language that mimics user input at a TTY.  The Except script is written to issue a set of commands, as if a human were typing them, and expects various responses.

The script I wrote below only support a limited number of switches. If you have a particular switch you’re welcome to modify the script to support that particular switch. The script will attempt to determine if the switch is running the software that has the features we’re looking to implement. I didn’t have a whole lot of time to test so buyer beware!

Here’s the expect script that I authored;

#!/usr/bin/expect -f
#
##############################################################################
#
# Filename: /usr/local/etc/set-nortel-timezone.exp
#
# Purpose:  Expect script designed to telnet into Nortel Ethernet Switches
#           and execute the CLI commands to confgure the appropriate timezone
#           information, including Day Light Saving time.
#
# Switches: Ethernet Switch 460 v3.7.x
#           Ethernet Switch 470 v3.7.x
#           Ethernet Switch 4500 v5.2.x
#           Ethernet Switch 5500 v5.1.x
#
# Author:   Michael McNamara
#
# Date:     June 1, 2008
#
# Version:  1.1
#
# Changes:
#
#           June 8, 2008 (M.McNamara)
#           - added documentation and ARGV command line checks
#           June 14, 2008 (M.McNamara)
#           - added check for switch version and exit if v3.6 switch software
#           - added check for Username introduced in v3.7 switch software
#
#
##############################################################################
#
# This Expect script was generated by autoexpect on Wed Jul 27 17:25:28 2005
# Expect and autoexpect were both written by Don Libes, NIST.
#
set force_conservative 1  ;# set to 1 to force conservative mode even if
                          ;# script wasn't run conservatively originally
if {$force_conservative} {
        set send_slow {1 .1}
        proc send {ignore arg} {
                sleep .1
                exp_send -s -- $arg
        }
}

if {[llength $argv] != 2} {

   puts "usage: set-nortel-timezone.exp < SWITCH > < PASSWORD >>"

exit 1

}

#
set PATH "/usr/local/etc/"
set TELNET "/usr/bin/telnet"

set SWITCH [lindex $argv 0]
set PASSWORD [lindex $argv 1]

set TODAY [timestamp -format %y%m%d ]
set WEEKDAY [timestamp -format %a ]
set DATE [timestamp -format %c ]

set send_human {.1 .3 1 .05 2}

#log_file $PATH/$SWITCH.expect.log
log_file /usr/local/etc/password.expect.log
log_user 0      # Disable logging to STDOUT
#log_user 1     # Enable logging to STDOUT

set timeout 10
spawn $TELNET $SWITCH
match_max 100000

expect "Trying"
expect {
   "Connected"  {

      expect "SW:v3.6" {
         send_log "\n\nThis version of software doesn't support the CLI commands!\n"
         send_user "\n\nThis version of software doesn't support the CLI commands!\n"
         exit 1
      }
      sleep 1
      send -- ""
                }
   Timeout      {
      send_log "We're unable to connect to the switch $SWITCH"
      send_user "We're unable to connect to the switch $SWITCH"
      exit 1;
                }
}

expect {
   "Username"   {
      send -- "RW\r"
   }
}

expect "Enter Password"
send -- "$PASSWORD\r"

expect {
   "Main Menu"  {
                }
   "Incorrect Password" {
      send_log "$SWITCH : Incorrect Password"
      exit 1
   }
   "Incorrect Credentials" {
      send_log "$SWITCH: Incorrect Credentials"
      exit 1
   }
}
sleep 1

# Let's get into the CLI interface from the menu prompts
send -- "C"

# Depending on the version of software we sometimes need a CR/LF
send -- "\r"
sleep 1

# Let's wait for the CLI prompt which includes the #
expect "#"
send -- "config term\r"
send -- "clock time-zone EST -5\r"
send -- "clock summer-time EDT date 9 Mar 2008 2:00 2 Nov 2008 2:00 +60\r"
send -- "exit\r"
send -- "logout\r"
expect eof

You can download the entire Expect script from this URL; set-nortel-timezone.exp.

The command line arguments are fairly straight forward;

usage: set-nortel-timezone.exp <SWITCH> <PASSWORD>

Where the SWITCH is the fully qualified domain name (FQDN) or the IP address of the switch in question and the PASSWORD is the Read-Write password for the switch.

If you had hundreds of switches to reconfigure you could wrap this Except script in a Bash shell script similar to the following;

#!/bin/bash
#
#####################################################################
#
# Language: Bash Shell Script
#
# Filename: /usr/local/etc/set-nortel-timezone.sh
#
# Purpose:  This script will kickoff the Expect script that will
#           configure the Daylight Saving Time features for each switch
#
# Author:   Michael McNamara
#
# Date:     June 1, 2008
#
# Version:  1.0
#
# Changes:
#
#           June 10, 2006 (M.McNamara)
#           -  added remote sites into shell script processing
#
#####################################################################
#

# Variables
PATH_TO=/usr/local/etc
UPGRADE=set-nortel-timezone.exp
MAIL_LIST=''
PAGER_LIST=''
ERROR_FLAG=0
MAILEXE='/usr/bin/mutt'
LOCKFILE=/tmp/trace.lck

# Check paramaters
if [ "$#" != 2 ]
then
  echo "Usage: `basename $0` <password>"
  exit 1
fi

PASSWORD=$1

#####################################################################
#####################################################################
# YOU SHOULD EDIT THE "SWITCHES" VARIABLE BELOW TO INCLUDE ALL THE
# SWITCHES THAT YOU WISH TO HAVE THE EXPECT SCRIPT RUN AGAINST
#####################################################################
#####################################################################

SWITCHES='sw1-5520.acme.org sw2-5520.acme.org sw3-5520.acme.org'

for SWITCH in $SWITCHES
do
        $PATH_TO/$UPGRADE $SWITCH $PASSWORD
done

exit

You can download the Bash shell script from this URL; set-nortel-timezone.sh.

I’ve only tested this on CentOS v5.2 but it should work on any Linux host with Expect installed although you may need to modify the path locations.

Cheers!

]]>
https://blog.michaelfmcnamara.com/2008/07/expect-script-daylight-saving-time/feed/ 7
WiFi Hotspot Portal https://blog.michaelfmcnamara.com/2007/11/wifi-hotspot-portal/ https://blog.michaelfmcnamara.com/2007/11/wifi-hotspot-portal/#comments Tue, 20 Nov 2007 01:00:00 +0000 http://maddog.mlhs.org/blog/2007/11/wifi-hotspot-portal/ A few years ago I had a request to design a public WiFi hotspot portal for the patients and visitors within our five major facilities. I did a fair amount of research and found a number of interesting commercial and open-source solutions. Unfortunately none of them really filled our requirements or caught my fancy. So I embarked on building/coding our own solution using a wide array of open-source software that was already available. Since I was most familiar with Perl at the time I chose to code the solution using Perl and Javascript (browser side) using Linux as the operating system of choice.

I needed to provide a public WiFi hotspot across our existing corporate wireless infrastructure at our five major sites. It obviously needed to be secure from our internal network, it needed to be 100% automated (there were no resources available to support this offering) and it needed to work (there’s a surprise requirement). We also needed to keep internal (corporate) laptops and wireless devices from connecting to the unencrypted network and circumventing current Internet access policies.

Because of security concerns I decided to only allow HTTP (TCP 80) and HTTPS (TCP 443) traffic from the public wireless network. I also tabled any ideas of content/URL filtering from the original design. Instead we would reliable on Blue Coat ProxySG/ProxyAV appliances and Websense to perform content filtering and AV scanning of the traffic in a later upgrade.

How did we do it?
We carved out an ESSID (“public”) from our Motorola Wireless LAN infrastructure at each facility. We setup the wireless network without any encryption or security so as to minimize any end-user difficulties in connecting to the wireless network. We took CentOS and built a WiFi portal server/gateway/firewall/router using an HP Proliant DL360. We essentially turned our Linux server into a cheap and very efficient firewall/gateway for the WiFi Hotspot. We connected one NIC of the Linux server to the wireless WLAN and the other to our internal network. This allowed use to use the Linux server to provide IP addresses to the wireless devices through DHCP. It also allowed use to have the Linux server provide DNS for name resolution. And most importantly it allowed use to use IPtables to provide firewalling between the wireless network and our internal network. This solution also allowed us to implement bandwidth shaping/throttling to prevent the public WiFi Hotspot wireless users from utilizing too much of our Internet link (DS-3 ~ 45Mbps).

Once a device associates with the wireless network the Linux portal server will issue the device a DHCP address from the 192.168.16.0/20 network. When the user opens their web browser they will be redirected to the Linux portal web server and the registration page as it appears below;

Once the user clicks on the “I AGREE” button the Linux server will kick off the “register.pl” script to check the IP/MAC address and decide if they should be granted access. If they are granted access they will be redirected to our Internet homepage after which they’ll be free to surf to any URL. If the user is denied access they will be directed to an error page.

It is also possible that the user may attempt to register multiple times due to their web browser caching the portal page contents as the contents of a legitimate Internet website. Example: A user opens their web browser to www.cnn.com and is greeted with the portal page. User registers that is then re-directed to www.acme.org. The user then types www.cnn.com back into the browser address bar, but instead of getting the legit content for the CNN website the user is greeted again by the portal page. The user not knowing any better clicks the “I AGREE” button for the second time in as many minutes. Previously this problem would have gone on and on over and over, now the system will detect that the user is already registered and will through an error alerting the user to “refresh” their web browser. In order to refresh the browser the user should just type in the URL of the website they are attempting to visit and click “Go” (or hit “enter”). If they are greeted with the portal page they should click the “refresh” button from the browser button bar. That will instruct the web browser to ignore any cached content and attempt to retrieve all the data direct from the source website.

Every night at midnight the firewall rules will be reset to the defaults. Requiring any that wishes to access the WiFi Hotspot to agree to the AUP again. This is done to prevent folks from continually sitting/camping on the WiFi Hotspot.

Initially I thought we might be able to use a VPN or GRE tunnel to connect the five public WLANs to a single Linux server. Unfortunately I was a little ahead of the times and VPN/GRE tunnels were just starting to be supported in the various wireless switches (Motorola in this case). So I decided to take an easier approach and installed five HP Prolaint DL360 servers, one for each site.

I’m very happy to report that the solution works very well and virtually supports itself.

The only issue that we’ve seen is the need to continually update the blacklist file to keep corporate wireless devices from connecting to the public network. Thankfully I’ve written a small Bash Shell script to help with that process.

I hope to write a more detailed account of how to set this up on my website sometime in the future. If your interested in hearing more or have questions please drop me a line.

Cheers!

]]>
https://blog.michaelfmcnamara.com/2007/11/wifi-hotspot-portal/feed/ 1
Perl Scripting https://blog.michaelfmcnamara.com/2007/10/perl-scripting/ https://blog.michaelfmcnamara.com/2007/10/perl-scripting/#comments Sat, 27 Oct 2007 17:50:00 +0000 http://maddog.mlhs.org/blog/2007/10/perl-scripting/ I really like using Perl because of the Net-SNMP Perl libraries that make it really easy to write code to interact with devices that support SNMP.

Hopefully everyone out there is backing up their network switch configurations in the unlikely event that if their hardware dies they only need to worry about replacing the hardware and not about re-configuring the entire switch.

Quite a few years back I wrote a Perl script that would send the proper SNMP commands to instruct a network switch to copy it’s configuration to a TFTP server. This script essentially became known as “switchtftpbackup.pl” It’s nothing fancy or pretty but it gets the job done.

I’ve posted this Perl script on my webiste under the Perl section.

I run this script from Cron one of our CentOS Linux servers at work every week. The same server also acts as a central TFTP server for the entire organization. I also run other scripts that then archive the weekly backups, in the event that I need to go to a backup that’s more than a week old.

I believe both Nortel’s Optivity NMS and Cisco’s Cisco Works both have options to backup switch configurations these days.

What are you using?

Cheers!

]]>
https://blog.michaelfmcnamara.com/2007/10/perl-scripting/feed/ 11