[CentOS] Using perl-Net-SSH-Perl with pubkey authentication under CGI.

Thu Nov 2 10:53:48 UTC 2006
Will McDonald <wmcdonald at gmail.com>

Guys, I wonder if anyone can give me any pointers here, I hope it's
CentOS related enough not to be too off topic, if it is then
apologies.

I'm attempting to setup a CGI which can connect to a remote system and
execute a command.

On the 'client', for the Apache user 'apache' I've given it a shell
and generated a key-pair. I've configured Keychain [
http://www.gentoo.org/proj/en/keychain/ ] to load the keys for the
apache user and make these persistently available via ssh-agent.

I've setup a specific user 'cgissh' on the remote target system and
configured its authorized_keys with apache at client's pubkey.

>From the client system, running the following script from the shell
returns the information I'd expect...

[apache at webdev1 cgi-bin]$ cat perl-net-ssh-perl-test.pl
#!/usr/bin/perl

print "Content-type: text/html\n\n";
print "<HEAD><TITLE>Quick Test</TITLE></HEAD>";

$ENV{HOME} = "/var/www";
$ENV{USER} = "apache";

use Net::SSH::Perl;

$sshhost='target';
$sshuser='cgissh';
$sshport='22';
$sshprotocol='2';
$sshdebug='1';
$sshcipher='3des-cbc';
$sshconn = Net::SSH::Perl->new($sshhost, protocol=>$sshprotocol,
port=>$sshport, debug=>$sshdebug, cipher=>$sshcipher);
$sshconn->login($sshuser);
my($out,$err) = $sshconn->cmd('hostname');

print "<HTML>";
print "<BODY>";

print $out;

print "</HTML>";
print "</BODY>";

It's definately using the pubkey information from Keychain as the
target system ONLY accepts key-based authentication and I'm "su -
apache"d to run the script so it's not picking up another users
ssh-agent key info from the environment.

Attempting to execute the same script as a CGI by accessing
http://client/cgi-bin/perl-net-ssh-perl-test.pl results in the
following in the logs...

[Wed Nov 01 17:10:53 2006] [error] [client 192.168.1.2]
clienthostname: Reading configuration data /var/www/.ssh/config
[Wed Nov 01 17:10:53 2006] [error] [client 192.168.1.2]
clienthostname: Reading configuration data /etc/ssh_config
[Wed Nov 01 17:10:53 2006] [error] [client 192.168.1.2]
clienthostname: Connecting to manlvs1, port 2251.
[Wed Nov 01 17:10:53 2006] [error] [client 192.168.1.2]
clienthostname: Remote version string: SSH-2.0-OpenSSH_3.9p1
[Wed Nov 01 17:10:53 2006] [error] [client 192.168.1.2]
[Wed Nov 01 17:10:53 2006] [error] [client 192.168.1.2]
clienthostname: Remote protocol version 2.0, remote software version
OpenSSH_3.9p 1
[Wed Nov 01 17:10:53 2006] [error] [client 192.168.1.2]
clienthostname: Net::SSH::Perl Version 1.30, protocol version 2.0.
[Wed Nov 01 17:10:53 2006] [error] [client 192.168.1.2]
clienthostname: No compat match: OpenSSH_3.9p1.
[Wed Nov 01 17:10:53 2006] [error] [client 192.168.1.2]
clienthostname: Connection established.
[Wed Nov 01 17:10:53 2006] [error] [client 192.168.1.2]
clienthostname: Sent key-exchange init (KEXINIT), wait response.
[Wed Nov 01 17:10:53 2006] [error] [client 192.168.1.2]
clienthostname: Algorithms, c->s: 3des-cbc hmac-sha1 none
[Wed Nov 01 17:10:53 2006] [error] [client 192.168.1.2]
clienthostname: Algorithms, s->c: 3des-cbc hmac-sha1 none
[Wed Nov 01 17:11:30 2006] [error] [client 192.168.1.2]
clienthostname: Entering Diffie-Hellman Group 1 key exchange.
[Wed Nov 01 17:11:30 2006] [error] [client 192.168.1.2]
clienthostname: Sent DH public key, waiting for reply.
[Wed Nov 01 17:11:30 2006] [error] [client 192.168.1.2]
clienthostname: Received host key, type 'ssh-dss'.
[Wed Nov 01 17:11:30 2006] [error] [client 192.168.1.2]
clienthostname: Host 'manlvs1' is known and matches the host key.
[Wed Nov 01 17:11:30 2006] [error] [client 192.168.1.2]
clienthostname: Computing shared secret key.
[Wed Nov 01 17:12:07 2006] [error] [client 192.168.1.2]
clienthostname: Verifying server signature.
[Wed Nov 01 17:12:18 2006] [error] [client 192.168.1.2]
clienthostname: Waiting for NEWKEYS message.
[Wed Nov 01 17:12:18 2006] [error] [client 192.168.1.2]
clienthostname: Enabling incoming encryption/MAC/compression.
[Wed Nov 01 17:12:18 2006] [error] [client 192.168.1.2]
clienthostname: Send NEWKEYS, enable outgoing
encryption/MAC/compression.
[Wed Nov 01 17:12:18 2006] [error] [client 192.168.1.2]
clienthostname: Sending request for user-authentication service.
[Wed Nov 01 17:12:18 2006] [error] [client 192.168.1.2]
clienthostname: Service accepted: ssh-userauth.
[Wed Nov 01 17:12:18 2006] [error] [client 192.168.1.2]
clienthostname: Trying empty user-authentication request.
[Wed Nov 01 17:12:18 2006] [error] [client 192.168.1.2]
clienthostname: Authentication methods that can continue:
publickey,keyboard-interactive.
[Wed Nov 01 17:12:18 2006] [error] [client 192.168.1.2]
clienthostname: Next method to try is publickey.
[Wed Nov 01 17:12:18 2006] [error] [client 192.168.1.2]
clienthostname: Trying pubkey authentication with key file
'/var/www/.ssh/id_dsa'
[Wed Nov 01 17:12:18 2006] [error] [client 192.168.1.2]
clienthostname: Will not query passphrase for '/var/www/.ssh/id_dsa'
in batch mode.
[Wed Nov 01 17:12:18 2006] [error] [client 192.168.1.2]
clienthostname: Loading private key failed.
[Wed Nov 01 17:12:18 2006] [error] [client 192.168.1.2] Permission
denied at /home/clientusername/cgi-bin/perl-net-ssh-per l-test.pl line
18

Why is it failing to load the private key? Do I need to source
something from the shell into the Perl script as would with a shell
script to use the Keychain agent information? If this was a shell
script I'd have used '[[ -f $HOME/.keychain/$HOSTNAME-sh ]] && source
$HOME/.keychain/$HOSTNAME-sh'.

Additional info: Both systems are up-to-date CentOS 4.4 systems
running the default Apache with perl-Net-SSH-Perl and its dependencies
from RPMForge.

Any pointers greatly appreciated.

Will.