UltraMega Blog
19Jan/108

Using SSH in PHP

This tutorial will show you how to use the SSH2 functions in PHP to execute commands over SSH. This requires the SSH2 PECL extension to be installed on your server (installation instructions). Keep in mind that as of this time, the extension is in a beta state, so stability is not guaranteed.

Sending commands is fairly straightforward. You just connect, authenticate, then execute commands. Authentication can be done using a password or public key. Executing commands is a little tricky since it returns a stream that you have to handle.

First, we need to connect:

$ssh = ssh2_connect('127.0.0.1', 22);

Replace the IP and port with the correct values of the target server. If successful, $ssh now contains a handle to the connection that we will pass to the next functions.

Now we need to authenticate as a user. This can be done using a simple password or using a public key. I'll show you both methods:

// Using a password
ssh2_auth_password($ssh, 'user', 'password');
 
// Using a public key
ssh2_auth_pubkey_file($ssh, 'user', '/var/www/.ssh/id_rsa.pub', '/var/www/.ssh/id_rsa', 'passphrase');

Change the values as necessary. If using a public key, the paths point to your public and private key files, respectively, and the passphrase is used to decrypt the private key if neccessary.

Now that we are connected and authenticated, we can send a command:

// exec a command and return a stream
$stream = ssh2_exec($ssh, 'whoami');
// force PHP to wait for the output
stream_set_blocking($stream, true);
// read the output into a variable
$data = '';
while($buffer = fread($stream, 4096)) {
    $data .= $buffer;
}
// close the stream
fclose($stream);
// print the response
echo $data;

In this example, we ran the whoami command and printed the username that we logged into. Once we executed the command, we must read any response from the stream using the fread function. One thing to note is the use of the stream_set_blocking command, which seems to be required. Don't forget to close the stream when you are done using the fclose command!

That's really all there is to it. The SSH2 extension can do many other things not covered in this tutorial, such as file transfers. It can be very useful when you want to automate some remote server administration tasks or something.

Here is a complete code example:

<?php
if($ssh = ssh2_connect('127.0.0.1', 22)) {
    if(ssh2_auth_password($ssh, 'user', 'password')) {
        $stream = ssh2_exec($ssh, 'whoami');
        stream_set_blocking($stream, true);
        $data = '';
        while($buffer = fread($stream, 4096)) {
            $data .= $buffer;
        }
        fclose($stream);
        echo $data; // user
    }
}
?>

Posted by Steve

Tagged as: , Leave a comment
Comments (8) Trackbacks (0)
  1. Personally, given just how difficult it is to get this thing installed and given just how unreliable it is (ssh2_exec, for example, always returns prematurely for me), I’d recommend just using phpseclib, instead:

    http://phpseclib.sourceforge.net/

    As a pure-PHP implementation it doesn’t require you compile anything or adjust any config files or anything. Plus, it just seems to work a whole lot more smoothly than the ssh2 PECL extension.

  2. I don’t know why people find it soo hard to just compile something..

    takes like 3 minutes from download to apache restart to get ssh2 running, probably quicker just installing from pecl

    pecl install ssh2 channel://pecl.php.net/ssh2-version

  3. Excelente artigo cara! O portal do PHP tem as funções e a teoria de como utilizá-la, mas ainda falta exemplos para facilitar o entendimento na utilização, e você fez isso muito bem, vou até publicar um artigo no meu blog, só que diferente!

    Obrigado!
    —————————————————————————————————————–
    Great article man! The portal has the PHP functions and the theory of how to use it, but still lack examples to facilitate understanding in the use, and you did it very well, I’ll even post an article on my blog, but different!

    Thank you!

  4. how can user SSH in place of telnet plz help in this code (hiteshk.yadav@gmail.com
    <?php
    //myprint($_SERVER);
    ini_set('default_socket_timeout',10); //set timeout for ldap server and imserver requests, if no data received within set timeout, it will continue.
    error_reporting(E_ALL);
    global $con,$nib_options;
    $error=array();

    if(isset($_POST['verification']) AND $_POST['verification'] == $_SESSION['verification'])
    {
    //do test
    global $error;
    //echo "”.print_r($_POST,true).””;
    //die();
    $username = $_POST[‘username’];
    if(isset($_POST[‘custom_userid’]) AND strlen(trim($_POST[‘custom_userid’]))>0)
    {
    $username = $_POST[‘custom_userid’];
    }

    $bng_ip = $_POST[‘bng’];
    if(!filter_var($bng_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))
    {
    if(!filter_var($_POST[‘dslam_ip’], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))
    {
    $error[] = “Please select valid DSLAM OR BNG…”;
    }
    else
    {
    $results = mysqli_query($con,”SELECT bng_ip FROM iptable WHERE dslam_ip = ‘{$_POST[‘dslam_ip’]}’ LIMIT 1″);
    while($row=mysqli_fetch_array($results))
    $bng_ip = $row[‘bng_ip’];
    }
    }

    if(empty($error))
    {
    require_once “PHPTelnet.php”; //need new code for login rest was same
    $telnet = new PHPTelnet();
    $telnet->use_usleep = 0;
    $telnet->show_connect_error=0;

    $bng_result = $telnet->Connect($bng_ip,’bbmp’,’bbmp123′);
    if($bng_result==0)
    {
    $telnet->endPrompt = “>”;
    $telnet->DoCommand(‘context bsnl.in’, $result);
    myprint2($result);
    $username = str_replace(“@bsnl.in”,”,trim($username));
    $telnet->DoCommand(‘show sub active username ‘.$username.’@bsnl.in’, $result); // till here
    myprint2($result);
    //die();
    preg_match_all(“/(?0)
    {
    echo “List of ‘{$username}’ connected users”;
    echo “Sr.No.
    DSLAM
    Outer Vlan
    Inner Vlan
    “;

    foreach ($matches[0] as $v)
    {
    //echo “$v“;
    global $nib_options,$con;
    $temp = explode(“:”,$v);
    //echo “SELECT * FROM iptable WHERE ssa='{$nib_options[‘ssa’]}’ AND vlan='{$temp[0]}’ LIMIT 1″;
    $r = mysqli_query($con,”SELECT * FROM iptable WHERE ssa='{$nib_options[‘ssa’]}’ AND vlan='{$temp[0]}’ LIMIT 1″);
    if(mysqli_num_rows($r))
    {
    while($row = mysqli_fetch_array($r))
    echo ”
    $count
    {$row[‘location’]}{$row[‘make’]} – {$row[‘dslam_ip’]}
    {$temp[0]}
    {$temp[1]}
    “;
    }
    else{
    echo ”
    $count
    Unknown (DSLAM data missing)
    {$temp[0]}
    {$temp[1]}
    “;
    }
    $count++;
    }

    echo “”;
    }
    else
    {
    $error[] = “No user connected with ‘{$username}’, Try checking with different BNG.”;
    }

    $telnet->Disconnect();

    }
    else
    {
    $error[] = “Could not connect to BNG: Please “;
    }
    }

    }

    $verification = md5(microtime().rand());
    $_SESSION[‘verification’] = $verification;
    ?>

    0)
    echo “”.implode(“”,$error).””;
    ?>

    Please wait, It will not take more than 2 minutes.

     

    <input type='hidden' name='verification' value='’>
    User ID to check: bbtest
    multiplay
    Or enter BB UserID

    Select DSLAM

    Select DSLAM
    <?php
    $results = mysqli_query($con,"SELECT * FROM iptable WHERE ssa = '{$nib_options['ssa']}'");
    if(mysqli_num_rows($results))
    {
    while($row = mysqli_fetch_array($results))
    {
    echo "”.$row[‘location’].” (“.$row[‘dslam_ip’].” – “.$row[‘vlan’].”)”;
    }
    }
    ?>

    OR

    Select BNG

    SELECT BNG
    <?php
    $results = mysqli_query($con,"SELECT * FROM iptable WHERE ssa = '{$nib_options['ssa']}' GROUP BY bng_ip");
    if(mysqli_num_rows($results))
    {
    while($row = mysqli_fetch_array($results))
    {
    echo "”.$row[‘bng_name’].” (“.$row[‘bng_ip’].”)”;
    }
    }
    ?>


Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

No trackbacks yet.