spivey49 has asked for the wisdom of the Perl Monks concerning the following question:
Solution
Turns out I didn't break the module. After much debugging I reverted back to the Net::Telnet module. Perlbotics provides a work around for the issues I was seeing with the Net::Telnet::Netscreen module below. Here's the working script in case someone finds it useful some day:
use strict; use warnings; use Net::Telnet; use Net::IP; use Getopt::Long; my $usage = "\nThis script will configure a netscreen firewall with a set of addre +sses and rules.\n" . "Rules will allow all traffic from a set of source IP addresses to + any destination on any port.\n\n" . "\nUsage: \n-h Host (firewall) to configure\n-u User \n-p Password +\n" . "-t Run a test run to only generate rules and addresses.\n\t-t wil +l not apply a configuration to the firewall\n" . "\tCan be used in conjunction with -set and -unset \n\tto generate + different command sets. Default is -set\n" . "-policyid Policy ID to start the set of rules at.\n\tDefault is 1 +50\n" . "-iprange Range of IPs to generate source addresses for.\n\tDefaul +t is 1.1.0.1 - 1.1.1.245\n" . "-from The zone traffic will be sourced from in the rules.\n\tDefa +ult is Untrust\n" . "-to The zone traffic will be destined to in the rules.\n\tDefault + is Trust\n" . "-zone The zone the addresses will be associated with.\n\tDefault +is Untrust\n" . "-set Apply the rules and addresses to the firewall\n-unset Remove + the rules from the firewall\n" . "-l Optional log file. Enter the full path to the log file.\n\tIf + the file exists it will be overwritten\n" . "-help or -? for this message.\n \nUsername, Password, and Host ar +e required.\n\n"; our ( $host, $uname, $pw, $set, $unset, $policyid, $iprange, $test, $vsys, $from, $to, $zone, $log, $help, $fw, $err ); GetOptions( "h=s" => \$host, "u=s" => \$uname, "p=s" => \$pw, "set" => \$set, "unset" => \$unset, "policyid=s" => \$policyid, "iprange=s" => \$iprange, "t" => \$test, "vsys=s" => \$vsys, "from=s" => \$from, "to=s" => \$to, "zone=s" => \$zone, "l=s" => \$log, "help|?:s" => \$help ); die $usage unless ( $uname and $pw and $host ) or $help; #Set defualts unless ($policyid) { $policyid = 150; } unless ($iprange) { $iprange = '1.1.0.1-1.1.1.245'; } unless ($from) { $from = "Untrust"; } unless ($to) { $to = "Trust"; } unless ($zone) { $zone = "Untrust"; } our $ip = new Net::IP($iprange) or die; my $prompt = '/[\w().-]*\(?([\w.-])?\)?\s*->\s*$|Done/'; if ($log) { open( LOG, "> $log" ) or die "Couldn't open file " . $log; + } if ($test) { &test; } elsif ($unset) { $fw = new Net::Telnet( host => $host ); unless ( $fw->login( $uname, $pw ) ) { print $fw->errmsg } &unset_config; } elsif ($set) { $fw = new Net::Telnet( host => $host ); unless ( $fw->login( $uname, $pw ) ) { print $fw->errmsg } &set_config; } if ($log) { close LOG or die "file not open" } sub test { my $count = 1; my $tstmsg = ''; $tstmsg = buildmsg( "#" x 65, "\n" ); $tstmsg = buildmsg( $tstmsg, "Will log into $host with username $uname and password $pw\n" +); $tstmsg = buildmsg( $tstmsg, "We will start at policy ID $policyid and IP range $iprange\n" + ); $tstmsg = buildmsg( $tstmsg, "#" x 65 ); $tstmsg = buildmsg( $tstmsg, "\n\n" ); print $tstmsg; if ($log) { print LOG $tstmsg } if ($unset) { do { $tstmsg = buildmsg( $ip->ip() . " :ip# $count\n" ); my $addrname = "AutoGenRule_" . $ip->ip(); my $rule = unset_rule( $addrname, $policyid ); $tstmsg = buildmsg( $tstmsg, "unset policy id $rule\n" ); my $addr = unset_addr($addrname); $tstmsg = buildmsg( $tstmsg, "unset address $addr\n" ); print $tstmsg; if ($log) { print LOG $tstmsg } ++$policyid; ++$count; } while ( ++$ip ); } else { do { $tstmsg = buildmsg( $ip->ip() . " :ip# $count\n" ); my $addrname = "AutoGenRule_" . $ip->ip(); my $addr = set_addr( $addrname, $ip->ip() ); $tstmsg = buildmsg( $tstmsg, "set address $addr\n" ); my $rule = set_rule( $addrname, $policyid ); $tstmsg = buildmsg( $tstmsg, "set policy id $rule\n" ); print $tstmsg; if ($log) { print LOG $tstmsg } ++$policyid; ++$count; } while ( ++$ip ); } $tstmsg = "Generated $count address and policy objects"; print $tstmsg; if ($log) { print LOG $tstmsg } } #end sub test sub unset_config() { if ( defined $fw ) { my $result; if ($vsys) { $result = cmd("enter vsys $vsys") } unless ($result) { print $err die } else { print "Entered Vsys $vsys\n" } do { my $addrname = "AutoGenRule_" . $ip->ip(); my $rule = unset_rule($policyid); my $addr = unset_addr( $addrname, $ip->ip() ); my $rulemsg = cmd($rule); my $addrmsg = cmd($addr); if ($rulemsg) { $rulemsg = "Removed policy $policyid with command\n\t$ +rule\n"; } else { print "Could not remove policy $policyid with command\n\t$rule\n\tError:$err +\n"; } if ($addrmsg) { $addrmsg = "Removed address $addrname with command\n\t +$addr\n"; } else { print "Could not remove address $addrname with command\n\t$addr\n\tError:$er +r\n"; } print $addrmsg, $rulemsg; if ($log) { print LOG $addrmsg, $rulemsg } ++$policyid; } while ( ++$ip ); } if ($vsys) { cmd("save conf"); cmd("exit"); } cmd("save conf"); $fw->close; } sub set_config() { if ( defined $fw ) { my $result; if ($vsys) { $result = cmd("enter vsys $vsys") } unless ($result) { print $err} else { print "Entered Vsys $vsys\n" } do { $err = undef; my $addrname = "AutoGenRule_" . $ip->ip(); my $rule = set_rule( $addrname, $policyid ); my $addr = set_addr( $addrname, $ip->ip() ); my $addrmsg = cmd($addr); my $rulemsg = cmd($rule); if ($addrmsg) { $addrmsg = "Added address $addrname with command\n\t$a +ddr\n"; } else { $addrmsg = "Could not add address $addrname with command\n\t$addr\n\tError:$err\n +"; } if ($rulemsg) { $rulemsg = "Added policy $policyid with command\n\t$ru +le\n"; } else { $rulemsg = "Could not add policy $policyid with command\n\t$rule\n\tError:$err\n" +; } print $addrmsg, $rulemsg; if ($log) { print LOG $addrmsg, $rulemsg } ++$policyid; } while ( ++$ip ); if ($vsys) { cmd("save conf"); cmd("exit"); } cmd("save conf"); $fw->close; } } sub set_addr { my $addrname = shift; my $ipaddr = shift; my $addr = "set address $zone $addrname $ipaddr\/32 Autocreate +d"; return $addr; } sub set_rule { my $addrname = shift; my $policyid = shift; my $rule = "set policy id $policyid from $from to $to $addrname any any per +m log"; return $rule; } sub unset_addr { my $addrname = shift; my $addr = "unset address $zone $addrname"; return $addr; } sub unset_rule { my $policyid = shift; my $rule = "unset policy id $policyid"; return $rule; } sub cmd { my $cmd = shift; my ( my $errmsg, my $line, my @lines ); unless ( $fw->eof ) { @lines = $fw->cmd($cmd); } foreach $line (@lines) { if ( $line =~ /\^-|(N|n)ot|(F|f)ail/ ) { $err = $line } } if ( $fw->errmsg ) { $err = $fw->$errmsg } if ($err) { return 0 } return 1; } sub buildmsg { my $msg = shift; my $append = shift; $msg = $msg . $append; return $msg; }
I have a script that adds address and policy objects to a Netscreen firewall. I found Net::Telnet::Netscreen that seemed a little more Netscreen friendly than the Net::Telnet module.
I'm not sure, but I think I might have broken my Net::Telnet::Netscreen module. The original module has a setValue method, but not an unsetValue method, so I added one. My script will send one command to the firewall, then exit. The -t option to the script still works fine and shows correct multiple commands the script will generate.
UPDATE: perlbotics suggested I update the question with the @ARGVs being passed to the script:
perl Rules.pl -h 10.99.59.253 -u netscreen -p netscreen -l c:\log.txt -iprange 1.1.0.1-1.1.0.2 -set
The firewall shows the script logging in, executing a command, saving the config, then exiting after one command
Here's the original setValue method:
#set a value in ns box sub setValue { my ($self,$setting, $value) = @_; return $self->error("No setting specified") unless $setting; return $self->error("No value specified") unless $value; my @results=$self->cmd("set ".$setting." ".$value); foreach my $result (@results) { if ($result =~ /\w+/) { return $self->error($result); } } return 1; }
I added this sub for the unsetValue method and reinstalled the module:
sub unsetValue { my ($self,$setting, $value) = @_; return $self->error("No setting specified") unless $setting; return $self->error("No value specified") unless $value; my @results=$self->cmd("unset ".$setting." ".$value); foreach my $result (@results) { if ($result =~ /\w+/) { return $self->error($result); } } return 1; }
Here's the script I'm using the module in:
use strict; use warnings; use Net::Telnet::Netscreen; use Net::IP; use Getopt::Long; my $usage = "\nThis script will configure a netscreen firewall with a set of addre +sses and rules.\n" . "Rules will allow all traffic from a set of source IP addresses to + any destination on any port.\n\n" . "\nUsage: \n-h Host (firewall) to configure\n-u User \n-p Password +\n" . "-t Run a test run to see the rules and addresses.\n\t-t will not +apply a configuration to the firewall\n" . "\tCan be used in conjunction with -set and -unset \n\tto generate + different command sets. Default is -set\n" . "-policyid Policy ID to start the set of rules at.\n\tDefault is 1 +50\n" . "-iprange Range of IPs to generate source addresses for.\n\tDefaul +t is 1.1.0.0 - 1.1.1.245\n" . "-from The zone traffic will be sourced from in the rules.\n\tDefa +ult is Untrust\n" . "-to The zone traffic will be destined to in the rules.\n\tDefault + is Trust\n" . "-zone The zone the addresses will be associated with.\n\tDefault +is Untrust\n" . "-set Apply the rules and addresses to the firewall\n-unset Remove + the rules from the firewall\n" . "-l Optional log file. Enter the full path to the log file.\n\tIf + the file exists it will be overwritten\n" . "-help or -? for this message.\n \nUsername, Password, and Host ar +e required.\n\n"; our ( $host, $uname, $pw, $set, $unset, $policyid, $iprange, $test, $vsys, $from, $to, $zone, $log, $help, $fw ); GetOptions( "h=s" => \$host, "u=s" => \$uname, "p=s" => \$pw, "set" => \$set, "unset" => \$unset, "policyid=s" => \$policyid, "iprange=s" => \$iprange, "t" => \$test, "vsys=s" => \$vsys, "from=s" => \$from, "to=s" => \$to, "zone=s" => \$zone, "l=s" => \$log, "help|?:s" => \$help ); die $usage unless ( $uname and $pw and $host ) or $help; unless ($policyid) { $policyid = 150; } unless ($iprange) { $iprange = '1.1.0.2 - 1.1.1.245'; } unless ($from) { $from = "Untrust"; } unless ($to) { $to = "Trust"; } unless ($zone) { $zone = "Untrust"; } our $ip = new Net::IP($iprange) or die; if ($log) { open( LOG, "> $log" ) or die "Couldn't open file " . $log; + } if ($test) { &test; } elsif ($unset) { $fw = new Net::Telnet::Netscreen( host => $host ); $fw->login( $uname, $pw ) or die $fw->error; &unset_config; } elsif ($set) { $fw = new Net::Telnet::Netscreen( host => $host ); $fw->login( $uname, $pw ) or die $fw->error; &set_config; } close LOG or die "file not open"; sub test { my $count = 1; print "#" x 65, "\n"; print "Will log into $host with username $uname and password $pw\n +"; print "We will start at policy ID $policyid and IP range $iprange\ +n"; print "The following addresses and rules will be generated:\n"; print "#" x 65, "\n\n"; if ($unset) { do { print $ip->ip() . " :ip# $count\n"; my $addrname = "AutoGenRule_" . $ip->ip(); my $rule = unset_rule( $addrname, $policyid ); print "unset policy id $rule\n"; my $addr = unset_addr($addrname); print "unset address $addr\n"; ++$policyid; ++$count; } while ( ++$ip ); } else { do { print $ip->ip() . " :ip# $count\n"; my $addrname = "AutoGenRule_" . $ip->ip(); my $addr = set_addr( $addrname, $ip->ip() ); print "set address $addr\n"; my $rule = set_rule( $addrname, $policyid ); print "set policy id $rule\n"; ++$policyid; ++$count; } while ( ++$ip ); } } sub unset_config() { if ( defined $fw ) { if ($vsys) { $fw->enter_vsys($vsys) } do { my $addrname = "AutoGenRule_" . $ip->ip(); my $rule = unset_rule( $addrname, $policyid ); my $addr = unset_addr( $addrname, $ip->ip() ); my $rulemsg = $fw->unsetValue( "policy id", $rule ); my $addrmsg = $fw->unsetValue( "address", $addr ); if ($rulemsg) { print "Removed $rule\n"; } else { print "Could not remove $rule\n" . $fw->error . "\n +"; } if ($addrmsg) { print "Removed $addr\n"; } else { print "Could not remove $addr\n" . $fw->error . "\n +"; } if ( $rulemsg and $log ) { print LOG "Removed $rule"; } else { print LOG "Could not remove $rule\n" . $fw->error . + "\n"; } if ( $addrmsg and $log ) { print LOG "Removed $addr"; } else { print LOG "Could not remove $addr\n" . $fw->error . + "\n"; } } while ( ++$ip ); } } sub set_config() { if ( defined $fw ) { if ($vsys) { $fw->enter_vsys($vsys) } do { my $addrname = "AutoGenRule_" . $ip->ip(); my $rule = set_rule( $addrname, $policyid ); my $addr = set_addr( $addrname, $ip->ip() ); my $addrmsg = $fw->setValue( "address", $addr ); my $rulemsg = $fw->setValue( "policy id", $rule ); if ($rulemsg) { print "Added $rule"; } else { print "Could not add $rule\n" . $fw->error + . "\n"; } if ($addrmsg) { print "Added $addr"; } else { print "Could not add $addr\n" . $fw->error + . "\n"; } if ( $rulemsg and $log ) { print LOG "Added $rule\n"; } else { print LOG "Could not add $rule\n" . $fw->error . "\ +n"; } if ( $addrmsg and $log ) { print LOG "Added $addr\n"; } else { print LOG "Could not add $addr\n" . $fw->error . "\ +n"; } } while ( ++$ip ); } } sub set_addr() { my $addrname = shift; my $ipaddr = shift; my $addr = "$zone $addrname $ipaddr\/32 \"Created with perl for te +sting\""; return $addr; } sub set_rule() { my $addrname = shift; my $policyid = shift; my $rule = "$policyid from $from to $to $addrname any any perm + log"; return $rule; } sub unset_addr() { my $addrname = shift; my $addr = "$zone $addrname"; return $addr; } sub unset_rule() { my $ipaddr = shift; my $policyid = shift; my $rule = $policyid; return $rule; }
The subs causing me grief are the set_config and unset_config subs. The unset_addr and unset_rule subs are left over from using Net::Telnet and aren't really doing much. I'll be taking those out later.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Broken Net::Telnet::Netscreen module?
by jethro (Monsignor) on Aug 13, 2008 at 00:50 UTC | |
by spivey49 (Monk) on Aug 13, 2008 at 17:43 UTC | |
by jethro (Monsignor) on Aug 13, 2008 at 19:16 UTC | |
by spivey49 (Monk) on Aug 13, 2008 at 20:18 UTC | |
by jethro (Monsignor) on Aug 13, 2008 at 20:38 UTC | |
| |
|
Re: Broken Net::Telnet::Netscreen module?
by Perlbotics (Archbishop) on Aug 17, 2008 at 14:43 UTC |