[rancid] Re: Understand some regex used in rancid

Lance Vermilion rancid at gheek.net
Fri Nov 14 18:37:23 UTC 2008


Are you running the IPS on a 6500 or on a ASA?

2008/11/14 Gregory W Zill <gregoryzill at solutionary.com>:
> Lance,
> I originally had "autoenable...0" and from there I went to "noenable" --
> upon your suggestion I just tried "autoenable...1" all have just about the
> same result. However, the "autoenable...1" with clogin does allow me to
> interact with the IPS, whereas the other settings freeze once logged in and
> I end up timing out back to the rancid host.
>
> Gregory,
>
> You need to set autoenable for that device inside your ".cloginrc".
> The IP puts you in privilege 15 when you login. I am guessing you do
> not have that specified so rancid is trying to enable.
>
> 2008/11/14 Gregory W Zill <gregoryzill at solutionary.com>:
>
>
> I get what appears to be a second user inputted somehow. Have you seen this?
> How might I fix? This is a 4215 IPS.
>
> $ clogin test_cisco_ips6
> test_cisco_ips6
> spawn ssh -c 3des -x -l cisco test_cisco_ips6
>
> Password:
> Last login: Fri Nov 14 09:07:54 2008 from 10.1.1.107
>
> cisco
> test_cisco_ips6# cisco
>                  ^
> % Invalid input detected at '^' marker
>
>
> BTW, the ipsrancid is great -- thank you
>
> Thx Max and John.
>
> As for making rancid work with IPS modules I have found that the post
> from Jeremy M. Guthrie
> "http://www.shrubbery.net/pipermail/rancid-discuss/2007-May/002209.html"
> does very well and doesn't require making a lot of changes to rancid
> to handle the errors that happen if you run too many commands that are
> invalid commands. I also eliminated the need for his ipslogin. I
> simply just had perl set the TERM to vt100 before it ran clogin and
> then set the TERM back to network after it was finished running
> clogin. I also fixed some typo's he had where it was the work "at"
> instead of "@". I fixed what should be skipped for the ShowVersion as
> it had some extra stuff that can change.
>
> Here is a copy of what I put on my webpage. http://www.gheek.net/?p=78
>
> In order to get rancid to collect the config from an IPS module you
> will need to make sure you have the correct login creds in the rancid
> users ".cloginrc", add the type of ips to "rancid-fe" and you also
> need to create the "ipsrancid" script.
>
> Changes required for "rancid-fe"
> 'ips'               => 'ipsrancid',
>
> Create the "ipsrancid" script as "<rancid_home>/bin/ipsrancid". Make
> sure you "chmod 755 <rancid_home>/bin/ipsrancid" and "chown
> <rancid_user>:<rancid_user> <rancid_home>/bin/ipsrancid".
> #! /usr/bin/perl
> ##
> ## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
> ## All rights reserved.
> ##
> ## This software may be freely copied, modified and redistributed
> ## without fee for non-commerical purposes provided that this license
> ## remains intact and unmodified with any RANCID distribution.
> ##
> ## There is no warranty or other guarantee of fitness of this software.
> ## It is provided solely "as is".  The author(s) disclaim(s) all
> ## responsibility and liability with respect to this software's usage
> ## or its effect upon hardware, computer systems, other software, or
> ## anything else.
> ##
> ## Except where noted otherwise, rancid was written by and is maintained by
> ## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin
> Schutz.
> ##
> #
> # hacked version of Hank's rancid - this one tries to deal with Hitachi's.
> #
> # Modified again by Lance Vermilion (11/13/08)
> # Modified from htrancid by Jeremy M. Guthrie
> # Created on 5/4/2007
> #
> #  This is meant to try handle Cisco's IPS V5.X line and on
> #
> #  RANCID - Really Awesome New Cisco confIg Differ
> #
> # usage: ipsrancid [-d] [-l] [-f filename | $host]
> use Getopt::Std;
> getopts('dfl');
> $log = $opt_l;
> $debug = $opt_d;
> $file = $opt_f;
> $host = $ARGV[0];
> $clean_run = 0;
> $found_end = 0;
> $timeo = 90;                            # clogin timeout in seconds
> my(@commandtable, %commands, @commands);# command lists
> my(%filter_pwds);                       # password filtering mode
>
> # This routine is used to print out the router configuration
> sub ProcessHistory {
>
>     ($new_hist_tag,$new_command,$command_string, @string) = (@_);
>     if ((($new_hist_tag ne $hist_tag) || ($new_command ne $command))
>         && defined %history) {
>         print eval "$command \%history";
>         undef %history;
>     }
>     if (($new_hist_tag) && ($new_command) && ($command_string)) {
>         if ($history{$command_string}) {
>             $history{$command_string} = "$history{$command_string}@string";
>         } else {
>             $history{$command_string} = "@string";
>         }
>     } elsif (($new_hist_tag) && ($new_command)) {
>         $history{++$#history} = "@string";
>     } else {
>         print "@string";
>     }
>     $hist_tag = $new_hist_tag;
>     $command = $new_command;
>     1;
> }
>
> sub numerically { $a <=> $b; }
>
> # This is a sort routine that will sort numerically on the
> # keys of a hash as if it were a normal array.
> sub keynsort {
>     local(%lines) = @_;
>     local($i) = 0;
>     local(@sorted_lines);
>     foreach $key (sort numerically keys(%lines)) {
>         $sorted_lines[$i] = $lines{$key};
>         $i++;
>     }
>     @sorted_lines;
> }
>
> # This is a sort routine that will sort on the
> # keys of a hash as if it were a normal array.
> sub keysort {
>     local(%lines) = @_;
>     local($i) = 0;
>     local(@sorted_lines);
>     foreach $key (sort keys(%lines)) {
>         $sorted_lines[$i] = $lines{$key};
>         $i++;
>     }
>     @sorted_lines;
> }
>
> # This is a sort routine that will sort on the
> # values of a hash as if it were a normal array.
> sub valsort{
>     local(%lines) = @_;
>     local($i) = 0;
>     local(@sorted_lines);
>     foreach $key (sort values %lines) {
>         $sorted_lines[$i] = $key;
>         $i++;
>     }
>     @sorted_lines;
> }
>
> # This is a numerical sort routine (ascending).
> sub numsort {
>     local(%lines) = @_;
>     local($i) = 0;
>     local(@sorted_lines);
>     foreach $num (sort {$a <=> $b} keys %lines) {
>         $sorted_lines[$i] = $lines{$num};
>         $i++;
>     }
>     @sorted_lines;
> }
>
> # This is a sort routine that will sort on the
> # ip address when the ip address is anywhere in
> # the strings.
> sub ipsort {
>     local(%lines) = @_;
>     local($i) = 0;
>     local(@sorted_lines);
>     foreach $addr (sort sortbyipaddr keys %lines) {
>         $sorted_lines[$i] = $lines{$addr};
>         $i++;
>     }
>     @sorted_lines;
> }
>
> # These two routines will sort based upon IP addresses
> sub ipaddrval {
>     my(@a) = ($_[0] =~ m#^(\d+)\.(\d+)\.(\d+)\.(\d+)$#);
>     $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
> }
> sub sortbyipaddr {
>     &ipaddrval($a) <=> &ipaddrval($b);
> }
>
> # This routine parses "show config"
> sub ShowConfig {
>     print STDERR "    In ShowConfig: $_" if ($debug);
>
>     $firstexit=0;
>
>     while (<INPUT>) {
>         tr/\015//d;
>         tr/\020//d;
>
>         #strip out the stupid spinning running-config progress thingy
>         s/Generating current config: \.*[\|\/\-\\]//gi;
>         $skipprocess=0;
>
>         #sometimes an 'exit' appears at the top of the config, we
> don't want them
>         if ( (/^exit/) && ( ! $firstexit ) ) {
>                 $firstexit=1;
>                 $skipprocess=1;
>         }
>
>         #remove spaces left over from lame spinning progress thingy
>         if ( /^\s+! ――――――――――/ ) {
>                 s/^\s+!/!/g
>         }
>
>         if (/^(read-only-community) / && $filter_pwds >= 1) {
>             ProcessHistory("","","","!$1 <removed>\n"); next;
>         }
>         if (/^(read-write-community) / && $filter_pwds >= 1) {
>             ProcessHistory("","","","!$1 <removed>\n"); next;
>         }
>         if (/^(trap-community-name) / && $filter_pwds >= 1) {
>             ProcessHistory("","","","!$1 <removed>\n"); next;
>         }
>         if (/^(ntp-keys \d+ md5-key) / && $filter_pwds >= 1) {
>             ProcessHistory("","","","!$1 <removed>\n"); next;
>         }
>         if (/^(password) / && $filter_pwds >= 1) {
>             ProcessHistory("","","","!$1 <removed>\n"); next;
>         }
>
>         last if (/^$prompt/);
>         next if (/^(\s*|\s*$cmd\s*)$/);
>         if ( ! /^$prompt/) {
>                 if ( ! $skipprocess ) {
>                         print STDOUT "      ShowConfig Data: $_" if
> ($debug);
>                         ProcessHistory("","","","$_");
>                 }
>         }
>     }
>     $clean_run=1;
>     print STDERR "    Exiting ShowConfig: $_" if ($debug);
>     return(0);
> }
>
> # This routine parses single command's that return no required info
> sub ShowVersion {
>     print STDERR "    In ShowVersion: $_" if ($debug);
>     ProcessHistory("","","","!\n!IPS Show Version Start\n");
>
>     while (<INPUT>) {
>         tr/\015//d;
>
>         $skipprocess=0;
>
>         if ( /^Sensor up-time/ ) { $skipprocess=1; }
>         if ( ( /using.*bytes of available/i ) ) { $skipprocess=1; }
>
>         last if (/^$prompt/);
>         next if (/^(\s*|\s*$cmd\s*)$/);
>         if ( ! /^$prompt/) {
>                 if ( ! $skipprocess ) {
>                         print STDOUT "      ShowVersion Data: $_" if
> ($debug);
>                         ProcessHistory("","","","! $_");
>                 }
>         }
>     }
>     ProcessHistory("","","","!\n!IPS Show Version End\n");
>     print STDERR "    Exiting ShowVersion: $_" if ($debug);
>     return(0)
> }
>
> # This routine parses single command's that return no required info
> sub ShowUsersAll {
>     print STDERR "    In ShowUsersAll: $_" if ($debug);
>     ProcessHistory("","","","!\n!IPS User Database Start\n");
>
>     while (<INPUT>) {
>         tr/\015//d;
>
>         $skipprocess=0;
>
>         s/^    CLI ID   //g;
>         s/^             //g;
>         s/^\* +[0-9]+ +//g;
>
>         last if (/^$prompt/);
>         next if (/^(\s*|\s*$cmd\s*)$/);
>         if ( ! /^$prompt/) {
>                 if ( ! $skipprocess ) {
>                         print STDOUT "      ShowUsersAll Data: $_" if
> ($debug);
>                         ProcessHistory("","","","!$_");
>                 }
>         }
>     }
>     ProcessHistory("","","","!\n!IPS User Database End\n!\n!\n");
>     print STDERR "    Exiting ShowUsersAll: $_" if ($debug);
>     return(0)
> }
>
> # dummy function
> sub DoNothing {print STDOUT;}
>
> # Main
> @commandtable = (
>         {'show version'         => 'ShowVersion'},
>         {'show users all'       => 'ShowUsersAll'},
>         {'show configuration'   => 'ShowConfig'}
> );
> # Use an array to preserve the order of the commands and a hash for mapping
> # commands to the subroutine and track commands that have been completed.
> @commands = map(keys(%$_), @commandtable);
> %commands = map(%$_, @commandtable);
>
> $cisco_cmds=join(";", at commands);
> $cmds_regexp=join("|", at commands);
>
> open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
> select(OUTPUT);
> # make OUTPUT unbuffered if debugging
> if ($debug) { $| = 1; }
>
> # The IPS doesn't like the TERM of network so we must change it
> if ( $ENV{TERM} eq 'network' ) {
> $ENV{TERM} = 'vt100′;
> }
> if ($file) {
>     print STDERR "opening file $host\n" if ($debug);
>     print STDOUT "opening file $host\n" if ($log);
>     open(INPUT,"<$host") || die "open failed for $host: $!\n";
> } else {
>     print STDERR "executing clogin -t $timeo -c\"$cisco_cmds\"
> $host\n" if ($debug);
>     print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\"
> $host\n" if ($log);
>     if (defined($ENV{NOPIPE})) {
>         system "clogin -t $timeo -c \"$cisco_cmds\" $host </dev/null >
> $host.raw 2>&1" || die "clogin failed for $host: $!\n";
>         open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n";
>     } else {
>         open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host
> </dev/null |") || die "clogin failed for $host: $!\n";
>     }
> }
> # Change the TERM back to network
> if ( $ENV{TERM} eq 'vt100′ ) {
> $ENV{TERM} = 'network';
> }
>
> # determine password filtering mode
> if ($ENV{"FILTER_PWDS"} =~ /no/i) {
>         $filter_pwds = 0;
> } elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
>         $filter_pwds = 2;
> } else {
>         $filter_pwds = 1;
> }
>
> ProcessHistory("","","","!RANCID-CONTENT-TYPE: ipsrancid\n!\n");
> TOP: while(<INPUT>) {
>     tr/\015//d;
>
>     #strip out the stupid spinning running-config progress thingy
>     s/Generating current config: \.*[\|\/\-\\]//gi;
>
>     if (/^.*logout$/)  {
>         $clean_run=1;
>         last;
>     }
>     if (/^Error:/) {
>         print STDOUT ("$host clogin error: $_");
>         print STDERR ("$host clogin error: $_") if ($debug);
>         $clean_run=0;
>         last;
>     }
>     while (/($cmds_regexp)/) {
>         $cmd = $1;
>         if (!defined($prompt)) {
>             $prompt = ($_ =~ /^([^#]+#)/)[0];
>             $prompt =~ s/([][}{)(\\])/\\$1/g;
>             print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
>         }
>         print STDERR ("IPS COMMAND:$_") if ($debug);
>         if (! defined($commands{$cmd})) {
>             print STDERR "$host: found unexpected command - \"$cmd\"\n";
>             $clean_run = 0;
>             last TOP;
>         }
>         $rval = &{$commands{$cmd}};
>         delete($commands{$cmd});
>         if ($rval == -1) {
>             $clean_run = 0;
>             last TOP;
>         }
>     }
> }
> print STDOUT "Done $logincmd: $_\n" if ($log);
> # Flush History
> ProcessHistory("","","","");
> # Cleanup
> close(INPUT);
> close(OUTPUT);
>
> if (defined($ENV{NOPIPE})) {
>     unlink("$host.raw") if (! $debug);
> }
>
> # check for completeness
> if (scalar(%commands) || !$clean_run ) {
>     if (scalar(%commands)) {
>         printf(STDOUT "$host: missed cmd(s): %s\n", join(',',
> keys(%commands)));
>         printf(STDERR "$host: missed cmd(s): %s\n", join(',',
> keys(%commands))) if ($debug);
>     }
>     if (!$clean_run ) {
>         print STDOUT "$host: End of run not found\n";
>         print STDERR "$host: End of run not found\n" if ($debug);
>         system("/usr/bin/tail -1 $host.new");
>     }
>     unlink "$host.new" if (! $debug);
> }
>
> On Wed, Nov 12, 2008 at 11:53 PM, john heasley <heas at shrubbery.net> wrote:
>
>
> Wed, Nov 12, 2008 at 05:36:50PM -0700, Lance Vermilion:
>
>
> I don't understand what this is meaning. i have searched around but
> still can't figure out what the # sign is used for in perl regex like
> it is being used here.
>
> while (/#\s*($cmds_regexp)\s*$/) {
>
>
> the # is a #, the end of the enabled user's prompt.
>
>
>
> If I can figure this out then I will have the IPS module working for
> rancid using the default clogin/rancid with only minor tweaks.
> _______________________________________________
> Rancid-discuss mailing list
> Rancid-discuss at shrubbery.net
> http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss
>
>
> _______________________________________________
> Rancid-discuss mailing list
> Rancid-discuss at shrubbery.net
> http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss
>
>
> --
>
> Gregory W Zill, MBA, CISSP
> Information Security Engineer
> Phone:    402-361-3066
> Email: gregoryzill at solutionary.com
> Making Security Manageable
> ________________________________
> ActiveGuard(R) and SecurCompass(R) are recognized excellence award winners
> by SC
> Magazine and InfoSecurity Products Guide.
>
> Confidentiality Notice: The content of this communication, along with any
> attachments, is covered by federal and state law governing electronic
> communications and may contain confidential and legally privileged
> information. If the reader of this message is not the intended recipient,
> you are hereby notified that any dissemination, distribution, use or copying
> of the information contained herein is strictly prohibited. If you have
> received this communication in error, please immediately contact us by
> telephone at 402.361.3000 or e-mail security at solutionary.com. Thank you.
>
> Copyright 2000-2008, Solutionary, Inc. All rights reserved. ActiveGuard,
> SecurCompass, Solutionary and the Solutionary logo are registered marks of
> Solutionary, Inc. SecurComply is a service mark of Solutionary, Inc.
>
>
> --
>
> Gregory W Zill, MBA, CISSP
> Information Security Engineer
> Phone:    402-361-3066
> Email: gregoryzill at solutionary.com
> Making Security Manageable
> ________________________________
> ActiveGuard(R) and SecurCompass(R) are recognized excellence award winners by SC
> Magazine and InfoSecurity Products Guide.
>
> Confidentiality Notice: The content of this communication, along with any
> attachments, is covered by federal and state law governing electronic
> communications and may contain confidential and legally privileged
> information. If the reader of this message is not the intended recipient,
> you are hereby notified that any dissemination, distribution, use or copying
> of the information contained herein is strictly prohibited. If you have
> received this communication in error, please immediately contact us by
> telephone at 402.361.3000 or e-mail security at solutionary.com. Thank you.
>
> Copyright 2000-2008, Solutionary, Inc. All rights reserved. ActiveGuard,
> SecurCompass, Solutionary and the Solutionary logo are registered marks of
> Solutionary, Inc. SecurComply is a service mark of Solutionary, Inc.


More information about the Rancid-discuss mailing list