I say phpseclib. Personally, I think you get better support with phpseclib and that the API is better but there are less subjective reasons too:
More portable.
I tried to install libssh2-php on Ubuntu 12.04 and "sudo apt-get install libssh2-php" didn't work for me. And even if it did it likely wouldn't get the latest version. So I had to compile libssh2 and the PECL extension myself which is always a hassle and not something a lot of admins are going to be willing to do.
And even if you are willing to compile stuff let's say your hard drive fails and you have to rebuild the server. If you're willing to compile libssh2 you'll have probably compiled other stuff too. Which means you can't just fire up another box - you have to remember all the changes you made on your old box and reapply them. And what if you don't remember them? Or what if one of them hasn't been updated to work with the latest version of another?
phpseclib, in contrast, doesn't require much of anything other than PHP. It'll use mcrypt, gmp, bcmath or openssl if they're available but if they're not, that's okay, too. And it doesn't even require PHP5, although it certainly supports it.
Better public key support.
How you do it with libssh2:
<?php
$ssh = ssh2_connect('domain.tld');
ssh2_auth_pubkey_file($ssh, 'username', '/home/ubuntu/pubkey', '/home/ubuntu/privkey'/*, 'password'*/);
$stream = ssh2_exec($ssh, 'ls -la');
echo stream_get_contents($stream);
Both have to be of the right format too. If you didn't use ssh-keygen to generate your keys good luck in converting them.
With phpseclib:
<?php
include('Net/SSH2.php');
include('Crypt/RSA.php');
$rsa = new Crypt_RSA();
$rsa->loadKey('...');
$ssh = new Net_SSH2('domain.tld');
$ssh->login('username', $rsa);
//$ssh->setPassword('password');
echo $ssh->exec('ls -la');
Ignoring the API for the time being there are a few clear ways phpseclib comes out on top here:
- phpseclib takes in strings - not file paths. If you want to do a file you can do file_get_contents.
- phpseclib doesn't require a public key. Most private key formats have the public key embedded within them. And if they don't... phpseclib supports that too.
- phpseclib can take in pretty much any standardized format, from PKCS#1 formatted keys, to PuTTY keys, to XML Signature keys
Interactive shell.
Let's try to do sudo on the remote system.
With phpseclib:
http://phpseclib.sourceforge.net/ssh/examples.html#password,sudo,
With libssh2? I have no clue. My best guess (doesn't work):
<?php
$ssh = ssh2_connect('domain.tld');
ssh2_auth_password($ssh, 'username', 'password');
$shell = ssh2_shell($ssh);
echo fread($shell, 1024*1024);
fwrite($shell, "sudo ls -la
");
$output = fread($shell, 1024*1024);
echo $output;
if (preg_match('#[pP]assword[^:]*:#', $output)) {
fwrite($shell, "password
");
}
echo fread($shell, 1024*1024);
I can't get top to work with libssh2 either but it works fine with phpseclib:
http://phpseclib.sourceforge.net/ssh/examples.html#password,top,
Diagnosing problems
Why didn't top or sudo work? On phpseclib you can get logs:
http://phpseclib.sourceforge.net/ssh/examples.html#password,oneoff,logging,
They look like this:
http://phpseclib.sourceforge.net/ssh/log.txt
You can also do print_r($ssh->getErrors())
or echo $ssh->getLastError()
.
Changing Directories
I don't see any cd or chdir functions at http://php.net/ssh2 . phpseclib, however, has it - Net_SFTP::chdir(...)
Speed
libssh2:
<?php
$ssh = ssh2_connect('domain.tld');
ssh2_auth_password($ssh, 'username', 'password');
$start = microtime(true);
$sftp = ssh2_sftp($ssh);
$fp = fopen('ssh2.sftp://'.$sftp.'/home/username/1mb', 'w');
fwrite($fp, str_repeat('a', 1024 * 1024));
$elapsed = microtime(true) - $start;
echo "took $elapsed seconds";
25.71 seconds.
phpseclib:
<?php
include('Net/SFTP.php');
$sftp = new Net_SFTP('domain.tld');
$sftp->login('username', 'password');
$start = microtime(true);
$sftp->put('1mb', str_repeat('a', 1024*1024));
$elapsed = microtime(true) - $start;
echo "took $elapsed seconds";
11.70 seconds.
So phpseclib is more than twice as fast.