Make SSH connections with PHP
条评论Not everyone knows about PHP‘s capabilities of making SSH connections and executing remote commands, but it can be very useful. I’ve been using it a lot in PHP CLI applications that I run from cronjobs, but initially it was a pain to get it to work. The PHP manual on Secure Shell2 Functions is not very practicle or thorough for that matter, so I would like to share my knowledge in this how to, to make it a little less time consuming setting this up.
In this article I’m going to assume that:
- You’re running Debian / Ubuntu
If not, you will have to substitute the package manager aptitude with whatever your distribution provides - You’re running PHP 5
If not, just replace php5 with php4 everywhere - You have basic knowledge of PHP & server administration
- You already have PHP installed
Prerequisites
Packages
First let’s install the following packages:
1 | sudo aptitude update |
That should set us up alright.
Update - On recent Ubuntu machines, there’s no need to do any compiling anymore:
1 | aptitude install libssh2-1-dev |
If the above works for you (you should see: “Build process completed successfully”), you can skip to Great! PHP supports SSH - time to code.
If not, you probably need to compile manually, continue reading here.
libssh2
We need libssh2 from sourcefourge. We have to compile this, but no worries, this is all you need to do:
1 | cd /usr/src |
That’s it! Easy right?
- Update: since December 26th 2008, libssh2 has reached version 1.0. Though I have not tested it: it has been reported to work. So you may want to check sf.net and download the latest stable version.
Installation
ssh2.so
Next we need to link libssh & PHP together. There’s a PECL module for this so let’s install using:
1 | pecl install -f ssh2 |
The -f makes sure ssh2 is installed even though there’s not a stable candidate. You could also use the package name: ssh2-beta to overrule this.
Now you need to make sure our new ssh2.so module is loaded by PHP. Edit your php.ini file (for CLIApache utilities /etc/php5/apache2/php.ini)utitilies: /etc/php5/cli/php.ini, for
1 | extension=ssh2.so |
It should be placed beneath the: “Dynamic Extensions” section somewhere around line 515.
Great! PHP supports SSH - time to code
You’ve just enabled ssh2 support in PHP. Now how can we make use of this? There are 2 options. SSH supports the:
execute method
This tells the server’s operating system to execute something and pipe the output back to your script. (recommended)
shell method
This opens an actual shell to the operating system, just as you would normally when logging in with your terminal application. Somerouters that don’t have a full POSIX compliant implementation, but run their own application as soon as you login, require this. (advanced)
Method 1: Execute
Best would be to create functions or even a class for the following code, but this is the basic idea and will definitely get you started:
1 | if (("ssh2_connect")) [die](http://www.php.net/die)("function ssh2_connect doesn't exist"); |
Method 2: Shell
Best would be to create functions or even a class for the following code, but this is the basic idea and will definitely get you started:
1 | if (("ssh2_connect")) [die](http://www.php.net/die)("function ssh2_connect doesn't exist"); |
Tips
Sometimes when a server is busy, or a connection is buggy, the buffer may run dry, and the PHP script stops collecting data from a command output (even though the command hasn’t completed yet!). There are a couple of things you could do about that:
1 | ssh2_exec($con, 'ls -al; echo "__COMMAND_FINISHED__"' ); |
Now, in the loop where you keep checking for the buffer, just see if the COMMAND_FINISHED line is coming by. Because then you know you have all the data. To avoid infinite loops, just limit the loop with a timeout of 10 seconds or so:
1 | $time_start = [time](http://www.php.net/time)(); |
In the example above, you’d better set stream_set_blocking to false.
Can’t get enough?
PHP can send files over ssh!
1 | ssh2_scp_send($con, "/tmp/source.dat", "/tmp/dest.dat", 0644); |
Doesn’t work?
Check the following:
- Did you follow every step of the prerequisites & installation how to in this article?
- On the serverside, ‘PasswordAuthentication yes’ must be enabled in the sshd_config. Default is yes on most servers, but in some cases you will have to turn this on yourself by making sure the following lines are in place in the file: /etc/ssh/sshd_config:
1 | # Change to yes to enable tunnelled clear text passwords |
If you’ve made any changes, ssh needs a restart
1 | /etc/init.d/ssh restart |