PHP ssh2_exec() from Ubuntu Server to Windows with OpenSSH in Cygwin - works but fails the second time
Asked Answered
A

3

1

I had been using PHP's ssh_connect() and multiple ssh_exec() between two Ubuntu VMs without any problems. However, now I need to call multiple ssh_exec() from Ubuntu Server to Windows machine via OpenSSH/Cygwin. The result from ssh2_exec() in the following code prints an Array of files located at /var/www the first time, but returns empty array the second or more times.

If I use ssh2_connect before the second ssh_exec() it returns an array of files again. I even attempted to use phpseclib but had the same problem. Also, I need to execute other commands like Git so PHP functions like opendir() or readdir() won't be sufficient to solve this problem.

<?php
$host = "10.xx.x.xx"; 
$username = "sagunms"; 
$password = "password"; 

$conn = ssh2_connect($host, 22);
if (ssh2_auth_password($conn, $username, $password) === false) {
    throw new Exception('Login is invalid');
}

//First time execution - returns array of files successfully
$stream = ssh2_exec($conn, 'cd /var/www && ls'); 
stream_set_blocking($stream, true);
$cmdOutput = fread($stream, 4096);
fclose($stream); 
$result = explode("\n", $cmdOutput); // Convert string to array
print_r($result);                   // Print array

echo "<hr/>";

//Second time execution - returns an "empty array" but no errors seen
$stream = ssh2_exec($conn, 'cd /var/www && ls'); 
stream_set_blocking($stream, true);
$cmdOutput = fread($stream, 4096);
fclose($stream); 
$result = explode("\n", $cmdOutput); // Convert string to array
print_r($result); // Print array
?>

Is there something in Cygwin OpenSSH that is causing this problem? Thanks.

Acree answered 24/5, 2013 at 2:8 Comment(1)
I could only find an unanswered post with similar problem: linkAcree
A
2

Cygwin OpenSSH has this particular problem that even I had no solution for it. I would suggest you create a conditional statement if(isWindows) then ssh_connect() each time before ssh2_exec() else, ssh2_exec() using the same $conn resource variable.

Actinism answered 7/6, 2013 at 3:59 Comment(0)
I
1

This seems to be Cygwin specific problem. I had the same problem and later decided to go for Bitvise SSH Server for Windows instead of Cygwin with OpenSSH. This eliminated the need to reconnect to SSH before each and every command as you are forced to do right now.

Instancy answered 4/7, 2013 at 18:8 Comment(0)
S
1

Even though, this is an old question, as there are no posted solutions. The issue is with the openssh server that comes with cygwin. And you will face the same issue with using another php library like phpseclib. I faced the same issue and this is the solution for future reference. The cause of the issue is that, In windows based systems, setuid is called before executing a new command. For the first command its set initially so there are no issues. Subsequent calls however result in trying to reassign it and a a failure and openssh will not able able to do it. This is already explained during the ssh-host-config script-

*** Info: You appear to be running Windows XP 64bit, Windows 2003 Server,
*** Info: or later.  On these systems, it's not possible to use the LocalSystem
*** Info: account for services that can change the user id without an
*** Info: explicit password (such as passwordless logins [e.g. public key
*** Info: authentication] via sshd).

*** Info: If you want to enable that functionality, it's required to create
*** Info: a new account with special privileges (unless a similar account
*** Info: already exists). This account is then used to run these special
*** Info: servers.

In order to solve it, you need to create the privileged user account that the script tries to make and make sure that at the end of script it says -

*** Info: The sshd service has been installed under the 'cyg_server'
*** Info: account.  To start the service now, call `net start sshd' or
*** Info: `cygrunsrv -S sshd'.  Otherwise, it will start automatically
*** Info: after the next reboot.

Any message indicating that the account was not found and that it is defaulting to the "SYSTEM" account will result in the issue. In that case make sure the passwd file is up to date and includes the new user.

And when you launch Windows Services manager and check the properties of CYGWIN sshd service, under log on tab it needs to say that it is using the newly created privileged account instead of local account.

Also verify that under group policy editor -> Security Settings -> Local Policies -> User Rights Assignment , the new user account needs to have the privileges to create token objects and act as part of the operating system.

Sly answered 1/2, 2015 at 14:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.