Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
#!/usr/bin/perl -w # $Id: pancho-unstable,v 1.30 2001/10/09 03:30:11 charles Exp $ ## PANCHO ## copyright 2001 Charles J. Menzes ## http://pancho.lunarmedia.net/ ## send bugs to : pancho-bugs@lunarmedia.net ## send feature requests to : pancho-request@lunarmedia.net ## send questions to : pancho-help@lunarmedia.net ## send everything else to : pancho@lunarmedia.net ## module calls use strict; use Net::SNMP; use Getopt::Long; use Socket; use POSIX qw(strftime); use Sys::Hostname; use Fcntl ':flock'; ############ THE FOLLOWING VARIABLES NEED TO BE EDITED ############ ############ SPECIFIC TO YOUR ENVIRONMENT. PLEASE READ ############ ############ THROUGH THE HOWTO DOCUMENT PROVIDED WITH ############ ############ THIS SCRIPT TO ENSURE YOU ARE USING THE ############ ############ CORRECT INFORMATION AND FORMAT REQUIRED. ############ my $community = ''; # your RW snmp community string my $tftpserver = ""; # ip/hostname/fqdn of your tftpserver my @routers = qw(); # list of routers my $logging = ""; # set this to "1" to enable logging my $logfile = ""; # full path to your logfile ############ NO FURTHER EDITING SHOULD BE REQUIRED. ############ ############ DOING SO IS AT YOUR OWN RISK. ############ ## development variables my $rcs = (qw$Revision: 1.30 $)[-1]; ## ensure some arguments are given die "\nPancho requires some flags to be specified.\nPlease try running + $0 --help\n\n" unless (@ARGV); ## command line options my $upload; my $download; my $filename; my $commit; my $list; my $host; my $string; my $version; my $old; my $server; my $regex; my $help; my $verbose; my $path; my $show; my $start; my $reload; my $query; GetOptions ( 'upload' => \$upload, 'download' => \$download, 'filename=s' => \$filename, 'commit' => \$commit, 'list=s' => \$list, 'host=s' => \$host, 'server=s' => \$server, 'string=s' => \$string, 'version' => \$version, 'old' => \$old, 'regex=s' => \$regex, 'help' => \$help, 'verbose-help' => \$verbose, 'path=s' => \$path, 'show' => \$show, 'startup' => \$start, 'reload' => \$reload, 'query' => \$query, ); ## set up oids my $rand = strftime("%S", localtime); my %oid = ( ## cisco-config-copy-mib method => ".1.3.6.1.4.1.9.9.96.1.1.1.1.2.$ran +d", source => ".1.3.6.1.4.1.9.9.96.1.1.1.1.3.$ran +d", destination => ".1.3.6.1.4.1.9.9.96.1.1.1.1.4.$ran +d", ipaddress => ".1.3.6.1.4.1.9.9.96.1.1.1.1.5.$ran +d", filename => ".1.3.6.1.4.1.9.9.96.1.1.1.1.6.$ran +d", rowstatus => ".1.3.6.1.4.1.9.9.96.1.1.1.1.14.$ra +nd", ## deprecated lsystem mibs wrnet => ".1.3.6.1.4.1.9.2.1.55.", confnet => ".1.3.6.1.4.1.9.2.1.53.", ## universal platform wrmem => ".1.3.6.1.4.1.9.2.1.54.0", ## univeral platform reload => ".1.3.6.1.4.1.9.2.9.9.0", ## universal platform version => ".1.3.6.1.2.1.1.1.0", ); my %filelocation = ( tftp => "1", start => "3", run => "4", ); ## logging format and time my %clock; my $user; my $hostname; my $format; if ($logging) { my %clock = ( month => strftime("%b", localtime), day => strftime("%d", localtime), time => strftime("%H:%M:%S", localtime), ); my $user = getpwuid($<); my $hostname = hostname(); my $format = "$clock{month} $clock{day} $clock{time} [$hostname] pan +cho:"; } ## show version and exit &version if ($version); ## show verbose help menu and exit &verbose if ($verbose); ## show the help menu and exit &usage if ($help); ## show set parameters and exit &showinfo if ($show); ## build out count for error checking my $count = 0; $count++ if ($upload); $count++ if ($download); ## ensure that we have a node or list of nodes if ($host) { push(@routers, $host); } elsif ($list) { open(FH, $list); @routers = <FH>; close(FH); } elsif ( $#routers < 0 ) { print "\nYou have not specified a node or list of nodes to act upon! +\n\n" unless ($count == 0); exit(1); } ## determine the path within the tftproot my $tftppath = $path || "/"; ## determine if we are using the default server or another $tftpserver = $server if ($server); ## resolve fqdn/hostname for tftpserver if ($tftpserver =~ /[a-zA-Z]/) { my $i = gethostbyname($tftpserver); $tftpserver = inet_ntoa($i); } ## determine if we are using the default community string or another $community = $string if ($string); ## check to ensure that we have the information required if (!$community) { print "\nYou have not specified an SNMP community.\n\n"; exit(1); } elsif (!$tftpserver && ($upload || $download)) { print "\nYou have not specified a tftp server.\n\n"; exit(1); } if ($upload && $count == 1) { if (!$filename) { print "\nIn order to tftp a configuration to a remote device\nyou +must indicate a specific filename using -f.\n\n"; exit(1); } else { if ($start) { &execute('tftp','start'); } else { &execute('tftp','run'); } } } elsif ($download && $count == 1) { if ($start) { &execute('start','tftp'); } else { &execute('run','tftp'); } } elsif ($commit) { &execute('wrmem',0); } elsif ($reload) { &execute('reload',0); } else { print "\nYou cannot upload and download at the same time.\n\n" unless ($count == 0); } ## subroutines sub version { print "\n This is Pancho version $rcs\n\n"; exit; } sub execute { ## pull source and destination of files my $source = shift; my $destination = shift; ## declare variable for array of failed hosts my @failed; ## open log file for writing and put cursor at end of file if ($logging) { open(FH, ">>$logfile") or die "Cant open the logfile! : $!\n"; flock(FH,2); seek(FH,0,2); } ## for my $host(@routers) { chomp $host; ## test to see if host resolves to ip address my $z = gethostbyname($host); unless ($z) { ## if not, push host name into failed list push (@failed, $host); ## skip to next host in list next unless ($z); } ## test to see if hostname fits regex description next if (($regex) and ($host !~ /$regex/)); ## if sending file to tftpserver set file to $host.cfg $filename = "$host.cfg" if ($destination eq "tftp"); ## query for ios version if necesssary if ($count > 0) { if ($query) { ## set up initial parameters for this nodes snmp session(s) my $s = Net::SNMP->session( -hostname => $host, -community => $community ); ## grab the ios major revision number my $ios_version = $s->get_request ($oid{version}); ## close the snmp session $s->close; if (($ios_version->{$oid{version}}) =~ /Version 11/) { &deprecated($host,$source,$destination); } else { &ccCopy($host,$source,$destination); } } else { &ccCopy($host,$source,$destination); } } ## write config to memory if ($commit) { ## start session my $s = Net::SNMP->session( -hostname => $host, -community => $community ); ## write to memory $s->set_request($oid{wrmem}, INTEGER, "1"); ## close session $s->close; ## log output to screen and possibly external file &log_action($host,'wrmem',0,0); } ## reload the router if ($reload) { ## start the session my $s = Net::SNMP->session( -hostname => $host, -community => $community ); ## reload the router $s->set_request($oid{reload}, INTEGER, "2"); ## close the session $s->close; ## log output to screen and possibly external file &log_action($host,'reload',0,0); } } print "\nThe following hosts could not be resolved: @failed\n\n" if (@failed); flock(FH,8) if ($logging); close(FH) if ($logging); exit; } sub deprecated { my $host = shift; my $source = shift; my $destination = shift; if (($source eq "start") or ($destination eq "start")) { print "\nCopying configurations to and from startup-config\nis not + possible using deprecated mibs.\n\n"; } else { my $mib; ## set up proper value for $mib if ($source eq "tftp") { $mib = $oid{confnet}; } else { $mib = $oid{wrnet}; } $mib = "$mib$tftpserver"; my $s = Net::SNMP->session( -hostname => $host, -community => $community ); ## set up the request $s->set_request($mib, OCTET_STRING, "$tftppath/$filename"); ## grab an error if it exists. my $error = $s->error; ## close snmp session $s->close; ## log output to screen and possibly external file &log_action($host, $source, $destination, $error); } } sub ccCopy { my $host = shift; my $source = shift; my $destination = shift; ## start up an snmp session my $s = Net::SNMP->session( -hostname => $host, -community => $community ); ## copy files across network $s->set_request ( ## select method of transfer $oid{method}, INTEGER, 1, ## select source file location $oid{source}, INTEGER, $filelocation{$source}, ## select destination file location $oid{destination}, INTEGER, $filelocation{$dest +ination}, ## set tftpserver ip address $oid{ipaddress}, IPADDRESS, $tftpserver, ## set the filename being written $oid{filename}, OCTET_STRING, "$tftppath$filena +me", ## set the session status $oid{rowstatus}, INTEGER, 4, ); ## grab an error message if it exists my $error = $s->error; ## close the snmp session $s->close; ## log output to screen and possibly external file &log_action($host, $source, $destination, $error); sub log_action { my $host = shift; my $source = shift; my $destination = shift; my $error = shift; if ($error) { ## log to screen print "\n$error\n\n"; ## log to external file print FH "$format $error" if ($logging); } elsif ($source eq "tftp") { if ($destination eq "run") { ## log to screen print "\nSuccessfully copied config to $host from $tftpserver\n\ +n"; ## log to external file print FH "$format config <$filename> copied from $tftpserver to +$host by $user\n" if ($logging); } elsif ($destination eq "start") { ## log to screen print "\nSuccessfully copied config to nvram on $host from $tftp +server\n\n"; ## log to external file print FH "$format config <$filename> copied from $tftpserver to +nvram on $host by $user\n" if ($logging); } } elsif ($destination eq "tftp") { if ($source eq "run") { ## log to screen print "\nSuccessfully copied config to $tftpserver from $host.\n +\n"; ## log to external file print FH "$format config copied to $tftpserver from $host by $us +er\n" if ($logging); } elsif ($source eq "start") { ## log to screen print "\nSuccessfully copied config to $tftpserver from nvram on + $host.\n\n"; ## log to external file print FH "$format config copied to $tftpserver from nvram on $ho +st by $user\n" if ($logging); } } if ($source eq "wrmem") { ## log to screen print "\nSuccessfully wrote config to memory on $host.\n\n"; ## log to external file print FH "$format config copied to nvram on $host by $user\n" if ($logging); } if ($source eq "reload") { ## log to screen print "\nSuccessfully initialized a reload of $host.\n\n"; ## log to external file print FH "$format initialization of reload on $host by $user\n" if ($logging); } } sub usage { print <<USAGE; options [ --upload | --download | --commit ] [ --filename <filename> ] [ --list <list> ] [ --host <hostname> ] [ --server <ip/fqdn/hostname> ] [ --string <snmp community> ] [ --path <path within tftproot> ] [ --regex <regular expression> ] [ --query ] [ --start ] [ --show ] [ --version ] [ --verbose-help ] [ --help ] requires [ perl, net::snmp ] USAGE exit(0); } sub showinfo { if ($tftpserver) { print "\nYour tftpserver is currently set to : $tftpserver\n"; } else { print "\nYou do not have a default tftpserver value set.\n"; } if ($community) { print "Your SNMP community is currently set to : $community\n"; } else { print "You do not have a default SNMP community value set.\n"; } if ( $#routers < 0 ) { print "\nThere are no nodes listed in your default list of routers +.\n\n"; } else { print "\nThe following nodes are in your default list of routers:\ +n"; for my $node( sort @routers) { print " $node\n"; } print "\n"; } exit; } sub verbose { print <<USE; NAME pancho SYNOPSIS options [ --upload | --download | --commit ] [ --filename <filename> ] [ --list <list> ] [ --host <hostname> ] [ --server <ip/fqdn/hostname> ] [ --string <snmp community> ] [ --path <path within tftproot> ] [ --regex <regular expression> ] [ --query ] [ --start ] [ --show ] [ --version ] [ --verbose-help ] [ --help ] requires [ perl, net::snmp ] DESCRIPTION pancho was written with the goal of allowing network admnistrators make a change to a group of cisco routers without being required to log into each host. pancho also provides the flexibility to allow admins to use its function against a single host, a select group or the entire whole. in addition to changes to current configurations on remote routers, pancho is also capable of archiving router configurations manually or through automated runs. OPTIONS -u, --upload specify that pancho send a configuration file TO the remote device(s). -d, --download specify that pancho retrieve a configuration file FROM the remote device(s). -c. --commit specify that pancho perform a 'write memory' or 'copy run start' on the remote device(s). -f, --filename specify the local filename that pancho should send to the remote device. -l, --list specify a local file that hold a list of device hostnames or ip addresses that pancho should perform actions against. --host specify an individual host on which pancho will perform actions. --server specify a tftp server that pancho will push or pull configurations to and from. this may be in the format of an ip address, a fully qualified domain name, or a hostname able to be resolved by the machine upon which pancho is being ran. --string specify a snmp read-write string. -p, --path specify a path within the tftproot. -r, --regex specify a regular expression that pancho can use to filter out specific hosts from the host file that actions should be taken against. --query script will determine whether older deprecated cisco mibs should be used against remote host or newer versions. --start change source/destination to startup-config or the nvram of the remote router. this will essentially cause the router to either execute a "copy tftp startup-config" or "copy startup- config tftp". --show display a list of the current default settings. --version display the current version of pancho. --verbose-help this display --help short synopsis of flag options. USAGE getting started with pancho does not require much work, however some thought should be put into the process. pancho is capable of having a few default settings predefined that take effect each time pancho is ran. open pancho in your favorite text editor and look for the area near the beginning of the file that highlights three fields that can be updated with your specific information. The field $community, $tftpserver and \@routers all define their matching information. For $community and $tftpserver, simply put the corresponding strings between the quotes to the right of the equal sign. \@routers takes a bit more work, however it should not prove too difficult. this field should be populated with the group of devices that you feel will be configured or archived most often on your network. the devices can be entered by hostname or by ip address within the parentheses to the right of the equal sign. at least one single space should seperate each entry such that it may look like: \@routers = qw( border1 edge-5.lunarmedia.net 172.20.5.19 webfarm.ord 10.4.101.1 ); at first glance, pancho appears to have a significantly long command line. however, many of the option flags seen above can be set as default such that the flags themselves would only be called to override the default settings. for example a default tftpserver may be set within the pancho configuration, however you will still be able to specify: --server 172.16.254.16 in case you would like to push/pull your config to an alternate server. pancho can be set up to have a default group of nodes that it will affect when ran. this list can be altered by specifying the --host flag to indicate a single node or the --list flag which will let you direct pancho to read the group to be effected from a plain text file. this text file should have each node listed on its own line either by hostname or ip address. another method which allows pancho to further limit the group of devices touched is the --regex option. this feature is very powerful in the hands of someone with a fair amount of knowledge concerning regular expressions and nodes grouped with logical naming conventions. --regex ^core.* would indicate that within the default list of nodes, or within the list obtained from an external text file, only those with a name beginning in "core" would be affected. two flags which allow greater flexibility concerning the hosts being touched by pancho are --start and --query. using the --start flag will cause pancho to send/receive a configuration to/from a remote device's startup-config, or nvram, rather than from the machine's running-config. the caveat to the --start flag is that this operation can only be performed on devices using the newer cisco-copy- config mibs. this means that most ios revisions prior to 12.x will not allow it. for networks that do run in a mixed environment, using several different revisions of ios, which may cross major version numbers, the --query flag was added. since ios 11.x takes a different grouping of mibs than does 12.x you can run pancho against your group of nodes with the --query flag enabled. pancho will find out the major revision number from each remote device and run the operation against the node using the correct group of oid. without running --query, pancho will try to use the newer cisco mibs. the final optional flag is --filename. if unspecified, this value defaults to the hostname of the device being touched with an extension of ".cfg". the --filename flag argument should always be used when a single configuration file will be uploaded to a group of devices. additionally, --filename may be used to specify an entire path to a specific individual file within a subdirectory of the tftproot: --filename /cfg/2500/tacacs_config.txt in situations where you are not specifying a specific filename but would like your configs to be written/read from a director +y beneath the tftproot, --path allows you to specify an alternative: --path /cfg/7200 pancho's only mandatory flag is one of two options, --upload or --download. this specifies whether or not pancho will push a configuration to the router or pull the remote device's config down to the local tftp server. pancho lives remotely from the router and therefore views the world from that perspective. --upload signifies that a file will be uploaded TO the router. conversely, --download indicates that the config will be brought down FROM the router. the final option of --commit is used to perform a remote "write memory" or "copy run start". this option can be used either individually, or in conjunction with --upload essentially committing to memory the changes as they are being made. EXAMPLES in order to utilize pancho's full capacity for router configuration, one needs to be familiar with cisco's 'copy tftp run' or 'config net' syntax. in depth discussion on the procedure can be found on cisco's website at http://www.cisco.com. a summary of the process is as follows. a remote router will tftp a configuration file consisting of standard ios commands into its running-config. the router will merge the current running-config and the command options received from the text file and then apply the whole to its new running configuration. an example may better state the process. on the tftp server, we create a plain text file to update the access-list 5 on a group of remote routers. the plain text file, is as follows: ! no access-list 5 access-list 5 permit 10.6.21.64 0.0.0.31 access-list 5 permit 10.12.71.0 0.0.0.255 ! end since we plan on completely rewriting access-list 5 on the remote routers with this new acl, our first statement is 'no access-list 5' which allows us to start a new acl listing. the following acl statements will then build the new access-list. since cisco's 'copy tftp run' process first merges the current running-config and our plain text commands before it applies the newly created configuration, there will be no interruption in traffic being inspected by access- list 5. very different than just copying and pasting the same commands into the cisco command prompt which applies each statement with the hit of the carriage return allowing for the possibility of serious consequences. with knowledge of cisco's ios syntax, the possibilities for remote configuration are endless, and with pancho's capability for customization, an entire network may be updated or archived from a single point of management. the following a just a few of pancho's command line options in running syntax: update all routers with changes held in a flat file pancho -u -f acl_update.txt archive all router configurations locally pancho -d or to a remote tftp server pancho -d --server ns1.lunarmedia.net download a host's configuration to a directory within the tftproot called configs pancho -d --host rsm716.pdx --path /configs commit changes on a group of hosts held within an external file pancho --commit --list hostfile.txt send configuration changes to a group of devices with varying versions of ios pancho --upload --query --filename config.txt update all border routers with a new motd using an alternate snmp community pancho -u -f motd.txt --regex border --string f00B\@ +r CAVEATS pancho's power does come with some caveats that should not be considered lightly. pancho depends upon remote routers having a read-write(rw) snmp community string configured. since read-write strings offer full snmp control to a machine the potential for exploit could be high. it is HIGHLY recommended, if not considered mandatory by this author that all routers using rw snmp strings should have an acl configured to limit what machines can gain such access to the device. again, full documentation can be found on cisco's website, however a short synopsis is as follows: ! access-list specifying nodes that will be capable ! of using snmp access to routers access-list 10 permit host 10.10.220.78 access-list 10 permit 192.168.96.4 0.0.0.3 ! ! apply access-list to snmp community snmp-server community 9Eck#0-A rw 10 ! pancho also relies on the tftp protocol and server. files held within the tftproot and its subdirectories are generally world readable. moreover the tftp protocol does not inherently provi +de any method for user authentication. because of this, it is generally good measure to try to limit the nodes which have access to the tftp mechanism. this can be achieved through a local firewall specifying remote nodes or subnets that can push/pull to and from the tftpserver. with re +mote routers all belonging to different subnets, this would at firs +t seem tedious to set up and even worse to maintain. a common convention to combat this is to use loopback addresses from an aggregate on all remote devices. it is then possible to specif +y ip tftp source-interface Loopback 100 and ensure that all tftp requests coming in from remote device +s will have a predictable source address, that can be grouped in +to the aggregate. using this mechanism, a large group of routers numbered with Loopback addresses having /32 masks can be conso +lidated into a larger aggregate with a shorter mask allowing for less configuration within the firewall rules. one final caveat when using pancho is the new grouping of cisc +o mibs, cisco-copy-config. these mibs deprecate those used previ +ously with ios revision 11.x as a result pancho tries to compensate by allowing the adminis +trator access to both sets of mibs. some functionality available thro +ugh the newer set is not available through the older. the full details + of cisco's new oid, can be found at: http://www.cisco.com/warp/public/477/SNMP/copy_configs_snmp. +shtml COMMENTS Please send all comments regarding pancho to: pancho\@lunarmedia.net Check for new releases of pancho at: http://pancho.lunarmedia.net/ BUGS AUTHOR Charles J. Menzes <menzes\@lunarmedia.net> Pancho Copyright(C) 2001 USE exit(0); }

In reply to Pancho(configure/archive Cisco routers) by c

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (6)
As of 2024-03-28 15:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found