我有一个脚本,它将ssh
列出路由器并从中运行命令commands.txt
。我想enable
在通过连接到路由器之后,ssh
在我执行其余命令之前,commands.txt
我有两个问题。第一的,我该如何传递启用命令?当我将它作为第一行时,它似乎没有做任何事情commands.txt.
第二,一旦我弄清楚了enable
提示部分,我将如何传递我的凭证以使脚本完全自动化?
脚本
命令.txt
当我运行当前脚本时,当它提示我连接路由器时,我会输入密码。然后它就会显示% Type "show ?" for a list of subcommands
,然后继续连接到下一个路由器并要求我输入凭据。
答案1
考虑看看馊。它主要用作 Cisco 和其他网络设备的配置备份工具,但它的一个组件克洛金,本质上是一个 Expect 脚本,它完全按照您的要求执行。使用示例中的命令和路由器文件列表,您可以在所有路由器上执行以下命令:
clogin -u user -p pass -e enablepass -x commands.txt $(cat routers.txt)
它可以读取配置文件您可以在其中存储登录名和密码,这样就可以避免在命令行上传递它们。它有多个登录选项,因此它可以处理您不使用aaa new-model
而只在 VTY 上有密码的情况,以及使用较旧设备在响应命令时要求输入用户名的情况enable
。
唯一真正的缺点是它不是特别安静。例如,如果您想要 的输出show version
,您会得到它,但您还会在输出中获得所有登录横幅、登录/密码提示和命令提示。
答案2
我已经使用这个 perl 脚本大约一年了。它是我在各种论坛上找到的几个 perl 脚本片段的演变,经过了一些反复试验,但效果很好。您需要为 usleep 安装模块 Time::HiRes,但我发现它有助于在远程交换机和路由器上执行命令,因为这些命令的响应时间会稍长一些。它将跳过没有响应或身份验证失败的设备,继续处理列表中的下一个设备,并为每个以其 IP 地址命名的设备提供一个日志文件。
希望它对某人有帮助。
#
# usage: perl cisco.pl (target_hostfile) (ssl_password) (enable_password)
#
use Net::SSH2;
use warnings;
use strict;
use Time::HiRes qw(usleep);
use File::Slurp;
print "\nEnter switch list filenane: ";
my $input = <STDIN>; ### target hosts file from STDIN
chomp($input);
my @hostfile = read_file($input,chomp => 1); ### read target host file
my $arrSize = @hostfile;
my $user = "username"; ### your username
print "\nEnter ssh password: ";
my $password = <STDIN>; ### ssh password from STDIN
chomp($password);
print "\nEnter enable password: ";
my $secret = <STDIN>; ### enable password from STDIN
chomp($secret);
print "\nEnter command delay in miliseconds: ";
my $delay = <STDIN>;
chomp($delay);
my $delaytime = $delay/1000;
print "\nCopmmand delay confirmed: $delaytime Seconds\n";
print "\nEnter command list filename: ";
my $commandlist = <STDIN>;
chomp($commandlist);
my @commandfile = read_file($commandlist,chomp => 1);
my $commandsize = @commandfile;
my $i = 0;
my $j = 0;
$delay*=1000; ### convert delay into microseconds for usleep command
for ($i = 0; $i < $arrSize; $i++){
my $ssh = Net::SSH2->new();
if(!$ssh->connect($hostfile[$i])){
print("Connection Failed ($hostfile[$i]\n");
next;
}
usleep($delay); ### time in microsecond
if(!$ssh->auth_password($user,$password)){
print("Authentication Failed ($hostfile[$i]\n");
next;
}
usleep($delay); ### time in microsecond
my $channel = $ssh->channel();
$channel->blocking(0);
$channel->shell();
print $channel "enable\n";
usleep($delay); ### time in microsecond
print $channel "$secret\n"; ### enable password from input string3
usleep($delay); ### time in microsecond
print $channel "term len 0\n";
usleep($delay); ### time in microsecond
for ($j = 0; $j < $commandsize; $j++){
print $channel "$commandfile[$j]\n";
usleep($delay); ### time in microsecond so 1 millisecond == 1000 microseconds
}
open (my $OUTPUTFILE, ">$hostfile[$i].log") or die "Can't open $hostfile[$i].log: $!"; ### target host as filename
while (<$channel>) {
chomp;
print $OUTPUTFILE "$_";
}
close $OUTPUTFILE or die "$OUTPUTFILE: $!";
}
close $OUTPUTFILE or die "$OUTPUTFILE: $!";
}
答案3
我会考虑使用类似 expect 的东西,而不是仅仅尝试从文件重定向。expect 将处理密码提示等,并根据输出响应您想要的信息。
http://expect.sourceforge.net/
在 rhel6 下,该包将被称为 expect。还有一个 Python 模块可以做类似的事情,称为 pexpect,可从 rhel6 更新存储库获取。一个做同样事情的 perl 模块称为 perl-Expect。
这可能会给你带来更好的结果。
本页http://nixcraft.com/showthread.php/15060-script-to-auto-login-to-cisco-router-(-telnet-and-SSH)给出一些您正在尝试做的事情的例子。
编辑:刚刚发现思科的另一个链接也描述了这一点:
https://supportforums.cisco.com/discussion/11553001/script-automate-tasks