我的情况与下面的问题类似SSH2更改用户密码
唯一的区别是我的操作是"scp",我想通过PHP发送ssh命令,使用scp命令将文件发送到远程机器(我知道PHP本身有实现这一点的方法,但出于某种原因,我跳过了那个方法)。
Code is as follows
//run specified cmd with stream reading and writing
function runCMDAdvance($cmd){
if (strpos($cmd,'scp') !== false) {
//reply machine when ask for password in file transfer
$confirmPass = $this->password."n".$this->password."n";
if (!($stream = ssh2_exec($this->conn, $cmd )))
{
echo "fail: unable to execute commandn";
fclose($stream);
return ERROR_SSH_EXEC_COMM;
}
fwrite($stream,$confirmPass); //>>Actually I want to pass the password information by writing to the stream, but turn out that it does not work
stream_set_blocking($stream, true);
}
}
当我尝试在流集阻塞后写入密码信息时,php执行代码会被卡住。(我想原因是远程机器正在等待密码信息,但php无法提供这些信息,所以它一直在等待,并阻塞了php运行的线程。)
我已经通读了上面的问题,但似乎无法找到实现这一目标的正确方向,对此有什么想法吗??
再次感谢大家的帮助!
参考neubert的答案,使用phpseclib仍然不起作用。。。
//$cmd is $cmd = 'scp '.$scpPath.' root@'.$ip.':/root';
function runCMDAdvance($cmd, $tVal){
if (strstr($cmd,"scp")!==FALSE){
if((include('Net/SSH2.php')) && (include('Net/SCP.php'))){
//set ssh timeout value
$this->setTimeoutVar($tVal);
$ssh = new Net_SSH2($this->host);
if (!$ssh->login($this->username, $this->password)){
echo "Bad Login";
return false;
}
$ssh->write($cmd."n");
$ssh->read(' password:');
$ssh->write($this->password."n");
}
}
else{
echo "Wrong command used, please check your code";
return false;
}
}
我处理SSH读写流的解决方案
//run any specified cmd using ssh
//parameter:
//cmd>>running command
//tVal>>command run timeout
//return:terminal stdout
function runCMDAdvance($sshIP, $cmd, $tVal,$tarIP){
$ssh = new Net_SSH2($sshIP);
if (!$ssh->login($this->username, $this->password)){
echo "Bad Login";
return false;
}
//set timeout for running ssh command, should be done after the ssh object has been initialized
$ssh->setTimeout($tVal);
//scp action detected
if (strstr($cmd,"scp")!==FALSE){
//if this is the first time to do the ssh, connect with "yes" for answering
if ($ssh->write($cmd)){
//store the output of the text message given by the router
$ssh_stdout = $ssh->read();
//echo $ssh_stdout."|||";
if (strstr($ssh_stdout,'trusted ')!==FALSE){
$ssh->write("yn");
//and ask password
$ssh->read(' :password');
}
//deal with known host situation
elseif (strstr($ssh_stdout,'ssh-keygen ')!==FALSE){
$ssh->write('ssh-keygen -f '.'/root/.ssh/known_hosts -R '.$tarIP."n");
$ssh->write($cmd);
$ssh->read(' :password');
$ssh->write($this->password."n");
return true;
}
//deal with still connecting situation
elseif (strstr($ssh_stdout,'Are you sure you want to continue connecting')!==FALSE){
$ssh->write("yesn");
$ssh->read(' :password');
$ssh->write($this->password."n");
return true;
}
$ssh->write($this->password."n");
$returnRead = $ssh->read();
$ssh->disconnect();
return true;
}//end of inner inner if
}//end of scp if (deal with scp)
else{//if not scp action,just normal action,simply execute the command
//exec will not return anything if the command is not run successfully
$res = $ssh->exec($cmd);
$ssh->disconnect();
return $res;
}
}
以下是如何使用phpseclib,一个纯PHP SSH2实现:
<?php
include('Net/SSH2.php');
define('NET_SSH2_LOGGING', 3);
$ssh = new Net_SSH2('www.website1.com');
$ssh->login('username', 'password');
$ssh->write("ssh username@www.website2.comn");
$ssh->read(' password:');
$ssh->write("passwordn");
$ssh->setTimeout(0.5);
echo $ssh->read();
scp
(以及ssh
)不需要密码,而是来自标准输入,而是来自控制台(如tty
),这是一件好事。将密码存储在任何地方(例如某些PHP代码)都会损害ssh的用途。
相反,您应该创建一个RSA身份验证密钥。这里有一个简单的操作方法。
完成后,按如下方式更改命令行:
scp -i /path/to/your/rsa.private.key
请确保将此私钥存储在"安全"的位置。它必须可以从您的PHP脚本访问,但不能从其他脚本访问。特别是不要通过URL访问它。