我正在尝试从Linux服务器上的Perl脚本登录HP Switch(3500)。我坚持使用Net :: OpenSSH作为我可用的唯一模块。
但每次我尝试登录时它都会挂起。当它访问网络服务器并且我只是登录,获取目录列表并离开时,代码工作正常。当对开关运行时,它会挂断。
手动登录时,方法如下:
$ ssh -luser_name 20.xxx.xxx.xxx
We'd like to keep you up to date about:
* Software feature updates
* New product announcements
* Special events
Please register your products now at: www.hp.com/networking/register
user_name@20.xxx.xxx.xxx's password: [I type that in, hit enter]
ProCurve J8693A Switch 3500yl-48G
Software revision K.15.04.1018m
Copyright (C) 1991-2013 Hewlett-Packard Development Company, L.P.
RESTRICTED RIGHTS LEGEND
Confidential computer software. Valid license from HP required for possession,
use or copying. Consistent with FAR 12.211 and 12.212, Commercial Computer
Software, Computer Software Documentation, and Technical Data for Commercial
Items are licensed to the U.S. Government under vendor's standard commercial
license.
HEWLETT-PACKARD DEVELOPMENT COMPANY, L.P.
20555 State Highway 249, Houston, TX 77070
[delete lots of lines here]
Press any key to continue
我编写了一个简短的脚本来尝试登录并发出一个简单的命令:
use strict;
use Net::OpenSSH;
my $host = '20.xxx.xxx.xxx';
my $user = 'user_name';
my $password = 'password';
my $login_string = $user . ':' . $password . '@' . $host;
my $ssh = Net::OpenSSH->new($login_string);
$ssh->error and die "Cannot open the connection " . $ssh->error;
my @results = $ssh->capture2('show cpu');
map { print;} @results;
它没有走得太远:
$ perl testopenssh.pl
We'd like to keep you up to date about:
* Software feature updates
* New product announcements
* Special events
Please register your products now at: www.hp.com/networking/register
这就是它挂起的地方。它就像它不认识到它正在寻找密码而永远不会超过这一点。我点击了CTRL-C然后就死了。当我这样做时,调试模式后来显示:
# file object not yet found at /home/xxxxxx/.libnet-openssh-perl/user_name-20.xxx.xxx.xxx-21357-620440
# passwd/passphrase requested (user_name@20.xxx.xxx.xxx's password:)
# file object not yet found at /home/xxxxxx/.libnet-openssh-perl/user_name-20.xxx.xxx.xxx-21357-620440
# file object not yet found at /home/xxxxxx/.libnet-openssh-perl/user_name-20.xxx.xxx.xxx-21357-620440
# file object found at /home/xxxxxx/.libnet-openssh-perl/app-20.xxx.xxx.xxx-21357-620440
# call args: ['ssh','-O','check','-T','-S','/home/xxxxxx/.libnet-openssh-perl/user_name-20.xxx.xxx.xxx-21357-620440','-l','user_name','20.xxx.xxx.xxx','--']
# open_ex: ['ssh','-O','check','-T','-S','/home/xxxxxx/.libnet-openssh-perl/user_name-20.xxx.xxx.xxx-21357-620440','-l','user_name','20.xxx.xxx.xxx','--']
# io3 mloop, cin: 0, cout: 1, cerr: 0
# io3 fast, cin: 0, cout: 1, cerr: 0
# stdout, bytes read: 28 at offset 0
#> 4d 61 73 74 65 72 20 72 75 6e 6e 69 6e 67 20 28 70 69 64 3d 32 31 33 35 38 29 0d 0a | Master running (pid=21358)..
# io3 fast, cin: 0, cout: 1, cerr: 0
# stdout, bytes read: 0 at offset 28
# leaving _io3()
# _waitpid(21362) => pid: 21362, rc:
# call args: ['ssh','-S','/home/xxxxxx/.libnet-openssh-perl/user_name-20.xxx.xxx.xxx-21357-620440','-l','user_name','20.xxx.xxx.xxx','--','show cpu']
# open_ex: ['ssh','-S','/home/xxxxxx/.libnet-openssh-perl/user_name-20.xxx.xxx.xxx-21357-620440','-l','user_name','20.xxx.xxx.xxx','--','show cpu']
# io3 mloop, cin: 0, cout: 1, cerr: 1
# io3 fast, cin: 0, cout: 1, cerr: 1
这是否意味着它甚至在寻找密码之前就挂了?
关于我还能尝试什么的任何想法?
谢谢!
答案 0 :(得分:1)
正如您可能知道的那样,当您使用SSH时,无法以交互方式呈现密码,即没有包含它的命令行选项。如果您使用SSH密码验证,则必须以交互方式提供。
Net :: OpenSSH连接调用单个字符串的方式:
my $ssh2 = Net::OpenSSH->new('jack:secret@foo.bar.com:10022');
只是程序员提供密码的好方法,但它会模仿交互式密码身份验证。文档说:“对于密码验证,必须安装IO :: Pty”
我认为switch的pty实现可能与您登录的Web服务器不同,因此Net :: OpenSSH模块 - 或者说IO :: Pty - 无法通过密码验证?
我同意上面的@Marlon预期会很好地适应这里。您需要模仿人类行为的任何地方,期望是一个很好的选择。并且您不 使用SSH密钥,但建议不要在脚本文件中以明文形式使用密码。但是,上面的Perl程序并不完全是顶级安全的东西,其中列出了密码。因此,您可以轻松切换到一个可以轻松处理交互式密码登录的expect脚本,与您现在处于相同的安全级别。
只是我的2c。
答案 1 :(得分:0)
我正在使用期望和私钥认证来完成此任务。
我有一个简单的期望脚本,我使用IP和登录后执行的命令调用:
#!/usr/bin/expect
#
# sendswitchcmd.exp
#
set timeout 60
spawn ssh -t -t -o ConnectTimeout=5 -o StrictHostKeyChecking=no -i PATHTOYOURKEY]
expect -re "Press any key to continue"
send "X"
expect -re ".*#"
send "config\n"
expect -re ".*#"
send "[lindex $argv 1] [lindex $argv 2]\n "
expect -re ".*#"
send "ex\n"
expect -re ".*#"
send "ex\n"
expect -re ".*>"
send "ex\n"
expect -re ".*you want to log out.*"
send "y"
有了这个我可以做的事情,比如
./sendswitchcmd.exp [switch-IP] "show vlans"
我还在一些Bash-Scripts中调用了我为交换机更简单的配置而构建的。
也许这可以帮助你。