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@client's pubkey.
From the client system, running the following script from the shell
returns the information I'd expect...
[apache@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.
hey Will,
We don't use keychain, but we do use Net::SSH::Perl through apache on CentOS and RHEL.
Couple questions. Can you become the apache user and manually ssh into cgissh@target with/without a password? If so can you manually run your script outside of apache? No group or other write permission set on any of the directories above your keys? Anything in syslog on the ssh server side concerning why permission was denied?
I will say that once you get it working, make sure you have the following perl modules installed. It will drastically increase the speed of your handshaking. At least it did for us.
Crypt-DH 0.03 (Yes, older version) IO Math-BigInt-GMP
hope this helps, marc
-----Original Message----- From: Will McDonald Sent: Thursday, November 02, 2006 5:54 AM To: CentOS mailing list Subject: [CentOS] Using perl-Net-SSH-Perl with pubkey authentication underCGI.
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@client's pubkey.
From the client system, running the following script from the shell
returns the information I'd expect...
[apache@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.
On 02/11/06, Marc wia@iglass.net wrote:
hey Will,
Hi Marc, thanks for responding.
We don't use keychain, but we do use Net::SSH::Perl through apache on CentOS and RHEL.
The reason I'm using Keychain is to provide passwordless authentication whilst still having passworded private keys, if you can see where I'm coming from.
Couple questions. Can you become the apache user and manually ssh into cgissh@target with/without a password? If so can you manually run your script outside of apache? No group or other write permission set on any of the directories above your keys? Anything in syslog on the ssh server side concerning why permission was denied?
Yep, SSH from client to target as the intended users is OK, as allowing CGIs to connect to other systems and run command isn't an ideal situation security-wise I've been very strict with permissions and ownerships, but it does work and I've loosened them just on the off chance it was a permissions thing.
Here's a snippet of me su - ing and connecting to the target system...
[root@webdev1 ~]# su - apache
KeyChain 2.5.1; http://www.gentoo.org/proj/en/keychain/ Copyright 2002-2004 Gentoo Foundation; Distributed under the GPL
* Found existing ssh-agent (4189) * ssh-agent: All identities removed. * Adding 1 ssh key(s)... Enter passphrase for /var/www/.ssh/id_dsa: Identity added: /var/www/.ssh/id_dsa (/var/www/.ssh/id_dsa)
[apache@webdev1 ~]$ ssh -p2251 -lcgissh manlvs1 hostname manlvs1b
Running the CGI script from the command line behaves the same, i.e. it connects, executes 'hostname' and returns the correct response.
I will say that once you get it working, make sure you have the following perl modules installed. It will drastically increase the speed of your handshaking. At least it did for us.
Crypt-DH 0.03 (Yes, older version) IO Math-BigInt-GMP
I had noticed a _considerable_ speed overhead using Net::SSH::Perl but I'd put that aside as something to address once I've got it working as expected, I'll have a look at those modules, thanks.
Will.
On 02/11/06, Will McDonald wmcdonald@gmail.com wrote:
On 02/11/06, Marc wia@iglass.net wrote:
hey Will,
Hi Marc, thanks for responding.
We don't use keychain, but we do use Net::SSH::Perl through apache on CentOS and RHEL.
The reason I'm using Keychain is to provide passwordless authentication whilst still having passworded private keys, if you can see where I'm coming from.
Couple questions. Can you become the apache user and manually ssh into cgissh@target with/without a password? If so can you manually run your script outside of apache? No group or other write permission set on any of the directories above your keys? Anything in syslog on the ssh server side concerning why permission was denied?
Update: I've just tried removing the passphrase from the private key and now Net::SSH::Perl is happily reading it and using it to authenticate so now I suppose the questions is can I use it with a passworded private key...
[apache@webdev1 .ssh]$ ssh-keygen -f id_dsa -p Enter old passphrase: Key has comment 'id_dsa' Enter new passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved with the new passphrase.
Compare passwordless log excerpt:
[Thu Nov 02 14:48:54 2006] [error] [client 192.168.24.111] webdev1: Trying empty user-authentication request. [Thu Nov 02 14:48:54 2006] [error] [client 192.168.24.111] webdev1: Authentication methods that can continue: publickey,keyboard-in teractive. [Thu Nov 02 14:48:54 2006] [error] [client 192.168.24.111] webdev1: Next method to try is publickey. [Thu Nov 02 14:48:54 2006] [error] [client 192.168.24.111] webdev1: Trying pubkey authentication with key file '/var/www/.ssh/id_ds a' [Thu Nov 02 14:49:00 2006] [error] [client 192.168.24.111] webdev1: Login completed, opening dummy shell channel. [Thu Nov 02 14:49:00 2006] [error] [client 192.168.24.111] webdev1: channel 0: new [client-session]
With passworded:
[Wed Nov 01 17:12:18 2006] [error] [client 192.168.24.111] webdev1: Authentication methods that can continue: publickey,keyboard-in teractive. [Wed Nov 01 17:12:18 2006] [error] [client 192.168.24.111] webdev1: Next method to try is publickey. [Wed Nov 01 17:12:18 2006] [error] [client 192.168.24.111] webdev1: Trying pubkey authentication with key file '/var/www/.ssh/id_ds a' [Wed Nov 01 17:12:18 2006] [error] [client 192.168.24.111] webdev1: Will not query passphrase for '/var/www/.ssh/id_dsa' in batch m ode. [Wed Nov 01 17:12:18 2006] [error] [client 192.168.24.111] webdev1: Loading private key failed. [Wed Nov 01 17:12:18 2006] [error] [client 192.168.24.111] Permission denied at ~/cgi-bin/perl-net-ssh-p erl-test.pl line 18
I wonder, if I _force_ it out of batch mode, but with a passworded key... nope, that's obviously being interpreted as "should be run in interactive mode" and is erroring. So I guess the question is, how to I get Net::SSH::Perl to source keys from a running ssh-agent as I don't want to have passwordless private keys involved if I can avoid it.
Will.
On Thursday 02 November 2006 06:58, Will McDonald wrote:
Update: I've just tried removing the passphrase from the private key and now Net::SSH::Perl is happily reading it and using it to authenticate so now I suppose the questions is can I use it with a passworded private key...
Are you sure that apache reads all it's login scripts when forking to run a CGI? It looked as if you were having something auto-add your key through ssh-agent on su - apache.
Are you really looking for a passworded key? If you are just including the password in a script along with the key you really aren't increasing your security at all, but you are increasing the complexity. As long as you trust the integrity of the box the private key is stored on, you should be fine. If an attacker gets into this box, it's not a great leap to assume they'll be able to find a passphrase supplied in a script if they find the CGI (and it's not a great leap to think they might look for that when finding an SSH private key associated with user apache).
Have you considered SUExec? That way you aren't running as Apache, but as a specified account. This might also limit exposure in the case that there is an Apache exploit that gives privileges to users as the apache user.