There are many cool things your can do if you have SSH with PHP. PHP 5 does not include this feature in its core distribution. So how can you do it?
One solution is to make use of the ssh2 package from PECL. The package provides several useful methods for secure remote access. Unfortunately, sometimes you may not be able to use the package due to some pragmatic problems. If you do not have privileged access to the server, and if you fail to convince the admin to install the package or the libraries required to compile it, you won't be able to use it (as well as many other PECL packages).
To solve this problem, I've written some code that requires only the following items to use SSH with PHP:
/usr/bin/ssh.)You need to prepare your server with a few things before you can make sure of the script.
DocumentRoot to make sure that no public user can even peek at the directory. Include a file .htaccess with a single line of DENY from ALL for extra protection.~/.ssh/id_rsa to a safe place such as the working directory prepared above. Set the file ownership and permission carefully. For even better security, encrypt the private key. Modify the code to decrypt the key with a user-supplied password when needed. Be warned that if you lose the private key and do not respond in time, your machines are in great risk!
Here it goes.
<?php
/*
A PHP Class for using SSH
Copyright (C) 2007 http://www.vyvy.org/
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Changes:
* [29-Jan-07] First release
*/
/*----------------------------------------------------------------*/
/* Configuration */
/*----------------------------------------------------------------*/
define('PATH_SSH', 'ssh'); // Path to SSH binary
/*----------------------------------------------------------------*/
/* Implementation */
/*----------------------------------------------------------------*/
define('SSH_ERROR_SSH_CONFIG', 0x1);
class vyvy_ssh
{
private \$user;
private \$host;
private \$file_ssh_key;
private \$file_ssh_config;
private \$file_known_hosts;
private \$error = 0;
function __construct(\$user, \$host, \$dir_ssh, \$file_ssh_key)
{
\$this->user = \$user;
\$this->host = \$host;
\$this->file_ssh_key = \$file_ssh_key; // For better security, you may want to encrypt this file and decrypt it when needed.
/* SSH configuration */
\$this->file_ssh_config = tempnam(\$dir_ssh, 'config_');
\$this->file_known_hosts = tempnam(\$dir_ssh, 'hosts_');
\$size = file_put_contents(\$this->file_ssh_config,
"StrictHostKeyChecking no\n"
. "UserKnownHostsFile {\$this->file_known_hosts}\n"
. "Protocol 2");
if (!\$size) {
\$this->error |= SSH_ERROR_SSH_CONFIG;
}
}
function __destruct()
{
/* Delete temporary files */
exec('shred --remove '.\$this->file_ssh_config);
exec('shred --remove '.\$this->file_known_hosts);
}
function exec(\$command, \$wait=true)
{
if (\$this->error) {
return array(false, 0);
}
\$cmd = PATH_SSH . " -n -F {\$this->file_ssh_config} -i {\$this->file_ssh_key} {\$this->user}@{\$this->host} 'sh -c \"{\$command}\"'";
if (!\$wait) {
\$cmd .= ' > /dev/null &';
}
exec(\$cmd, \$output, \$error);
if (\$error) {
return array(false, \$error);
}
return array(true, \$output);
}
}
?>
The following example lists the files of a remote machine. It's quite simple to use, isn't it?
<?php
require_once "vyvy_ssh.php";
\$ssh = new vyvy_ssh('vyvy', '10.0.0.7',
'/home/vyvy/www_private/ssh/',
'/home/vyvy/www_private/id_rsa');
list(\$status, \$output) = \$ssh->exec('ls -las');
\$output_formatted = htmlspecialchars(implode("\n", \$output));
echo <<<PAGE
<html>
<head>
<title>Sample Output</title>
</head>
<body>
<p>Status: {\$status}</p>
<p>Output:</p>
<pre>
{\$output_formatted}
</pre>
</body>
</html>
PAGE;
?>