Cannot reload Cisco device using perl Net::Appliance::Session library - perl

I am trying to reboot a Cisco device using net::appliance::session library. But even the code doesn't give en error the device doesn't reboot. This is the two lines I am using:
$session->cmd(String => 'Reload',Match => ['/Proceed/'], );
$session->cmd(String => "\n", Match => ['//'],);
In the Cisco shell a reload command is given like this:
test#reload
Proceed with reload? [confirm]
Connection closed by foreign host.
This thread in the cpan forum also tells me to do this way. I think there is a problem with carriage returns and confirm dialogs. Because when I try to create a directory it works fine:
$session->cmd(String => 'mkdir',Match => ['/Create dire.*/'] );
$session->cmd(String => 'test',Match => ['//'] );
The equivelant of this in Cisco shell:
test#mkdir
Create directory filename []? test
Created dir flash:test
But when I try to delete this directory which needs a carriage return as confirmation the scripts fails again.
$session->cmd(String => 'rmdir asd',Match => ['/Remove directory.*/'] );
$session->cmd(String => '\n' ,Match => ['/Delete flash.*/'] );
$session->cmd(String => '\n');
The equivelant in Cisco is this:
test#rmdir test
Remove directory filename [test]?
Delete flash:test? [confirm]
Removed dir flash:test
So I think the problem isn't with reload command. But the problem is sending carriage returns as confirmation. I have tried \n \r \n\r \r\n and empty string but they didn't work.
Any ideas?

Maybe the Cisco device is case sensitive? In the example you used 'reload' and 'Reload' in the Perl code.
Maybe you could try this:
$session->say('reload');
$session->gather();
$session->say('confirm');
$session->gather();

Related

Replace host key automatically on linux

I have a script that connects to an SFTP server with the following code:
use Net::SFTP::Foreign;
my %cfg = (
user => "$user",
password => "$password",
port => 22,
more => [-o => 'StrictHostKeyChecking no']
);
my $sftp = Net::SFTP::Foreign->new("$host",%cfg);
I am using StrictHostKeyChecking to make sure the script automatically accepts the ssh key.
The issue begins when the server replaces the host key with new one. I get the error: WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
So I have to manually remove the key by running ssh-keygen -R testserver.com
After that the script works fine again.
I am trying to find a way to autmatically replace the key if it changes.
Technically I can run ssh-keygen -R testserver.com every time the script runs, but I do not like that solution.
So far I am not able to a good automated way to replace the key.
Add another option that points UserKnownHostsFile to /dev/null should do the trick, not that it's recommend from security perspective ;-)
use Net::SFTP::Foreign;
my %cfg = (
user => "$user",
password => "$password",
port => 22,
more => [-o => 'StrictHostKeyChecking=no',
-o => 'UserKnownHostsFile=/dev/null']
);
my $sftp = Net::SFTP::Foreign->new("$host",%cfg);

Not able to use 'copy_perm' option in Net::SFTP::Foreign module

I want to copy the file from remote host to the local host with the preservation of file permission, hence i tried to use the 'copy_perm' option as per the documentation of Net::SFTP::Foreign as mentioned below -
my $sftp = Net::SFTP::Foreign->new(
host => $host,
key_path => $ssh_key_path,
copy_perm => 1,
more => [ -o => 'Compression yes' ]
);
But I am getting the below error -
Invalid option 'copy_perm' or bad combination of options at test.pl at line 101.
The line 101 is the Net::SFTP::Foreign object creation as mentioned above.
Did i miss anything or anyone has faced same issue before?
That's because copy_perm isn't an option for the new method. You use it in get and put.

SNMP v3 with NET::SNMP working, but snmpwalk/snmpget not?

I have the following (working) perl script:
use Net::SNMP;
# create session to the host
my ($session, $error) = Net::SNMP->session(
-hostname => $hostname,
-version => 'snmpv3',
-username => 'my_user_name',
-authkey => 'my_authkey',#actually, here stands the real authkey as configured on the switch
-privkey => 'my_privkey',#same as on switch
-authprotocol => 'sha',
-privProtocol => 'des'
);
if (!defined($session)) {
print $error . "\n";
last;
}
# retrieve a table from the remote agent
my $result = $session->get_table(
-baseoid => $MAC_OID
);
if (!defined($result)) {
print $session->error . "\n";
$session->close;
last;
}
#print out the result of the snmp query
#....
Now I wanted to use snmpwalk or snmpget with the same keys. For that, I created a snmp.conf file in .snmp of my home directory with the following content:
defSecurityName my_user_name
defContext ""
defAuthType SHA
defSecurityLevel authPriv
defAuthPassphrase my_auth_key here
defVersion 3
defPrivPassphrase my_privkey here
defPrivType DES
As I see it, I use the same credentials in the script and for snmpget. Why do I get snmpget: Authentication failure (incorrect password, community or key) ?
That depends on the version of snmpget and snmpset you use. When I tested an older version of net-snmp against my C# based SNMP agent http://sharpsnmplib.codeplex.com I noticed that for SHA authen mode + DES privacy mode a bug prevented the net-snmp command line tools from generating the correct message bytes (the encryption is wrong so that no agent can decrypt it).
My suggestion is that you try to use Net::SNMP instead, as like you found out, it is not affected by the same bug.
Your problem is that you're using an authentication key for Net::SNMP and a password for the command-line net-snmp tools. Based on your Net::SNMP usage you're actually using 'localized' keys. Which means the right tokens for your snmp.conf file are:
defAuthLocalizedKey 0xHEXSTRING
defPrivLocalizedKey 0xHEXSTRING
See the snmp.conf manual page for further details.

Perl SCP ERROR(Asking to Continue?)

Here's is what I am doing
my $username = "user";
my $password= "pass";
my $host="xxx.xxx.xxx.xxx";
my $scpe = Net::SCP::Expect->new(user => $username,
password => $password,
preserve => 1,
recursive => 1,
verbose=>1,
auto_yes=>1);
$scpe->scp("$file","$host:./drop/drop.txt");
When I run this code there is no error I am using unix box, $file is in my directory and have full permissions, also I have changed the directory to temp in unix box but when somebody else runs this code they get
Problem performing scp: Are you sure
you want to continue connecting
(yes/no)? at scp.pl line 242
I am very confused why is it happening, as this error is not received by me
Short answer:
Raise the timeout_auto value:
my $scpe = Net::SCP::Expect->new(user => $username,
password => $password,
preserve => 1,
recursive => 1,
verbose=>1,
timeout_auto=>10, #For example - 5 should probably be plenty
auto_yes=>1);
Long answer.
The
problem performing scp
is what Net::SCP::Expect prepends to the literal error message it gets from SCP itself, so in this case
Are you sure you want to continue
connecting (yes/no)?
This usually happens because the host SCP is connecting to is not yet known.
You should set auto_yes to 1 if you want to avoid this error as the CPAN Documentation for NET::SCP::Expect explains, but I see you're already doing that.
If that doesn't help, consider raising the timeout_auto value. It defaults to 1 second, but if it takes longer for SCP to pose the 'are you sure' question (because for example the DNS looking of the host takes longer), it might not be enough.

How do I find the standard site_perl directory for Perl?

How can I find the standard site_perl (non-arch specific) location? Is it safe to just loop over #INC and find the path ending with "site_perl", or is there a standard way to do this?
The reason for trying to find this, is I have a very large project built up from hundreds of individual modules, all with their own Makefile.PL files (pretty much every .pm file has been built as its own CPAN style module). Along with this, each module may have artifacts (templates, .cgi's, etc), in various locations, all which need to be deployed to various locations, nothing is standard. This is the first step in trying to get this under control, basically having a single Makefile which can find and deploy everything, the next step will be getting it in sensible layout in version control.
I've spent time trying to do this with standard installation tools, but have had no luck.
C:\Temp> perl -MConfig -e "print qq{$_ => $Config{$_}\n} for grep { /site/ } keys %Config"
d_sitearch => define
installsitearch => C:\opt\perl\site\lib
installsitebin => C:\opt\perl\site\bin
installsitehtml1dir =>
installsitehtml3dir =>
installsitelib => C:\opt\perl\site\lib
installsiteman1dir =>
installsiteman3dir =>
installsitescript => C:\opt\perl\site\bin
sitearch => C:\opt\perl\site\lib
sitearchexp => C:\opt\perl\site\lib
sitebin => C:\opt\perl\site\bin
sitebinexp => C:\opt\perl\site\bin
sitehtml1dir =>
sitehtml1direxp =>
sitehtml3dir =>
sitehtml3direxp =>
sitelib => C:\opt\perl\site\lib
sitelib_stem =>
sitelibexp => C:\opt\perl\site\lib
siteman1dir =>
siteman1direxp =>
siteman3dir =>
siteman3direxp =>
siteprefix => C:\opt\perl\site
siteprefixexp => C:\opt\perl\site
sitescript =>
sitescriptexp =>
usesitecustomize => define
Or, as #ysth points out in comments, you can use:
C:\Temp> perl -V:.*site.*
on Windows and
$ perl '-V:.*site.*'
in *nix shells.
Is there a reason not to use one of the module installers (ExtUtils::MakeMaker, Module::Build, Module::Install)?
But if you must, the directory is available (after loading Config) as $Config::Config{'installsitelib'}. Note that some platforms may configure perl such that this directory doesn't literally appear in #INC, instead having some other directory that's symlinked to the installsitelib directory.
Just run perl -V. It will print the default #INC at the end.
It is not safe to loop over #INC as it can be modified by code or the environment, and, therefore, may contain multiple directories that end in site_perl.
If you are trying to determine where a given module is installed use %INC.