0

我有与以下问题类似的情况 SSH2 change a user password

唯一的区别是我的操作是“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 command\n";
                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("y\n");
                    //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("yes\n");
                    $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;
        }
    }
4

2 回答 2

0

以下是使用纯 PHP SSH2 实现 phpseclib 的方法

<?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.com\n");
$ssh->read(' password:');
$ssh->write("password\n");

$ssh->setTimeout(0.5);
echo $ssh->read();
于 2013-07-04T15:44:10.150 回答
0

scp(以及ssh)不要期望密码,而是来自标准输入,而是来自控制台(如tty),这是一件好事。将密码存储在任何地方(例如某些 PHP 代码)会损害 ssh 的目的。

相反,您应该创建一个 RSA 身份验证密钥。这是一个简单的操作方法

完成后,按如下方式更改命令行:

scp -i /path/to/your/rsa.private.key

确保将此私钥存储在“安全”位置。它必须可以从您的 PHP 脚本访问,但不能从其他脚本访问。特别是不要让它从 URL 访问。

于 2013-07-04T12:40:37.987 回答