Question

I'm trying to use phpseclib to connect to a cisco SF308 switch. I am using this library to successfully connect to some HP switches, but for some reason, it just won't work with my cisco. Here's the code:

 set_include_path(get_include_path() . PATH_SEPARATOR . '/var/www/phpseclib');
 include('/var/www/phpseclib/Net/SSH2.php');
 define('NET_SSH2_LOGGING', NET_SSH2_LOG_COMPLEX); //add near include lines
 $cisco = new Net_SSH2('10.10.10.10');

 if (!$cisco->login('username', 'password')) {
     exit('Login Failed');
 }

 echo $cisco->write('\n');

 echo $cisco->write('help');
 echo $cisco->read('/([0-9A-Z\-])*(#)(\s*)/i', NET_SSH2_READ_REGEX);  
 echo $cisco->data;
 echo $cisco->getLog();
 echo $cisco->disconnect();

It always dies with the Login Failed error message.

I've tried adding some debug statements in the NET_SSH2 library itself and its dying with the error number 51, which is defined as 'NET_SSH2_MSG_USERAUTH_FAILURE'.

One thing that is different between the hp switches and this cisco is that when connecting manually, the hp is "smart" enough to pick up the username from the initial ssh command. For example, if you were to do this at a command prompt:

 ssh username@10.10.10.10

and then hit enter, it will pick up "username" as the username, and it will only prompt you for a password. With the cisco switch (SF302-08 is the model), it still prompts for both the username and the password. Once i supply the username for a second time, and then the password, I can connect to the switch.

I'm not sure if this is what's causing the problem, but it's something that is clearly different between the two switches. I'm trying to find some documentation for the cisco to see if there's any way to change this / make it pick up the username in the initial connect request. But if you have any other suggestions, please let me know! I'm all ears.

Thanks.

EDIT 1

I turned on complex logging and got the full details of where it's failing, in case this helps. Here's my latest code:

 set_include_path(get_include_path() . PATH_SEPARATOR . '/var/www/phpseclib');
 include('Net/SSH2.php');
 define('NET_SSH2_LOGGING', true); //turn on logging.

 $ssh = new Net_SSH2('10.10.10.10'); //starting the ssh connection to localhost
 if (!$ssh->login('username', 'password')) { //if you can't log on...
    echo('Login Failed');
    echo 'Error message is: <br>';
    $log = $ssh->getLog(NET_SSH2_LOG_COMPLEX);
    foreach ($log as $logitem)  {
             echo $logitem.'<br>';
     }

This returns the following output:

 Login FailedError message is:
 <-
 ->
 <- NET_SSH2_MSG_KEXINIT (0.0118s)
 -> NET_SSH2_MSG_KEXINIT (0s)
 -> NET_SSH2_MSG_KEXDH_INIT (0s)
 <- NET_SSH2_MSG_KEXDH_REPLY (0.7912s)
 -> NET_SSH2_MSG_NEWKEYS (0s)
 <- NET_SSH2_MSG_NEWKEYS (0s)
 -> NET_SSH2_MSG_SERVICE_REQUEST (0s)
 <- NET_SSH2_MSG_SERVICE_ACCEPT (0.4927s)
 -> NET_SSH2_MSG_USERAUTH_REQUEST (0s)
 <- NET_SSH2_MSG_USERAUTH_FAILURE (0.0059s)

So it is contacting the switch but as was mentioned in my initial post, it's failing while trying to authenticate the username/password.

Was it helpful?

Solution

After doing some research, here's the solution to our problem. Others may have resolved in a different way, but this seems to work for us.

What we noticed is the following:

  1. popular ssh libraries like phpseclib were failing on this switch because of the limited ssh implementation.

  2. php's ssh2_auth_none function returns TRUE on this switch.

What does this mean?

It seems that the ssh protocol has an authentication method called "none". This is insecure, and is usually disabled on most switches. The ssh2_auth_none() function attempts to connect without any authentication and if it fails, it returns a list of the authentication methods that the server accepts. In the case of the SF300.. it passes and returns nothing for the authentication methods.

  1. Known CLI and SSH Limitations

Although they weren't able to give us a solution, CISCO tech support did explicitly state that the small business class switches have a limited CLI and a pared down version of SSH as well so you cannot treat it as you an enterprise level switch that has a full blown ssh implementation.

In case it helps, here's a little snippet of code that shows how to connect to these types of devices:

    <?php

      $username = 'myusername';

      $password = 'mypassword';

      $connection = ssh2_connect('123.123.123.123', 22);

      //$authentication_methods = ssh2_auth_none($connection, 'user');

      $stdio_stream = ssh2_shell($connection);

      fwrite($stdio_stream,$username."\n");

      sleep(1);

      fwrite($stdio_stream,$password."\n");

      sleep(1);

      echo "Results: " . stream_get_contents($stdio_stream); 
      echo 'sending show bonjour command:<br>';
     fwrite($stdio_stream, "show bonjour".PHP_EOL); //you can use \n instead of PHP_EOL but PHP_EOL is recommended.

     sleep(1);

     echo "<br>Results: " . stream_get_contents($stdio_stream); 

    ?>

Hope this helps anyone who's attempting to connect to these types of devices programmatically.

OTHER TIPS

I am not familiar with the library that you are using, but I have had to script some things with Cisco routers using Perl. For this I used the Net::Telnet::Cisco module which deals with some of the idiosyncrasies of interacting with a Cisco device. When I connected to a Cisco Nexus device, rather that a regular IOS device, this broke. I had to fix it by altering the regular expression the module used to recognize the strings that indicate that the telnet session is awaiting user input. I was able to see the exact strings being sent from both the IOS device and the Nexus device using Wireshark. I suspect that you will need to something similar.

I would check the IP address you are using is correct and check the username and password have permission to connect

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top