I wanted to make the remote connection and automate the change password of any user account in that remote machine so I am using Perl Net::SSH:: Expect module. My connection is happening but I'm not able to perform any command on the remote machine. I am new to Perl language so there might be some mistakes in my code. I have tried searching for this but wasn't able to find something related to it.
Initially, I tried using Net:: OpenSSH and Expect module in combination but wasn't able to achieve the use-case.
#!/usr/bin/perl
use strict;
use warnings;
use Net::OpenSSH;
use Expect;
use Net::SSH::Expect;
my $uName= "user";
my $ssh = Net::SSH::Expect->new (
host => "IPAddress",
password=> "userPassword",
user => $uName,
raw_pty => 1
);
# logon to the SSH server using those credentials.
my $login_output = $ssh->login();
if ($login_output !~ /Welcome/) {
die "Login has failed. Login output was $login_output";
}
#Random line display
print "Connected to $uName\n";
#This is where I was trying the change password use case
$ssh->send("passwd") or die "Cannot execute the passwd command: $!\n";
$ssh->waitfor("Changing password for user.\n
(current) UNIX password: ", 3) or die "prompt 'password' not found after 1 second";
$ssh->send("oldPassword\n");
$ssh->waitfor("\n
Enter new UNIX password: " , 2) or die "prompt 'New password:' not found";
$ssh->send("newPassword");
$ssh->waitfor("\n
Retype new UNIX password: ", 1) or die "prompt 'Confirm new password:' not found";
$ssh->send("newPassword");
#$ssh->send("") or die "Cannot spawn: $!\n";
$ssh->close();
This the output i am getting
Cannot execute the passwd command
I tried executing a simple command just to check whether any command is getting executed or not. It is but still, my change password use case using send(passwd) is not.
#!/usr/bin/perl
use strict;
use warnings;
#use Net::OpenSSH;
#use Expect;
use Net::SSH::Expect;
#
# You can do SSH authentication with user-password or without it.
#
my $uName= "admin1";
# Making an ssh connection with user-password authentication
# 1) construct the object
my $ssh = Net::SSH::Expect->new (
host => "192.168.56.101",
password=> "Passw0rd1",
user => "admin1",
raw_pty => 1
);
# 2) logon to the SSH server using those credentials.
# test the login output to make sure we had success
my $login_output = $ssh->login();
if ($login_output !~ /Welcome/) {
die "Login has failed. Login output was $login_output";
}
print "Connected to $uName\n";
This is the new simple command i am trying to execute
my $who = $ssh->exec("who");
print ($who);
My old use case with die removed from send()
$ssh->send("passwd");
$ssh->waitfor("Changing password for $uName.\n(current) UNIX password: ", 2) or die "prompt 'password' not found after 2 second";
$ssh->send("Passw0rd1\n");
$ssh->waitfor("\nEnter new UNIX password: " , 2) or die "prompt 'New password:' not found";
$ssh->send("qwerty123");
$ssh->waitfor("\nRetype new UNIX password: ", 1) or die "prompt 'Confirm new password:' not found";
$ssh->send("qwerty123");
$ssh->close();
Now the output is coming like this
admin3@admin3-VirtualBox:~/Desktop$ perl NetSSHExpect.pl
Connected to admin1
admin1 :0 2019-07-19 11:49 (:0)
admin1 pts/1 2019-07-19 12:41 (192.168.56.1)
admin1@admin1-VirtualBox:~$ prompt 'password' not found after 2 second at NetSSHExpect.pl line 36.
admin3@admin3-VirtualBox:~/Desktop$
According to the documentation:
void send($string) - sends
$string
to the SSH server, returns nothing
Sends the string to the SSH server.
So don't check the return value, just remove the or die ..
part after the send()
:
$ssh->send("passwd"); # <-- no error code is returned here..