My post from yesterday: https://stackoverflow.com/questions/14296006/phpseclib-sftp-port-number
Ok, so yesterday I started learning about SSH / SFTP with php. I searched a bunch of forum posts and surmised that i needed to download the phpseclib.
Being relatively new to php thus starting on php5 i was not aware of previous php4's non-use of the __constructor, hence the above question/post.
The responses were conflicting, and a little off topic to the original Q however has delivered me to a question that I feel needs answering before i continue:
Which is better to use, ssh2 pecl extension OR phpseclib?
This question: phpseclib vs libssh2 is the same but I feel a little outdated now as asked on Nov 5 '10 at 17:37
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:
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\n");
$output = fread($shell, 1024*1024);
echo $output;
if (preg_match('#[pP]assword[^:]*:#', $output)) {
fwrite($shell, "password\n");
}
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.