Reputation: 1321
I am working on a tool that reads an iptables configuration from a remote host over SSH2 using the PECL SSH2 extension. I am able to successfully make the connection to the host, authenticate, and execute commands. The trouble I am having is sometimes the stream doesn't contain any data.
/**
* Load the current firewall configuration
* @return bool
*/
public function loadRules() {
$stream = ssh2_exec($this->connection,"~/iptsave;");
stream_set_blocking($stream,true);
$iptablesSave = stream_get_contents($stream);
if(empty($iptablesSave)) {
return false;
}
parent::restore($iptablesSave);
return true;
}
About 25% of the time, loadRules()
returns false, even when connecting to locahost instead of the remote system. I was able to work around the problem by changing the ssh2_exec
call to
$stream = ssh2_exec($this->connection,"~/iptsave; sleep .5");
but I am concerned that something is wrong.
Upvotes: 3
Views: 3005
Reputation: 468
With some severs you have to use 'interactive shell'. And sometimes you have to set the delay / sleep manually. A working example:
$connection = ssh2_connect($IP, 22);
$auth = ssh2_auth_password($connection, $User, $Pass);
$cmd = "help" . PHP_EOL;
if (!$auth) {
echo "Login Failed;
exit(1);
}
$shell = ssh2_shell($connection);
stream_set_blocking($shell, false); // we will use manual sleep
sleep(1); // This sleep to make sure that you get the prompt back
fwrite ($shell, $cmd . ";" . PHP_EOL);
sleep(1); // This to make sure that the command executes and we get the prompt back again!
while($output = fgets($shell)){
echo $output;
}
fwrite ($shell, "exit;" . PHP_EOL); // If needed
sleep(1);
ssh2_disconnect($connection);
unset($shell);
unset($connection);
Upvotes: 0
Reputation: 11
May be this will solve the issue:
$stream = ssh2_exec($this->connection,"~/iptsave;");
stream_set_blocking($stream,true);
$stream_out = ssh2_fetch_stream($stream, SSH2_STREAM_STDIO);
$iptablesSave = stream_get_contents($stream);
Upvotes: 0
Reputation: 11
phpSecLib may be able to help:
According to this post, it always returns the output, unlike ssh2.so.
Upvotes: 1
Reputation: 3991
I've got the same issue here. Somehow you need to set a delay for getting the result of the stream.
The way you've done it is possible, but you could also set a sleep(1)
after the stream_set_block($stream, true)
function.
You could try the usleep()
function. Haven't tried it yet
Upvotes: 0